Skip to content

Commit

Permalink
feat(board): change order of tiles (#1584)
Browse files Browse the repository at this point in the history
* feat(board): change order of tiles

* style(tile): change arrow icons

* style(edit): change placement delete tile and arrows to change order of tiles

* style(edit): buttons and width of baseExpand

* style(board): stroke on arrow buttons
  • Loading branch information
purusott authored Jul 23, 2024
1 parent 4a0d508 commit f27738c
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 60 deletions.
11 changes: 11 additions & 0 deletions next-tavla/app/(admin)/edit/[id]/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { TBoard, TBoardID } from 'types/settings'
import { TTile } from 'types/tile'
import { getWalkingDistance } from 'app/(admin)/components/TileSelector/utils'
import { TLocation } from 'types/meta'
import { revalidatePath } from 'next/cache'

initializeAdminApp()

Expand Down Expand Up @@ -47,3 +48,13 @@ export async function getWalkingDistanceTile(
},
}
}
export async function saveTiles(bid: TBoardID, tiles: TTile[]) {
const access = await hasBoardEditorAccess(bid)
if (!access) return redirect('/')

await firestore().collection('boards').doc(bid).update({
tiles: tiles,
'meta.dateModified': Date.now(),
})
revalidatePath(`/edit/${bid}`)
}
142 changes: 105 additions & 37 deletions next-tavla/app/(admin)/edit/[id]/components/TileCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
'use client'
import { BaseExpand } from '@entur/expand'
import { TTile } from 'types/tile'
import { Button, IconButton, SecondarySquareButton } from '@entur/button'
import {
Button,
IconButton,
NegativeButton,
SecondarySquareButton,
} from '@entur/button'
import { FilterChip } from '@entur/chip'
import { Switch, TextField } from '@entur/form'
import { CloseIcon, DeleteIcon, EditIcon, QuestionIcon } from '@entur/icons'
import {
CloseIcon,
DeleteIcon,
DownwardIcon,
EditIcon,
QuestionIcon,
UpwardIcon,
} from '@entur/icons'
import { Modal } from '@entur/modal'
import {
Heading3,
Expand Down Expand Up @@ -38,12 +50,18 @@ function TileCard({
address,
demoBoard,
setDemoBoard,
moveItem,
index,
totalTiles,
}: {
bid: TBoardID
tile: TTile
address?: TLocation
demoBoard?: TBoard
setDemoBoard?: Dispatch<SetStateAction<TBoard>>
moveItem: (index: number, direction: string) => void
index: number
totalTiles: number
}) {
const posthog = usePostHog()
const [isOpen, setIsOpen] = useState(false)
Expand Down Expand Up @@ -109,43 +127,75 @@ function TileCard({

return (
<div>
<div
className={`flex justify-between items-center px-6 py-4 bg-secondary ${
isOpen ? 'rounded-t' : 'rounded'
}`}
>
<div className="flex flex-row gap-4 items-center mr-2">
<Heading3 margin="none">{tile.name}</Heading3>
<div className="hidden sm:flex flex-row gap-4 h-8">
{transportModes.map((tm) => (
<TransportIcon transportMode={tm} key={tm} />
))}
<div className="flex flex-row">
<div
className={`flex justify-between items-center px-6 py-4 bg-secondary w-full ${
isOpen ? 'rounded-t' : 'rounded'
}`}
>
<div className="flex flex-row gap-4 items-center ">
<Heading3 margin="none">{tile.name}</Heading3>
<div className="hidden sm:flex flex-row gap-4 h-8">
{transportModes.map((tm) => (
<TransportIcon transportMode={tm} key={tm} />
))}
</div>
</div>

<div className="flex flex-row gap-4">
<SecondarySquareButton
onClick={() => {
if (changed) return setConfirmOpen(true)
setIsOpen(!isOpen)
}}
aria-label="Rediger stoppested"
>
{isOpen ? <CloseIcon /> : <EditIcon />}
</SecondarySquareButton>
</div>
</div>
<div className="flex flex-row gap-4">
<SecondarySquareButton
onClick={async () => {
bid === 'demo'
? removeTileFromDemoBoard(tile)
: await deleteTile(bid, tile)
}}
aria-label="Slett stoppested"
>
<DeleteIcon />
</SecondarySquareButton>
<SecondarySquareButton
onClick={() => {
if (changed) return setConfirmOpen(true)
setIsOpen(!isOpen)
}}
aria-label="Rediger stoppested"
>
{isOpen ? <CloseIcon /> : <EditIcon />}
</SecondarySquareButton>
<div
className={` flex flex-col ${
index !== 0 || index !== totalTiles - 1
? 'justify-center gap-2'
: 'justify-between'
}`}
>
{index !== 0 && (
<SecondarySquareButton
onClick={() => {
moveItem(index, 'up')
}}
aria-label="Flytt opp"
className="ml-2 *:!border-gray-300"
>
<UpwardIcon
onClick={() => {
moveItem(index, 'up')
}}
aria-label="Flytt opp"
/>
</SecondarySquareButton>
)}
{index !== totalTiles - 1 && (
<SecondarySquareButton
onClick={() => {
moveItem(index, 'down')
}}
aria-label="Flytt ned"
className="ml-2 *:!border-gray-300"
>
<DownwardIcon />
</SecondarySquareButton>
)}
</div>
</div>
<BaseExpand open={isOpen}>
<div className="bg-secondary px-6 py-4 rounded-b">
<div
className={`bg-secondary px-6 mr-14 py-4 ${
totalTiles == 1 && 'w-full'
} rounded-b`}
>
<form
id={tile.uuid}
action={async (data: FormData) => {
Expand Down Expand Up @@ -297,10 +347,28 @@ function TileCard({
value={uniqLines.length.toString()}
/>

<div className="flex flex-row justify-end mt-8">
<SubmitButton variant="primary">
Lagre endringer
<div className="flex flex-row justify-start gap-4 mt-8">
<SubmitButton
variant="primary"
aria-label="lagre valg"
>
Lagre valg
</SubmitButton>
<Button variant="secondary" aria-label="avbryt">
Avbryt
</Button>
<NegativeButton
onClick={async () => {
bid === 'demo'
? removeTileFromDemoBoard(tile)
: await deleteTile(bid, tile)
}}
aria-label="Slett stoppested"
type="button"
>
<DeleteIcon />
Fjern stoppested
</NegativeButton>
</div>
<Modal
size="small"
Expand Down
65 changes: 65 additions & 0 deletions next-tavla/app/(admin)/edit/[id]/components/TileList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use client'

import { TBoard, TBoardID } from 'types/settings'
import { TileCard } from 'app/(admin)/edit/[id]/components/TileCard/index'
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
import { TTile } from 'types/tile'
import { saveTiles } from '../../actions'
import { debounce } from 'lodash'

function TileList({
board,
setDemoBoard,
bid,
}: {
board: TBoard
bid?: TBoardID
setDemoBoard?: Dispatch<SetStateAction<TBoard>>
}) {
const [array, setArray] = useState<TTile[]>(board.tiles)

useEffect(() => {
setArray(board.tiles)
}, [board.tiles])

const moveItem = (index: number, direction: string) => {
const newIndex: number = direction === 'up' ? index - 1 : index + 1
if (newIndex < 0 || newIndex >= board.tiles.length) {
return
}

const newArray: TTile[] = [...board.tiles]

const oldElement = newArray[newIndex]

newArray[newIndex] = newArray[index] as TTile
newArray[index] = oldElement as TTile

setArray(newArray)
if (bid === 'demo' && setDemoBoard) {
const newBoard: TBoard = { ...board, tiles: newArray }
setDemoBoard(newBoard ?? board)
} else {
saveTiles(board.id ?? '', newArray)
}
}
const debouncedSave = debounce(moveItem, 150)
return (
<div className="flex flex-col gap-4">
{array.map((tile, index) => (
<TileCard
key={tile.uuid}
bid={bid ?? board.id ?? ''}
demoBoard={bid ? board : undefined}
tile={tile}
address={board.meta.location}
moveItem={debouncedSave}
index={index}
totalTiles={board.tiles.length}
setDemoBoard={setDemoBoard}
/>
))}
</div>
)
}
export { TileList }
16 changes: 4 additions & 12 deletions next-tavla/app/(admin)/edit/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { redirect } from 'next/navigation'
import { TBoardID } from 'types/settings'
import { addTile, getBoard, getWalkingDistanceTile } from './actions'
import { Heading1, Heading2 } from '@entur/typography'
import { TileCard } from './components/TileCard'
import { MetaSettings } from './components/MetaSettings'
import { TileSelector } from 'app/(admin)/components/TileSelector'
import { formDataToTile } from 'app/(admin)/components/TileSelector/utils'
Expand All @@ -18,8 +17,9 @@ import { DEFAULT_BOARD_NAME } from 'app/(admin)/utils/constants'
import { Preview } from './components/Preview'
import { ActionsMenu } from './components/ActionsMenu'
import { ThemeSelect } from './components/ThemeSelect'
import { TileList } from './components/TileList'

type TProps = {
export type TProps = {
params: { id: TBoardID }
}

Expand All @@ -40,7 +40,6 @@ export default async function EditPage({ params }: TProps) {

const access = await hasBoardEditorAccess(params.id)
if (!access) return redirect('/')

return (
<div className="flex flex-col gap-14">
<div className="flex flex-col md:flex-row justify-between">
Expand All @@ -65,7 +64,6 @@ export default async function EditPage({ params }: TProps) {
/>
<ThemeSelect board={board} />
</div>

<div className="flex flex-col gap-4">
<Heading2>Stoppesteder i tavlen</Heading2>
<TileSelector
Expand All @@ -84,14 +82,8 @@ export default async function EditPage({ params }: TProps) {
revalidatePath(`/edit/${params.id}`)
}}
/>
{board.tiles.map((tile) => (
<TileCard
key={tile.uuid}
bid={params.id}
tile={tile}
address={board.meta.location}
/>
))}

<TileList board={board} />
</div>

<div className="flex flex-col gap-4">
Expand Down
13 changes: 2 additions & 11 deletions next-tavla/app/demo/components/DemoBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { Heading2 } from '@entur/typography'
import { TileSelector } from 'app/(admin)/components/TileSelector'
import { formDataToTile } from 'app/(admin)/components/TileSelector/utils'
import { Preview } from 'app/(admin)/edit/[id]/components/Preview'
import { TileCard } from 'app/(admin)/edit/[id]/components/TileCard'
import useLocalStorage from '../../(admin)/hooks/useLocalStorage'
import { TTile } from 'types/tile'
import { usePostHog } from 'posthog-js/react'
import { TileList } from 'app/(admin)/edit/[id]/components/TileList'

const emptyDemoBoard = {
id: 'demo',
Expand All @@ -31,15 +30,7 @@ function DemoBoard() {
}}
col={false}
/>
{board.tiles?.map((tile: TTile) => (
<TileCard
key={tile.uuid}
tile={tile}
bid={board.id ?? 'demo'}
demoBoard={board}
setDemoBoard={setBoard}
/>
))}
<TileList board={board} setDemoBoard={setBoard} bid="demo" />
</div>
<div className="flex flex-col gap-4">
<Heading2>Forhåndsvisning</Heading2>
Expand Down

0 comments on commit f27738c

Please sign in to comment.