Files
carmanagement/apps/public-site/src/app/book/confirmation/page.tsx
T

142 lines
5.6 KiB
TypeScript

import Link from 'next/link'
import { DEFAULT_COMPANY_SLUG, siteFetchOrDefault } from '@/lib/api'
import { getPublicSiteDictionary } from '@/lib/i18n'
import { getPublicSiteLanguage } from '@/lib/i18n.server'
import type { PublicSitePageSections } from '@rentaldrivego/types'
import { resolvePageSectionsConfig } from '@/lib/pageSections'
interface ReservationDetail {
id: string
status: string
startDate: string
endDate: string
totalDays: number
totalAmount: number
vehicleCategory: string | null
vehicle: { make: string; model: string; year: number } | null
customer: { firstName: string; lastName: string; email: string } | null
}
interface PageProps {
searchParams?: { id?: string }
}
interface BrandResponse {
brand: {
menuConfig?: {
pageSections?: Partial<PublicSitePageSections> | null
} | null
} | null
}
export const dynamic = 'force-dynamic'
export default async function BookingConfirmationPage({ searchParams = {} }: PageProps) {
const reservationId = searchParams.id
const slug = DEFAULT_COMPANY_SLUG
const dict = getPublicSiteDictionary(getPublicSiteLanguage())
const brand = await siteFetchOrDefault<BrandResponse | null>(`/site/${slug}/brand`, null)
const pageSections = resolvePageSectionsConfig(brand?.brand?.menuConfig)
const reservation = reservationId
? await siteFetchOrDefault<ReservationDetail | null>(
`/site/${slug}/booking/${reservationId}`,
null,
)
: null
return (
<main className="min-h-screen bg-slate-50 py-16">
<div className="shell max-w-2xl">
<div className="card p-10 text-center">
{pageSections.bookingConfirmation.hero ? (
<>
<div className="mx-auto mb-5 flex h-16 w-16 items-center justify-center rounded-full bg-emerald-100">
<svg className="h-8 w-8 text-emerald-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
</svg>
</div>
<p className="text-sm font-semibold uppercase tracking-[0.18em] text-emerald-700">{dict.confirmation.eyebrow}</p>
<h1 className="mt-3 text-4xl font-black text-slate-900">{dict.confirmation.title}</h1>
<p className="mt-4 text-slate-600">
{dict.confirmation.description}
</p>
</>
) : null}
{pageSections.bookingConfirmation.summary && reservation && (
<div className="mt-8 rounded-xl border border-slate-200 text-left divide-y divide-slate-100 overflow-hidden text-sm">
<div className="bg-slate-50 px-4 py-2.5 text-xs font-semibold uppercase tracking-[0.12em] text-slate-500">
{dict.confirmation.bookingSummary}
</div>
{reservation.vehicleCategory && (
<Row label={dict.confirmation.vehicleCategory} value={dict.vehicles.categoryLabels[reservation.vehicleCategory as keyof typeof dict.vehicles.categoryLabels] ?? reservation.vehicleCategory} />
)}
{reservation.customer && (
<Row label={dict.confirmation.customer} value={`${reservation.customer.firstName} ${reservation.customer.lastName}`} />
)}
{reservation.customer?.email && (
<Row label={dict.confirmation.email} value={reservation.customer.email} />
)}
<Row
label={dict.confirmation.dates}
value={`${new Date(reservation.startDate).toLocaleDateString()} -> ${new Date(reservation.endDate).toLocaleDateString()} (${reservation.totalDays})`}
/>
<Row
label={dict.confirmation.total}
value={`${reservation.totalAmount.toLocaleString('fr-MA', { style: 'currency', currency: 'MAD', maximumFractionDigits: 0 })}`}
valueClass="font-bold text-slate-900"
/>
<Row label={dict.confirmation.reference} value={reservation.id} valueClass="font-mono text-xs text-slate-500 break-all" />
<Row
label={dict.confirmation.status}
value={reservation.status}
valueClass="rounded-full bg-amber-100 text-amber-800 px-2 py-0.5 text-xs font-semibold uppercase"
/>
</div>
)}
{pageSections.bookingConfirmation.summary && !reservation && reservationId && (
<p className="mt-6 text-sm text-slate-500">
{dict.confirmation.reference}: <span className="font-mono">{reservationId}</span>
</p>
)}
{pageSections.bookingConfirmation.actions ? <div className="mt-8 flex flex-wrap justify-center gap-3">
<Link
href="/vehicles"
className="rounded-full bg-slate-900 px-6 py-3 text-sm font-semibold text-white"
>
{dict.confirmation.browseMoreVehicles}
</Link>
<Link
href="/"
className="rounded-full border border-slate-300 px-6 py-3 text-sm font-semibold text-slate-700"
>
{dict.confirmation.backHome}
</Link>
</div> : null}
</div>
</div>
</main>
)
}
function Row({
label,
value,
valueClass = 'text-slate-700 font-medium',
}: {
label: string
value: string
valueClass?: string
}) {
return (
<div className="flex justify-between gap-4 px-4 py-3">
<span className="flex-shrink-0 text-slate-500">{label}</span>
<span className={`text-right ${valueClass}`}>{value}</span>
</div>
)
}