From 537c285bd4eabc3b133447349e4d1a0619e34fdf Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 1 Jun 2025 13:29:14 +0200 Subject: [PATCH] Initial draft of the invitations board --- app/[slug]/dashboard/guests/page.tsx | 17 +++++++ app/lib/invitation.tsx | 26 ++++++++++ app/ui/invitations/board.tsx | 73 ++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 app/lib/invitation.tsx create mode 100644 app/ui/invitations/board.tsx diff --git a/app/[slug]/dashboard/guests/page.tsx b/app/[slug]/dashboard/guests/page.tsx index d42b0ba..7915188 100644 --- a/app/[slug]/dashboard/guests/page.tsx +++ b/app/[slug]/dashboard/guests/page.tsx @@ -16,6 +16,8 @@ import GuestsTable from '@/app/ui/guests/table'; import { TabPanel, TabView } from 'primereact/tabview'; import { Toast } from 'primereact/toast'; import { Suspense, useRef, useState } from 'react'; +import InvitationsBoard from '@/app/ui/invitations/board'; +import { Invitation, InvitationSerializer } from '@/app/lib/invitation'; export default function Page() { @@ -35,6 +37,13 @@ export default function Page() { }); } + function refreshInvitations() { + new AbstractApi().getAll(new InvitationSerializer(), (objects: Invitation[]) => { + setInvitations(objects); + setInvitationsLoaded(true); + }); + } + function resetAffinities() { fetch(`/api/${getSlug()}/groups/affinities/reset`, { method: 'POST', @@ -73,8 +82,13 @@ export default function Page() { const [guests, setGuests] = useState>([]); const [guestBeingEdited, setGuestBeingEdited] = useState(undefined); + const [invitationsLoaded, setInvitationsLoaded] = useState(false); + const [invitations, setInvitations] = useState>([]); + const [invitationBeingEdited, setInvitationBeingEdited] = useState(undefined); + !groupsLoaded && refreshGroups(); !guestsLoaded && refreshGuests(); + !invitationsLoaded && refreshInvitations(); return (
@@ -134,6 +148,9 @@ export default function Page() {
+ + + diff --git a/app/lib/invitation.tsx b/app/lib/invitation.tsx new file mode 100644 index 0000000..04dc81c --- /dev/null +++ b/app/lib/invitation.tsx @@ -0,0 +1,26 @@ +import { Entity } from "./definitions"; +import { Guest } from "./guest"; + +export class Invitation implements Entity { + id?: string; + guests: Array; + + constructor(id?: string, guests: Array = []) { + this.id = id; + this.guests = guests; + } +} + +export class InvitationSerializer { + fromJson(data: any): Invitation { + return new Invitation(data.id, data.guests.map((guest: any) => new Guest(guest.id, guest.name, guest.group_name, guest.groupId, guest.color, guest.status, guest.children))); + } + + toJson(invitation: Invitation): string { + return JSON.stringify({ invitation: { guests: invitation.guests.map(guest => ({ id: guest.id })) } }); + } + + apiPath(): string { + return 'invitations'; + } +} \ No newline at end of file diff --git a/app/ui/invitations/board.tsx b/app/ui/invitations/board.tsx new file mode 100644 index 0000000..c151cbc --- /dev/null +++ b/app/ui/invitations/board.tsx @@ -0,0 +1,73 @@ +'use client'; + +import { AbstractApi } from "@/app/api/abstract-api"; +import { Guest } from "@/app/lib/guest"; +import { Invitation, InvitationSerializer } from "@/app/lib/invitation"; + +export default function InvitationsBoard({ guests, invitations }: { + guests: Array, + invitations: Array +}) { + const api = new AbstractApi(); + const serializer = new InvitationSerializer(); + + // Filter out guests that are already in invitations + const availableGuests = guests.filter( + (guest) => !invitations.some((invitation) => + invitation.guests.some((invitedGuest) => invitedGuest.id === guest.id) + ) + ); + + function handleCreateInvitation() { + api.create(serializer, new Invitation(), () => { + console.log("Invitation created successfully"); + }); + } + + return ( +
+ {/* Left Column: Guests */} +
+

Guests

+
    + {availableGuests.map((guest, index) => ( +
  • +

    {guest.name}

    +
  • + ))} +
+
+ + {/* Right Column: Invitations */} +
+

Invitations

+ + + +
+ {invitations.map((invitation, index) => ( +
+
    + {invitation.guests.map((guest) => ( +
  • {guest.name}
  • + ))} +
+
+ ))} +
+
+
+ ); +}