import { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Textarea } from "@/components/ui/textarea"; import { useAuth } from "@/context/AuthContext"; import { apiGet, apiPatch } from "@/lib/api"; import { isLikelyApiHotelBooking, mapApiBookingToBooking } from "@/lib/hotel-adapters"; import type { Booking } from "@/lib/types"; import { useAuthStore } from "@/store/authStore"; import { formatDate, formatDateTime, formatMoney } from "@/lib/format"; import { roomDisplayName } from "@/lib/room-utils"; export function BookingDetailPage() { const { id } = useParams<{ id: string }>(); const selectedPropertyId = useAuthStore((s) => s.selectedPropertyId); const [b, setB] = useState(null); const [note, setNote] = useState(""); const { canEditBookings } = useAuth(); useEffect(() => { if (!id) return; apiGet(`/bookings/${id}`) .then((raw) => { if (isLikelyApiHotelBooking(raw)) setB(mapApiBookingToBooking(raw)); else setB(raw as Booking); }) .catch(console.error); }, [id, selectedPropertyId]); if (!b) return

Loading…

; async function addNote() { if (!b || !note.trim() || !canEditBookings) return; const next = await apiPatch(`/bookings/${b.id}`, { internalNotes: [note.trim()], }); setB( isLikelyApiHotelBooking(next) ? mapApiBookingToBooking(next) : (next as Booking) ); setNote(""); } return (

{b.guest.firstName} {b.guest.lastName}

{b.id}

{b.status}
Guest

Email:{" "} {b.guest.email}

Phone:{" "} {b.guest.phone}

PNR:{" "} {b.guest.flightBookingNumber}

Arrival:{" "} {b.guest.arrivalTime}

Stay

{formatDate(b.checkIn)} → {formatDate(b.checkOut)} ({b.nights}{" "} nights)

Guests: {b.guests}

Room: {b.roomDisplayLabel ?? roomDisplayName(b.roomId)}

{b.holdReference &&

Hold: {b.holdReference}

} {b.confirmationId &&

Payment ref: {b.confirmationId}

} {b.paidAt &&

Paid: {formatDateTime(b.paidAt)}

}
Pricing

Nightly subtotal: {formatMoney(b.pricing.nightlySubtotal)}

Coupon: {b.pricing.couponCode ?? "—"}

Discount: {b.pricing.discountPercent}%

Tax: {formatMoney(b.pricing.taxAmount)}

Total: {formatMoney(b.pricing.total)}

Referral: {b.referralCode ?? "—"}

Internal notes
    {(b.internalNotes ?? []).map((n, i) => (
  • {n}
  • ))}
{canEditBookings && ( <>