import Link from 'next/link'; import { ArrowLeft, BedDouble, CalendarDays, LogIn, LogOut, XCircle, User, } from 'lucide-react'; import { getTranslations } from 'next-intl/server'; import { formatDate, formatCurrencyAmount } from '@kit/shared/dates'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { Badge } from '@kit/ui/badge'; import { Button } from '@kit/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@kit/ui/card'; import { AccountNotFound } from '~/components/account-not-found'; import { CmsPageShell } from '~/components/cms-page-shell'; import { BOOKING_STATUS_VARIANT as STATUS_BADGE_VARIANT, BOOKING_STATUS_LABEL_KEYS as STATUS_LABEL_KEYS, } from '~/lib/status-badges'; interface PageProps { params: Promise<{ account: string; bookingId: string }>; } export default async function BookingDetailPage({ params }: PageProps) { const { account, bookingId } = await params; const client = getSupabaseServerClient(); const t = await getTranslations('bookings'); const { data: acct } = await client .from('accounts') .select('id') .eq('slug', account) .single(); if (!acct) { return ( ); } // Load booking directly const { data: booking } = await client .from('bookings') .select('*') .eq('id', bookingId) .eq('account_id', acct.id) .single(); if (!booking) { return (

{t('detail.notFoundDesc', { id: bookingId })}

); } // Load related room and guest data const [roomResult, guestResult] = await Promise.all([ booking.room_id ? client.from('rooms').select('*').eq('id', booking.room_id).single() : Promise.resolve({ data: null }), booking.guest_id ? client.from('guests').select('*').eq('id', booking.guest_id).single() : Promise.resolve({ data: null }), ]); const room = roomResult.data; const guest = guestResult.data; const status = String(booking.status ?? 'pending'); return (
{/* Header */}
{t(STATUS_LABEL_KEYS[status] ?? status)}

ID: {bookingId}

{/* Room */} {t('detail.room')} {room ? (
{t('detail.roomNumber')} {String(room.room_number)}
{room.name && (
{t('rooms.name')} {String(room.name)}
)}
{t('detail.type')} {String(room.room_type ?? '—')}
) : (

{t('detail.noRoom')}

)}
{/* Guest */} {t('detail.guest')} {guest ? (
{t('guests.name')} {String(guest.first_name)} {String(guest.last_name)}
{guest.email && (
{t('detail.email')} {String(guest.email)}
)} {guest.phone && (
{t('detail.phone')} {String(guest.phone)}
)}
) : (

{t('detail.noGuest')}

)}
{/* Stay */} {t('detail.stay')}
{t('list.checkIn')} {formatDate(booking.check_in)}
{t('list.checkOut')} {formatDate(booking.check_out)}
{t('detail.adults')} {booking.adults ?? '—'}
{t('detail.children')} {booking.children ?? 0}
{/* Amount */} {t('detail.amount')}
{t('detail.totalPrice')} {booking.total_price != null ? formatCurrencyAmount(booking.total_price as number) : '—'}
{booking.notes && (
{t('detail.notes')}

{String(booking.notes)}

)}
{/* Status Workflow */} {t('detail.actions')} {t('detail.changeStatus')}
{(status === 'pending' || status === 'confirmed') && ( )} {status === 'checked_in' && ( )} {status !== 'cancelled' && status !== 'checked_out' && status !== 'no_show' && ( )} {status === 'cancelled' || status === 'checked_out' ? (

{t('detail.noMoreActions', { statusLabel: status === 'cancelled' ? t('detail.cancelledStatus') : t('detail.completedStatus'), })}

) : null}
); }