diff --git a/peopleportal/server/src/controllers/EventController.ts b/peopleportal/server/src/controllers/EventController.ts index 59ed209..5b4b416 100644 --- a/peopleportal/server/src/controllers/EventController.ts +++ b/peopleportal/server/src/controllers/EventController.ts @@ -815,6 +815,14 @@ export class EventController extends Controller { throw new CustomValidationError(404, `No event with id ${eventId}`); } + // RSVPs close when the event starts. + if (event.startTime.getTime() <= Date.now()) { + throw new CustomValidationError( + 400, + "RSVPs are closed because this event has already started.", + ); + } + // Ensure email is available through session or tempsession const email = req.session.authorizedUser?.email ?? diff --git a/peopleportal/webui/src/components/fabric/EventAttendance.tsx b/peopleportal/webui/src/components/fabric/EventAttendance.tsx index 6619dd9..bdcca6c 100644 --- a/peopleportal/webui/src/components/fabric/EventAttendance.tsx +++ b/peopleportal/webui/src/components/fabric/EventAttendance.tsx @@ -454,6 +454,10 @@ export const EventAttendance = () => { setDialogOpen(true); }; + // RSVPs close when the event starts (the server enforces this too). + const rsvpClosed = + event !== null && new Date(event.startTime).getTime() <= Date.now(); + const submitRsvp = async (acceptRsvp: boolean) => { const res = await fetch( `${PEOPLEPORTAL_SERVER_ENDPOINT}/api/events/${eventId}/rsvp`, @@ -468,7 +472,10 @@ export const EventAttendance = () => { ); if (!res.ok) { - toast.error(`Failed to RSVP to event: ${res.statusText}`); + const body = await res.json().catch(() => null); + toast.error( + `Failed to RSVP to event: ${body?.message ?? res.statusText}`, + ); return; } @@ -700,6 +707,18 @@ export const EventAttendance = () => {

RSVP

{loading ? ( + ) : rsvp === null && rsvpClosed ? ( + + + + RSVPs are closed + + + This event has already started, so RSVPs are + no longer accepted. + + + ) : rsvp === null ? ( @@ -762,7 +781,13 @@ export const EventAttendance = () => { : "Declined"} - {updating ? ( + {rsvpClosed ? ( + +

+ RSVPs closed when this event started. +

+
+ ) : updating ? ( <>