All checks were successful
Build Nginx-based docker image / build-static-assets (push) Successful in 1m52s
109 lines
3.2 KiB
TypeScript
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 >
|
|
);
|
|
} |