"use server" import { redirect } from "next/navigation" import { replaceInvitationInteractions } from "@/lib/db/queries/interactions" import { getInvitationByToken, submitInvitationResponse } from "@/lib/db/queries/invitations" import { isRsvpClosed } from "@/lib/rsvp-deadline" import { interactionSubmissionSchema } from "@/lib/validation/interactions" import { mealPreferenceSchema, submitInvitationResponseSchema, } from "@/lib/validation/response" function optionalString(formData: FormData, key: string) { return formData.get(key)?.toString() ?? "" } function transportHelp(value: FormDataEntryValue | null) { if (value === "yes") return true if (value === "no") return false return null } function toastRequest(formData: FormData) { if (!formData.has("wantsToast")) return null const speakerName = optionalString(formData, "toastSpeakerName") if (!speakerName) return null return { memberId: optionalString(formData, "toastMemberId") || null, speakerName, estimatedMinutes: optionalString(formData, "toastEstimatedMinutes"), } } export async function submitRsvpAction(token: string, formData: FormData) { if (isRsvpClosed()) redirect(`/invite/${token}?error=closed`) const invitation = await getInvitationByToken(token) if (!invitation) redirect(`/invite/${token}?error=invalid`) const members = invitation.members.map((member) => { const attendingValue = formData.get(`attending-${member.id}`) if (attendingValue !== "yes" && attendingValue !== "no") { redirect(`/invite/${token}?error=generic`) } const attending = attendingValue === "yes" const meal = mealPreferenceSchema.safeParse( formData.get(`meal-${member.id}`)?.toString() ?? "", ) return { memberId: member.id, attending, mealPreference: attending && meal.success ? meal.data : null, dietaryRestrictions: optionalString(formData, `dietary-${member.id}`), } }) const response = submitInvitationResponseSchema.safeParse({ token, members, arrivalDate: formData.get("arrivalDate"), departureDate: formData.get("departureDate"), stayLocation: formData.get("stayLocation"), needsTransportHelp: transportHelp(formData.get("needsTransportHelp")), messageToCouple: formData.get("messageToCouple"), }) const interactions = interactionSubmissionSchema.safeParse({ invitationId: invitation.invitation.id, toastRequest: toastRequest(formData), }) if (!response.success || !interactions.success) { redirect(`/invite/${token}?error=generic`) } await submitInvitationResponse(response.data) await replaceInvitationInteractions(interactions.data) redirect(`/invite/${token}?submitted=1`) }