import PlayzerLogo from '@/assets/playzer-logo-transparent.svg'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { ResponsiveDialog, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogFooter, ResponsiveDialogHeader, ResponsiveDialogTitle, } from '@/components/ui/responsive-dialog'; import { apiClient } from '@/lib/api-client'; import { useMutation, useQuery } from '@tanstack/react-query'; import { useNavigate } from '@tanstack/react-router'; import { AlertCircle, ArrowRight, CalendarDays, CheckCircle2, Clock3, LoaderCircle, Receipt, Trophy, XCircle, } from 'lucide-react'; import { useState } from 'react'; import { ShareWhatsappButton } from './components/share-whatsapp-button'; type PublicBookingConfirmationPageProps = { complexSlug: string; bookingCode: string; }; function extractMessage(error: unknown, fallback: string) { const msg = (error as { message?: string } | undefined)?.message; return msg || fallback; } function formatDateLabel(isoDate: string | undefined | null) { if (!isoDate) return ''; const [year, month, day] = isoDate.split('-').map(Number); const date = new Date(year, (month ?? 1) - 1, day ?? 1); const label = new Intl.DateTimeFormat('es-AR', { weekday: 'long', day: '2-digit', month: 'long', }).format(date); return label.charAt(0).toUpperCase() + label.slice(1); } function formatBookingPrice(price: number): string { if (price === 0) { return 'Sin cargo'; } return new Intl.NumberFormat('es-AR', { style: 'currency', currency: 'ARS', maximumFractionDigits: Number.isInteger(price) ? 0 : 2, }).format(price); } export function PublicBookingConfirmationPage({ complexSlug, bookingCode, }: PublicBookingConfirmationPageProps) { const navigate = useNavigate(); const [cancelDialogOpen, setCancelDialogOpen] = useState(false); const [customerPhone, setCustomerPhone] = useState(''); const [cancelError, setCancelError] = useState(null); const [cancelledBooking, setCancelledBooking] = useState<{ date: string; startTime: string; endTime: string; courtName: string; sport: { name: string }; bookingCode: string; price: number; complexName: string; } | null>(null); const confirmationQuery = useQuery({ queryKey: ['public-booking-confirmation', complexSlug, bookingCode], queryFn: () => apiClient.publicBookings.getConfirmation(complexSlug, bookingCode), }); const cancelMutation = useMutation({ mutationFn: (phone: string) => apiClient.publicBookings.cancelPublic(complexSlug, { bookingCode, customerPhone: phone, }), }); const handleCancelClick = () => { cancelMutation.reset(); setCustomerPhone(''); setCancelError(null); setCancelDialogOpen(true); }; const handleConfirmCancel = async () => { setCancelError(null); try { const data = await cancelMutation.mutateAsync(customerPhone); setCancelledBooking(data); setCancelDialogOpen(false); setCustomerPhone(''); } catch (error: unknown) { console.error('[Cancel]', error); setCancelError( (error as { message?: string } | undefined)?.message ?? 'No pudimos cancelar la reserva.' ); } }; const isCancelled = cancelledBooking !== null; const displayData = cancelledBooking ?? confirmationQuery.data; return (
{confirmationQuery.isLoading && !cancelledBooking && (
Cargando confirmación...
)} {confirmationQuery.isError && !cancelledBooking && (

{extractMessage( confirmationQuery.error, 'No pudimos cargar la confirmación de la reserva.' )}

)} {displayData && (
{isCancelled ? (
Reserva cancelada
) : (
Reserva confirmada
)}

{displayData.complexName}

Playzer

Tu turno

{formatDateLabel(displayData.date)}

{displayData.startTime} - {displayData.endTime}

Precio del turno

{formatBookingPrice(displayData.price)}

Cancha

{displayData.courtName} · {displayData.sport.name}

Código de reserva

{displayData.bookingCode}

{isCancelled ? (
Esta reserva fue cancelada. Te enviamos un email con los detalles de la cancelación.
) : (
)}
)}
Cancelar reserva Ingresá el número de teléfono que usaste al hacer la reserva para confirmar la cancelación.
{ setCustomerPhone(e.target.value); setCancelError(null); }} /> {cancelError &&

{cancelError}

}
); }