Manuel Bustillo 42d1de933f
All checks were successful
Build Nginx-based docker image / build-static-assets (push) Successful in 1m52s
WIP invitation layout
2025-06-08 09:10:35 +02:00

109 lines
3.2 KiB
TypeScript

/* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
'use client';
import { AbstractApi } from '@/app/api/abstract-api';
import { Guest } from '@/app/lib/guest';
import { Invitation, InvitationSerializer } from '@/app/lib/invitation';
import { useParams } from 'next/navigation';
import { Dropdown } from 'primereact/dropdown';
import { TabPanel, TabView } from 'primereact/tabview';
import { useEffect, useState } from 'react';
function GuestForm({ guest }: { guest: Guest }) {
const [formResponses, setFormResponses] = useState<Guest['formResponses']>(guest.formResponses || {});
return (
<div className="flex flex-col gap-4">
<div>
<label className="block font-medium">Will you use the bus to get to the venue?</label>
<Dropdown
value={formResponses?.busNeeded ? 'Yes' : formResponses?.busNeeded === false ? 'No' : ''}
options={[
{ label: '', value: '' }, // Blank option as default
{ label: 'Yes', value: 'Yes' },
{ label: 'No', value: 'No' },
]}
onChange={(e) =>
setFormResponses((prev) => ({
...prev,
busNeeded: e.value === 'Yes',
}))
}
placeholder="Select an option"
className="w-full"
/>
</div>
<div>
<label className="block font-medium">Dietary Restrictions</label>
<textarea
value={formResponses?.dietaryRestrictions}
onChange={(e) =>
setFormResponses((prev) => ({
...prev,
dietaryRestrictions: e.target.value,
}))
}
className="w-full p-2 border border-gray-300 rounded-md"
rows={3}
/>
</div>
<div>
<label className="block font-medium">Meal Preference</label>
<Dropdown
value={formResponses?.mealPreference}
options={[
{ label: '', value: '' }, // Blank option as default
{ label: 'Meat', value: 'Meat' },
{ label: 'Fish', value: 'Fish' },
]}
onChange={(e) =>
setFormResponses((prev) => ({
...prev,
mealPreference: e.value,
}))
}
placeholder="Select an option"
className="w-full"
/>
</div>
</div>
);
}
export default function Page() {
const params = useParams<{ slug: string, id: string }>()
const serializer = new InvitationSerializer();
const api = new AbstractApi<Invitation>();
const [invitation, setInvitation] = useState<Invitation | null>(null);
useEffect(() => {
api.get(serializer, params.id, (invitation) => {
setInvitation(invitation);
});
}, [params.slug, params.id]);
return (
<div>
{invitation && (
<div>
<p className="mb-4 font-medium">
{invitation.guests.length} seats have been reserved for this invitation.
</p>
<TabView className="border border-gray-300 rounded-md">
{invitation.guests.map((guest) => (
<TabPanel header={guest.name} >
<GuestForm guest={guest} />
</TabPanel>
))}
</TabView>
</div>
)
}
</div >
);
}