Skip to content

Commit

Permalink
Merge pull request #309 from TaloDev/update-game-names
Browse files Browse the repository at this point in the history
Allow updating game names
  • Loading branch information
tudddorrr authored Nov 1, 2024
2 parents 69812ef + bca8571 commit bced578
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/api/updateGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import makeValidatedRequest from './makeValidatedRequest'
import { Prop } from '../entities/prop'

const updateGame = makeValidatedRequest(
(gameId: number, data: { props: Prop[] }) => api.patch(`/games/${gameId}`, data),
(gameId: number, data: { name?: string, props?: Prop[] }) => api.patch(`/games/${gameId}`, data),
z.object({
game: gameSchema
})
Expand Down
85 changes: 81 additions & 4 deletions src/pages/Organisation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { format } from 'date-fns'
import { useRecoilValue } from 'recoil'
import Page from '../components/Page'
Expand All @@ -8,8 +8,8 @@ import TableCell from '../components/tables/TableCell'
import organisationState from '../state/organisationState'
import useOrganisation from '../api/useOrganisation'
import Button from '../components/Button'
import { IconPlus } from '@tabler/icons-react'
import ErrorMessage from '../components/ErrorMessage'
import { IconCheck, IconPencil, IconPlus, IconX } from '@tabler/icons-react'
import ErrorMessage, { TaloError } from '../components/ErrorMessage'
import NewInvite from '../modals/NewInvite'
import SecondaryNav from '../components/SecondaryNav'
import { secondaryNavRoutes } from './Dashboard'
Expand All @@ -19,13 +19,50 @@ import userState, { AuthedUser } from '../state/userState'
import SecondaryTitle from '../components/SecondaryTitle'
import { UserType } from '../entities/user'
import userTypeMap from '../constants/userTypeMap'
import TextInput from '../components/TextInput'
import updateGame from '../api/updateGame'
import buildError from '../utils/buildError'

function Organisation() {
const organisation = useRecoilValue(organisationState)
const { games, members, pendingInvites, loading, error, mutate } = useOrganisation()
const [showModal, setShowModal] = useState(false)
const user = useRecoilValue(userState) as AuthedUser

const [editingGameId, setEditingGameId] = useState<number | null>(null)
const [editingGameName, setEditingGameName] = useState('')
const [editingGameNameError, setEditingGameNameError] = useState<TaloError | null>(null)

useEffect(() => {
if (editingGameId) {
setEditingGameName(games.find((game) => game.id === editingGameId)!.name)
} else {
setEditingGameName('')
}

setEditingGameNameError(null)
}, [editingGameId, games])

const onUpdateGameName = useCallback(async () => {
try {
const { game } = await updateGame(editingGameId!, { name: editingGameName })

mutate((data) => {
return {
...data!,
games: data!.games.map((existingGame) => {
if (existingGame.id === editingGameId) return { ...existingGame, name: game.name }
return existingGame
})
}
}, false)

setEditingGameId(null)
} catch (err) {
setEditingGameNameError(buildError(err))
}
}, [editingGameId, editingGameName, mutate])

return (
<Page
title={organisation.name}
Expand All @@ -38,11 +75,51 @@ function Organisation() {
<>
<SecondaryTitle>Games</SecondaryTitle>

{editingGameNameError && <ErrorMessage error={editingGameNameError} />}

<Table columns={['Game', 'Player count', 'Created at']}>
<TableBody iterator={games}>
{(game) => (
<>
<TableCell>{game.name}</TableCell>
<TableCell className='flex items-center space-x-4'>
{editingGameId === game.id &&
<>
<TextInput
id={`edit-name-${game.id}`}
variant='light'
placeholder='Name'
onChange={setEditingGameName}
value={editingGameName}
/>
<Button
variant='icon'
className='p-1 rounded-full bg-indigo-900'
onClick={onUpdateGameName}
icon={<IconCheck size={16} />}
extra={{ 'aria-label': 'Update game name' }}
/>
<Button
variant='icon'
className='p-1 rounded-full bg-indigo-900'
onClick={() => setEditingGameId(null)}
icon={<IconX size={16} />}
extra={{ 'aria-label': 'Cancel editing game name' }}
/>
</>
}
{editingGameId !== game.id &&
<>
<span>{game.name}</span>
<Button
variant='icon'
className='p-1 rounded-full bg-indigo-900'
onClick={() => setEditingGameId(game.id)}
icon={<IconPencil size={16} />}
extra={{ 'aria-label': 'Edit game name' }}
/>
</>
}
</TableCell>
<TableCell>{game.playerCount}</TableCell>
<DateCell>{format(new Date(game.createdAt), 'do MMM Y')}</DateCell>
</>
Expand Down

0 comments on commit bced578

Please sign in to comment.