From 52caefc220a00d02980d724add5e4c83e70b4c94 Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 17 Nov 2024 19:18:20 +0100 Subject: [PATCH] Reuse the same dialog for creating and editing guests --- app/api/guests.tsx | 1 + app/dashboard/guests/page.tsx | 21 ++++++-- app/lib/definitions.ts | 5 +- ...ation-dialog.tsx => guest-form-dialog.tsx} | 53 +++++++++++++------ app/ui/guests/table.tsx | 12 +++-- 5 files changed, 66 insertions(+), 26 deletions(-) rename app/ui/components/{creation-dialog.tsx => guest-form-dialog.tsx} (54%) diff --git a/app/api/guests.tsx b/app/api/guests.tsx index 77a6764..df218b4 100644 --- a/app/api/guests.tsx +++ b/app/api/guests.tsx @@ -13,6 +13,7 @@ export function loadGuests(onLoad?: (guests: Guest[]) => void) { name: record.name, status: record.status, group_name: record.group.name, + groupId: record.group.id, }); })); }, (error) => { diff --git a/app/dashboard/guests/page.tsx b/app/dashboard/guests/page.tsx index fe46b0e..85e249a 100644 --- a/app/dashboard/guests/page.tsx +++ b/app/dashboard/guests/page.tsx @@ -2,16 +2,18 @@ 'use client'; +import { loadGroups } from '@/app/api/groups'; +import { loadGuests } from '@/app/api/guests'; import { Group, Guest } from '@/app/lib/definitions'; -import CreationDialog from '@/app/ui/components/creation-dialog'; +import { classNames } from '@/app/ui/components/button'; +import GuestFormDialog from '@/app/ui/components/guest-form-dialog'; import GroupsTable from '@/app/ui/groups/table'; import AffinityGroupsTree from '@/app/ui/guests/affinity-groups-tree'; import SkeletonTable from '@/app/ui/guests/skeleton-row'; import GuestsTable from '@/app/ui/guests/table'; import { TabPanel, TabView } from 'primereact/tabview'; import { Suspense, useState } from 'react'; -import { loadGuests } from '@/app/api/guests'; -import { loadGroups } from '@/app/api/groups'; + export default function Page() { function refreshGuests() { @@ -33,6 +35,7 @@ export default function Page() { const [guestsLoaded, setGuestsLoaded] = useState(false); const [guests, setGuests] = useState>([]); + const [guestBeingEdited, setGuestBeingEdited] = useState(undefined); !groupsLoaded && refreshGroups(); !guestsLoaded && refreshGuests(); @@ -44,9 +47,17 @@ export default function Page() {
- + + { refreshGuests(); setGuestBeingEdited(undefined) }} + guest={guestBeingEdited} + visible={guestBeingEdited !== undefined} + onHide={() => { setGuestBeingEdited(undefined) }} + /> }> - + setGuestBeingEdited(guest)} />
diff --git a/app/lib/definitions.ts b/app/lib/definitions.ts index 8e7e6ae..824bc5f 100644 --- a/app/lib/definitions.ts +++ b/app/lib/definitions.ts @@ -20,9 +20,10 @@ export type Customer = { export type GuestStatus = 'considered' | 'invited' | 'confirmed' | 'declined' | 'tentative'; export type Guest = { - id: string; - name: string; + id?: string; + name?: string; group_name?: string; + groupId?: string; color?: string; status?: GuestStatus } diff --git a/app/ui/components/creation-dialog.tsx b/app/ui/components/guest-form-dialog.tsx similarity index 54% rename from app/ui/components/creation-dialog.tsx rename to app/ui/components/guest-form-dialog.tsx index 01b169e..c9537ce 100644 --- a/app/ui/components/creation-dialog.tsx +++ b/app/ui/components/guest-form-dialog.tsx @@ -2,8 +2,8 @@ 'use client'; -import { createGuest } from '@/app/api/guests'; -import { Group } from '@/app/lib/definitions'; +import { createGuest, updateGuest } from '@/app/api/guests'; +import { Group, Guest } from '@/app/lib/definitions'; import { classNames } from '@/app/ui/components/button'; import { Dialog } from 'primereact/dialog'; import { Dropdown } from 'primereact/dropdown'; @@ -11,25 +11,46 @@ import { FloatLabel } from 'primereact/floatlabel'; import { InputText } from 'primereact/inputtext'; import { useState } from 'react'; -export default function CreationDialog({ groups, onCreate }: { groups: Group[], onCreate?: () => void }) { - const [visible, setVisible] = useState(false); +export default function GuestFormDialog({ groups, onCreate, onHide, guest, visible}: { + groups: Group[], + onCreate?: () => void, + onHide: () => void, + guest?: Guest, + visible: boolean, +}) { + + const [name, setName] = useState(guest?.name || ''); + const [group, setGroup] = useState(guest?.groupId || null); + + function resetForm() { + setName(''); + setGroup(null); + } - const [name, setName] = useState(''); - const [group, setGroup] = useState(null); function submitGuest() { - name && group && createGuest(name, group, () => { - setVisible(false); - setName(''); - setGroup(null); - onCreate && onCreate(); - }); + if (!(name && group)) { + return + } + + if (guest?.id !== undefined) { + guest.name = name; + guest.groupId = group; + updateGuest(guest).then(() => { + resetForm(); + onCreate && onCreate(); + }); + } else { + createGuest(name, group, () => { + resetForm(); + onCreate && onCreate(); + }); + } } return ( <> - - { if (!visible) return; setVisible(false); }}> +
setName(e.target.value)} /> @@ -43,7 +64,9 @@ export default function CreationDialog({ groups, onCreate }: { groups: Group[], } /> - +
diff --git a/app/ui/guests/table.tsx b/app/ui/guests/table.tsx index f7d0aa9..a18dc9a 100644 --- a/app/ui/guests/table.tsx +++ b/app/ui/guests/table.tsx @@ -5,12 +5,15 @@ import { destroyGuest, updateGuest } from '@/app/api/guests'; import { Guest, GuestStatus } from '@/app/lib/definitions'; import { classNames } from '@/app/ui/components/button'; +import { PencilIcon, TrashIcon } from '@heroicons/react/24/outline'; import clsx from 'clsx'; -import InlineTextField from '../components/form/inlineTextField'; import TableOfContents from '../components/table-of-contents'; -import { TrashIcon } from '@heroicons/react/24/outline'; -export default function guestsTable({ guests, onUpdate }: { guests: Guest[], onUpdate: () => void }) { +export default function guestsTable({ guests, onUpdate, onEdit }: { + guests: Guest[], + onUpdate: () => void, + onEdit: (guest: Guest) => void +}) { const handleGuestChange = (guest: Guest, status: GuestStatus) => { guest.status = status; updateGuest(guest).then(() => onUpdate()); @@ -24,7 +27,7 @@ export default function guestsTable({ guests, onUpdate }: { guests: Guest[], onU rowRender={(guest) => ( - { guest.name = newName; updateGuest(guest) }} /> + {guest.name} {guest.group_name} @@ -58,6 +61,7 @@ export default function guestsTable({ guests, onUpdate }: { guests: Guest[], onU )} { destroyGuest(guest, () => onUpdate()) }} /> + onEdit(guest)} />