Files
wedding-website/app/invite/[token]/page.tsx
T
2026-09-12 23:50:10 +02:00

52 lines
2.3 KiB
TypeScript

import { WeddingInvite } from "@/components/invite/wedding-invite"
import { getInvitationInteractions } from "@/lib/db/queries/interactions"
import { getInvitationByToken } from "@/lib/db/queries/invitations"
import { getPhotoUploadByInvitationId } from "@/lib/db/queries/uploads"
import { getGuestDictionary } from "@/lib/i18n/get-dictionary"
import { isSupportedLanguage } from "@/lib/i18n/config"
import { getInvitePageContent } from "@/lib/i18n/invite-page/content"
import { isRsvpClosed } from "@/lib/rsvp-deadline"
import { createPresignedDownloadUrl } from "@/lib/storage/uploads"
import { submitRsvpAction } from "./actions"
export const dynamic = "force-dynamic"
export default async function InvitePage({
params,
searchParams,
}: {
params: Promise<{ token: string }>
searchParams: Promise<{ submitted?: string; error?: string }>
}) {
const [{ token }, { submitted, error }] = await Promise.all([params, searchParams])
const detail = await getInvitationByToken(token)
const dictionary = getGuestDictionary(detail?.invitation.language ?? "en")
if (!detail) {
return <main className="flex min-h-screen items-center justify-center bg-wedding-ivory px-wedding-gutter-mobile"><section className="max-w-lg border border-wedding-line bg-wedding-cream p-8 text-center"><p className="wedding-section-label">{dictionary.hero.eyebrow}</p><h1 className="wedding-display-heading mt-5 text-wedding-section">{dictionary.invalid.title}</h1><p className="mt-5 font-wedding-ui text-wedding-body leading-wedding-body">{dictionary.invalid.description}</p></section></main>
}
const language = isSupportedLanguage(detail.invitation.language) ? detail.invitation.language : "en"
const [interactions, photoUpload] = await Promise.all([
getInvitationInteractions(detail.invitation.id),
getPhotoUploadByInvitationId(detail.invitation.id),
])
const photo = photoUpload
? { filename: photoUpload.original_filename, url: await createPresignedDownloadUrl(photoUpload.object_key) }
: null
return <WeddingInvite
action={submitRsvpAction.bind(null, token)}
detail={detail}
token={token}
dictionary={dictionary}
content={getInvitePageContent(language)}
closed={isRsvpClosed()}
toastRequest={interactions.toastRequests[0]}
photo={photo}
submitted={submitted}
error={error}
/>
}