102 lines
3.4 KiB
TypeScript
102 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import { useRouter } from "next/navigation";
|
|
import { useEffect } from "react";
|
|
import { useBooking } from "@/context/BookingContext";
|
|
import { useCurrency } from "@/context/CurrencyContext";
|
|
import { formatArrivalTimeDisplay } from "@/lib/formatArrivalTime";
|
|
import { siteConfig } from "@/lib/mocks/site";
|
|
|
|
export default function ConfirmationPage() {
|
|
const router = useRouter();
|
|
const {
|
|
confirmationId,
|
|
paidAt,
|
|
selectedRoom,
|
|
guest,
|
|
checkIn,
|
|
checkOut,
|
|
nights,
|
|
total,
|
|
resetBooking,
|
|
} = useBooking();
|
|
|
|
const { formatUsd } = useCurrency();
|
|
|
|
useEffect(() => {
|
|
if (!confirmationId) router.replace("/");
|
|
}, [confirmationId, router]);
|
|
|
|
if (!confirmationId || !selectedRoom) return null;
|
|
|
|
return (
|
|
<div className="mx-auto max-w-lg px-4 py-16 text-center md:py-24">
|
|
<div
|
|
className="mx-auto flex h-20 w-20 items-center justify-center rounded-full bg-[var(--color-success)] text-3xl text-white shadow-lg"
|
|
aria-hidden
|
|
>
|
|
✓
|
|
</div>
|
|
<h1 className="mt-8 font-display text-3xl md:text-4xl">Your booking is confirmed</h1>
|
|
<p className="mt-3 text-sm text-[var(--color-muted)]">
|
|
Thank you, {guest.firstName}. A mock itinerary email would be sent to {guest.email}.
|
|
</p>
|
|
<p className="mt-2 font-mono text-sm text-[var(--color-text)]">
|
|
Confirmation: {confirmationId}
|
|
</p>
|
|
{paidAt ? (
|
|
<p className="mt-1 text-xs text-[var(--color-muted)]">
|
|
Paid at: {new Date(paidAt).toLocaleString()}
|
|
</p>
|
|
) : null}
|
|
|
|
<div className="mt-10 overflow-hidden rounded-2xl border border-[var(--color-border)] bg-[var(--color-surface)] text-left shadow-sm">
|
|
<div className="relative aspect-[2/1] w-full">
|
|
<Image
|
|
src={selectedRoom.gallery[0]!}
|
|
alt={selectedRoom.name}
|
|
fill
|
|
className="object-cover"
|
|
sizes="(max-width:768px) 100vw, 512px"
|
|
/>
|
|
</div>
|
|
<div className="space-y-2 p-5 text-sm">
|
|
<p className="font-semibold">{siteConfig.name}</p>
|
|
<p>{selectedRoom.name}</p>
|
|
<p className="text-[var(--color-muted)]">
|
|
{checkIn} → {checkOut} · {nights} night{nights !== 1 ? "s" : ""}
|
|
</p>
|
|
<div className="border-t border-[var(--color-border)] pt-3 text-[var(--color-muted)]">
|
|
<p className="text-xs font-semibold uppercase tracking-wide text-[var(--color-text)]">
|
|
Flight arrival
|
|
</p>
|
|
<p className="mt-1">
|
|
Booking / PNR:{" "}
|
|
<span className="font-medium text-[var(--color-text)]">
|
|
{guest.flightBookingNumber.trim() || "—"}
|
|
</span>
|
|
</p>
|
|
<p className="mt-0.5">
|
|
Arrival (local):{" "}
|
|
<span className="font-medium text-[var(--color-text)]">
|
|
{formatArrivalTimeDisplay(guest.arrivalTime)}
|
|
</span>
|
|
</p>
|
|
</div>
|
|
<p className="font-semibold">Total paid: {formatUsd(total)}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<Link
|
|
href="/"
|
|
onClick={() => resetBooking()}
|
|
className="mt-10 inline-flex rounded-full bg-[var(--color-text)] px-10 py-3.5 text-sm font-semibold text-white hover:bg-[var(--color-primary)]"
|
|
>
|
|
Back to home
|
|
</Link>
|
|
</div>
|
|
);
|
|
}
|