From 2117655ec85d6f6f18342454f3637d62f9a5946c Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Sun, 16 Mar 2025 12:02:04 +0100 Subject: [PATCH] update rsvp-form handling the guest --- frontend/src/components/rsvp/rsvp-form.tsx | 127 ++++++++++++++++++--- 1 file changed, 108 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/rsvp/rsvp-form.tsx b/frontend/src/components/rsvp/rsvp-form.tsx index 2106436..eeedf94 100644 --- a/frontend/src/components/rsvp/rsvp-form.tsx +++ b/frontend/src/components/rsvp/rsvp-form.tsx @@ -1,6 +1,7 @@ "use client"; -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; import { useRSVPs } from "@/context/rsvp-context"; +import { useGuests } from "@/context/guest-context"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -13,42 +14,119 @@ import { } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; import { RsvpStatus } from "@/client/types.gen"; +import { useSearchParams } from "next/navigation"; +import { Loader2 } from "lucide-react"; interface RSVPProps { eventId: string; - guestId: string; onRSVPSuccess?: () => void; } -export const RSVP: React.FC = ({ - eventId, - guestId, - onRSVPSuccess, -}) => { +export const RSVP: React.FC = ({ eventId, onRSVPSuccess }) => { const { createRsvp } = useRSVPs(); + const { guests, isLoadingGuests } = useGuests(); + const searchParams = useSearchParams(); const [status, setStatus] = useState(RsvpStatus.ATTENDING); const [number_of_guests, setNumberOfGuests] = useState(1); const [response_message, setResponseMessage] = useState(""); const [dietary_requirements, setDietaryRequirements] = useState(""); + const [guestId, setGuestId] = useState(null); + const [isProcessing, setIsProcessing] = useState(false); + const [error, setError] = useState(null); + + // Extract invitation code from URL parameters + useEffect(() => { + const invitationCode = searchParams.get("code"); + if (!invitationCode) { + setError( + "Missing invitation code. Please use the link provided in your invitation.", + ); + return; + } + + // Find the guest with matching invitation code + if (guests && guests.length > 0) { + const matchingGuest = guests.find( + (guest) => guest.invitation_code === invitationCode, + ); + console.debug("matchingGuest", matchingGuest); + if (matchingGuest) { + setGuestId(matchingGuest.id); + setError(null); + } else { + setError("Invalid invitation code. Please check your invitation link."); + } + } + }, [searchParams, guests]); const submitRsvp = async (e: React.FormEvent) => { e.preventDefault(); - await createRsvp({ - event_id: eventId, - guest_id: guestId, - status, - number_of_guests, - response_message, - dietary_requirements, - }); + if (!guestId) { + setError( + "Cannot identify your invitation. Please check your link or contact the host.", + ); + return; + } - if (onRSVPSuccess) { - onRSVPSuccess(); + setIsProcessing(true); + setError(null); + + try { + await createRsvp({ + event_id: eventId, + guest_id: guestId, + status, + number_of_guests, + response_message, + dietary_requirements, + }); + + if (onRSVPSuccess) { + onRSVPSuccess(); + } + } catch (err) { + console.error("Error submitting RSVP:", err); + setError( + "Failed to submit your RSVP. Please try again or contact the host.", + ); + } finally { + setIsProcessing(false); } }; + // Show loading state while checking invitation code + if (isLoadingGuests) { + return ( +
+ +
+ ); + } + + // Show error if no valid invitation code + if (error) { + return ( +
+
+
+

+ Invitation Error +

+

{error}

+
+ +
+
+ ); + } + return (
@@ -123,8 +201,19 @@ export const RSVP: React.FC = ({
-