import Link from "next/link"; import { pool } from "../../../db/client"; export const dynamic = "force-dynamic"; type TicketRow = { order_id: string; quantity: number; amount_cents: number; status: string; checkout_provider: string; code: string | null; name: string; venue: string; starts_at: Date; }; export default async function TicketPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const result = await pool.query(` SELECT o.id AS order_id, o.quantity, o.amount_cents, o.status, o.checkout_provider, t.code, e.name, e.venue, e.starts_at FROM orders o JOIN events e ON e.id = o.event_id LEFT JOIN tickets t ON t.order_id = o.id WHERE o.id = $1 `, [id]); const ticket = result.rows[0]; if (!ticket) return

Ticket not found

Return to the workshop
; if (ticket.status !== "paid" || !ticket.code) { return

Payment pending

Your ticket is almost ready.

Stripe has not confirmed this test payment yet. Refresh after the webhook arrives.

; } return (

You have a place at the table

{ticket.name}

Ticket code{ticket.code}

{ticket.quantity} {ticket.quantity === 1 ? "seat" : "seats"} at {ticket.venue}

{new Intl.DateTimeFormat("en", { dateStyle: "full", timeStyle: "short", timeZone: "America/New_York" }).format(ticket.starts_at)}

{ticket.checkout_provider === "simulated" ? "Completed in free test order mode." : "Completed through Stripe test mode."}

Back to the event
); }