Files

84 lines
2.7 KiB
TypeScript

"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`)
}