update rsvp-form handling the guest

This commit is contained in:
2025-03-16 12:02:04 +01:00
parent a38eca3377
commit 2117655ec8

View File

@@ -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,28 +14,66 @@ 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<RSVPProps> = ({
eventId,
guestId,
onRSVPSuccess,
}) => {
export const RSVP: React.FC<RSVPProps> = ({ eventId, onRSVPSuccess }) => {
const { createRsvp } = useRSVPs();
const { guests, isLoadingGuests } = useGuests();
const searchParams = useSearchParams();
const [status, setStatus] = useState<RsvpStatus>(RsvpStatus.ATTENDING);
const [number_of_guests, setNumberOfGuests] = useState<number>(1);
const [response_message, setResponseMessage] = useState("");
const [dietary_requirements, setDietaryRequirements] = useState("");
const [guestId, setGuestId] = useState<string | null>(null);
const [isProcessing, setIsProcessing] = useState(false);
const [error, setError] = useState<string | null>(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();
if (!guestId) {
setError(
"Cannot identify your invitation. Please check your link or contact the host.",
);
return;
}
setIsProcessing(true);
setError(null);
try {
await createRsvp({
event_id: eventId,
guest_id: guestId,
@@ -47,8 +86,47 @@ export const RSVP: React.FC<RSVPProps> = ({
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 (
<div className="w-full bg-card text-card-foreground rounded-lg border shadow-sm p-6 flex justify-center items-center min-h-[300px]">
<Loader2 className="h-8 w-8 animate-spin text-primary" />
</div>
);
}
// Show error if no valid invitation code
if (error) {
return (
<div className="w-full bg-card text-card-foreground rounded-lg border shadow-sm">
<div className="p-6 flex flex-col gap-6">
<div>
<h2 className="text-lg font-medium text-destructive">
Invitation Error
</h2>
<p className="mt-2 text-muted-foreground">{error}</p>
</div>
<Button
onClick={() => (window.location.href = "/")}
className="w-full md:w-auto self-end"
>
Return Home
</Button>
</div>
</div>
);
}
return (
<div className="w-full bg-card text-card-foreground rounded-lg border shadow-sm">
<div className="p-6 flex flex-col gap-6">
@@ -123,8 +201,19 @@ export const RSVP: React.FC<RSVPProps> = ({
</div>
<div className="flex justify-end mt-6">
<Button type="submit" className="w-full md:w-auto">
Submit RSVP
<Button
type="submit"
className="w-full md:w-auto"
disabled={isProcessing}
>
{isProcessing ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Submitting...
</>
) : (
"Submit RSVP"
)}
</Button>
</div>
</form>