Compare commits
No commits in common. "87cf2d3bb2612c2d026530dbc54ebf02d8977293" and "943da9c7e886773c9cb6d7acadf675a4e1f87cb8" have entirely different histories.
87cf2d3bb2
...
943da9c7e8
@ -1,119 +0,0 @@
|
|||||||
/* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/
|
|
||||||
|
|
||||||
'use client'
|
|
||||||
|
|
||||||
import { AbstractApi } from "@/app/api/abstract-api";
|
|
||||||
import { Invitation, InvitationSerializer } from "@/app/lib/invitation";
|
|
||||||
import { useParams } from "next/navigation";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { FloatLabel } from "primereact/floatlabel";
|
|
||||||
import { Dropdown } from "primereact/dropdown";
|
|
||||||
import { Guest, GuestSerializer, GuestStatus } from "@/app/lib/guest";
|
|
||||||
import { Button } from "primereact/button";
|
|
||||||
|
|
||||||
type FormResponse = {
|
|
||||||
attendance: GuestStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
function GuestForm({ guest, idx }: { guest: Guest, idx: number }) {
|
|
||||||
const [response, setResponse] = useState<FormResponse>({
|
|
||||||
attendance: guest.status!
|
|
||||||
});
|
|
||||||
|
|
||||||
const [pendingChanges, setPendingChanges] = useState(false);
|
|
||||||
const [sending, setSending] = useState(false);
|
|
||||||
|
|
||||||
console.log('GuestForm response', response.attendance);
|
|
||||||
|
|
||||||
const attendanceOptions: { name: string, code: GuestStatus }[] = [
|
|
||||||
{
|
|
||||||
name: 'Attending',
|
|
||||||
code: 'confirmed'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Declined',
|
|
||||||
code: 'declined'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Tentative',
|
|
||||||
code: 'tentative'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const api = new AbstractApi<Guest>();
|
|
||||||
const serializer = new GuestSerializer();
|
|
||||||
|
|
||||||
const submitForm = () => {
|
|
||||||
setSending(true);
|
|
||||||
setPendingChanges(false);
|
|
||||||
api.update(serializer, {
|
|
||||||
id: guest.id!,
|
|
||||||
status: response.attendance,
|
|
||||||
}, () => setSending(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={guest.id}
|
|
||||||
className={`px-2 py-6 flex flex-col items-center ${idx !== 0 ? 'border-t border-gray-300' : ''}`}
|
|
||||||
>
|
|
||||||
<h2 className="m-2 text-xl font-semibold">{guest.name}</h2>
|
|
||||||
|
|
||||||
<Dropdown
|
|
||||||
value={response.attendance}
|
|
||||||
options={attendanceOptions}
|
|
||||||
optionLabel="name"
|
|
||||||
optionValue="code"
|
|
||||||
className="rounded-md w-full max-w-xs border border-gray-300"
|
|
||||||
checkmark={true}
|
|
||||||
highlightOnSelect={false}
|
|
||||||
onChange={(e) => {
|
|
||||||
setPendingChanges(true);
|
|
||||||
setResponse({ ...response, attendance: e.value })
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
label="Save"
|
|
||||||
icon="pi pi-save"
|
|
||||||
loading={sending}
|
|
||||||
onClick={submitForm}
|
|
||||||
disabled={!pendingChanges || sending}
|
|
||||||
className="mt-4 max-w-xs"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
const params = useParams<{ slug: string, id: string }>()
|
|
||||||
|
|
||||||
const [invitation, setInvitation] = useState<Invitation>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
localStorage.setItem('slug', params.slug);
|
|
||||||
|
|
||||||
const api = new AbstractApi<Invitation>();
|
|
||||||
const serializer = new InvitationSerializer();
|
|
||||||
|
|
||||||
api.get(serializer, params.id, (invitation: Invitation) => {
|
|
||||||
setInvitation(invitation);
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col items-center">
|
|
||||||
<h1 className="text-2xl font-bold mb-4">Invitation</h1>
|
|
||||||
{invitation ? (
|
|
||||||
<div>
|
|
||||||
<p>We have reserved {invitation.guests.length} seats in your honor. Please, confirm attendance submitting the following form:</p>
|
|
||||||
{invitation.guests.map((guest, idx) => (
|
|
||||||
<GuestForm key={guest.id} guest={guest} idx={idx} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<p>Loading...</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -29,7 +29,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
|||||||
|
|
||||||
<div className="max-w-4xl w-full h-full bg-[#f9f9f7] shadow-lg">
|
<div className="max-w-4xl w-full h-full bg-[#f9f9f7] shadow-lg">
|
||||||
<div
|
<div
|
||||||
className="max-w-4xl lg:m-6 m-3 lg:px-6 px-3 lg:py-24 py-2 border-2 border-[#d3d3d1] rounded-xl text-[#958971] flex justify-center"
|
className="max-w-4xl lg:m-6 m-3 lg:px-6 px-3 py-24 border-2 border-[#d3d3d1] rounded-xl text-[#958971] flex justify-center"
|
||||||
style={{ height: 'calc(100% - 3rem)' }}
|
style={{ height: 'calc(100% - 3rem)' }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -49,7 +49,6 @@ export class AbstractApi<T extends Entity> implements Api<T> {
|
|||||||
body: serializable.toJson(object),
|
body: serializable.toJson(object),
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept': 'application/json',
|
|
||||||
'X-CSRF-TOKEN': getCsrfToken(),
|
'X-CSRF-TOKEN': getCsrfToken(),
|
||||||
}
|
}
|
||||||
}).then(callback)
|
}).then(callback)
|
||||||
@ -62,7 +61,6 @@ export class AbstractApi<T extends Entity> implements Api<T> {
|
|||||||
body: serializable.toJson(object),
|
body: serializable.toJson(object),
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Accept': 'application/json',
|
|
||||||
'X-CSRF-TOKEN': getCsrfToken(),
|
'X-CSRF-TOKEN': getCsrfToken(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user