import { Button } from '@/components/ui/button'; import { ResponsiveDialog, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogFooter, ResponsiveDialogHeader, ResponsiveDialogTitle, } from '@/components/ui/responsive-dialog'; import { Separator } from '@/components/ui/separator'; import { useIsMobile } from '@/hooks/use-mobile'; import { cn } from '@/lib/utils'; import { AlertTriangle, BadgeCheck, CalendarDays, CheckCircle2, Clock, MapPin, MessageCircle, Phone, User, Wrench, XCircle, } from 'lucide-react'; import { useBooking } from '../booking-provider'; function formatDate(date: string | undefined) { if (!date) return ''; const formatted = new Intl.DateTimeFormat('es-AR', { weekday: 'long', day: 'numeric', month: 'long', }).format(new Date(`${date}T00:00:00`)); return formatted .split(' ') .map((word, index) => { if (index === 0 || index === 3) { return word.charAt(0).toUpperCase() + word.slice(1); } return word; }) .join(' '); } const statusConfig: Record = { CONFIRMED: { label: 'Reservada', className: 'bg-emerald-500/15 text-emerald-400 border-emerald-500/30', }, COMPLETED: { label: 'Completada', className: 'bg-sky-500/15 text-sky-400 border-sky-500/30', }, CANCELLED: { label: 'Cancelada', className: 'bg-red-500/15 text-red-400 border-red-500/30', }, NOSHOW: { label: 'No show', className: 'bg-amber-500/15 text-amber-400 border-amber-500/30', }, }; export function BookingToolsDialog() { const { selectedSegment, bookingToolsOpen, closeBookingTools, updateBookingStatus } = useBooking(); const isMobile = useIsMobile(); const booking = selectedSegment?.booking; const status = statusConfig[booking?.status ?? 'CONFIRMED'] ?? { label: booking?.status, className: 'bg-slate-500/15 text-slate-300 border-slate-500/30', }; const sendWhatsappReminder = () => { const phone = booking?.customerPhone; if (!phone) return; const message = ` Hola ${booking?.customerName}. \nTe recordamos que tenés una reserva para el día *${formatDate(booking?.date)} de ${booking?.startTime} a ${booking?.endTime} en la cancha ${booking?.courtName} (${booking?.sport?.name})*. ¡Te esperamos! \nSi no vas a poder asistir, por favor avisanos para que otros clientes puedan reservar. Gracias.\n\n*Equipo de ${booking?.complexName}*`; const url = `https://wa.me/${phone}?text=${encodeURIComponent(message)}`; window.open(url, '_blank'); }; const updateStatus = (nextStatus: 'CANCELLED' | 'COMPLETED' | 'NOSHOW') => { if (!booking?.id) return; updateBookingStatus(booking.id, nextStatus); closeBookingTools(); }; if (isMobile) { return ( !open && closeBookingTools()} > event.preventDefault()} > updateStatus('COMPLETED')} onCancel={() => updateStatus('CANCELLED')} onReminder={sendWhatsappReminder} onNoShow={() => updateStatus('NOSHOW')} /> ); } return ( !open && closeBookingTools()}> event.preventDefault()} > Detalles de la reserva Administra la reserva y su estado.
} label="Cancha" value={selectedSegment?.booking?.courtName ?? '-'} helper={selectedSegment?.booking?.sport?.name} withDivider /> } label="Estado actual" value={status.label} valueClassName="text-emerald-400 uppercase dark:text-emerald-500" withDivider /> } label="Cliente" value={selectedSegment?.booking?.customerName ?? '-'} /> } label="Fecha" value={`${formatDate(selectedSegment?.booking?.date)}`} withDivider className="sm:pt-10" /> } label="Hora" value={`${selectedSegment?.booking?.startTime} a ${selectedSegment?.booking?.endTime}`} withDivider className="sm:pt-10" /> } label="Teléfono" value={selectedSegment?.booking?.customerPhone ?? '-'} className="sm:pt-10" />

Acciones disponibles

Elegí qué hacer según lo que ocurrió con el cliente.

} title="Completar reserva" description="El cliente se presentó para usar la cancha." className="border-emerald-500/40 bg-emerald-500/10 text-lg text-emerald-600 hover:bg-emerald-500/15 hover:text-emerald-800" onClick={() => { updateStatus('COMPLETED'); }} /> } title="Cancelar reserva" description="El cliente avisó que no va a venir. La cancha vuelve a estar disponible." className="border-red-500/40 bg-red-500/10 text-lg text-red-600 hover:bg-red-500/15 hover:text-red-800" onClick={() => { updateStatus('CANCELLED'); }} /> } title="Enviar recordatorio" description="Enviar un mensaje por WhatsApp al cliente." className="border-sky-500/40 bg-sky-500/10 text-lg text-sky-600 hover:bg-sky-500/15 hover:text-sky-800" onClick={sendWhatsappReminder} /> } title="Marcar como No Show" description="El cliente no vino y no canceló." className="border-amber-500/40 bg-amber-500/10 text-lg text-amber-600 hover:bg-amber-500/15 hover:text-amber-800" onClick={() => { updateStatus('NOSHOW'); }} />
); } function MobileBookingToolsSheet({ status, onComplete, onCancel, onReminder, onNoShow, }: { status: { label: string | undefined; className: string }; onComplete: () => void; onCancel: () => void; onReminder: () => void; onNoShow: () => void; }) { const { selectedSegment } = useBooking(); const booking = selectedSegment?.booking; return (
Reserva {booking?.courtName ?? '-'} · {booking?.startTime ?? '--:--'} a{' '} {booking?.endTime ?? '--:--'}
{status.label ?? '-'}

Cancha

{booking?.courtName ?? '-'}

{booking?.sport?.name ?? '-'}

} label="Cliente" value={booking?.customerName ?? '-'} /> } label="Teléfono" value={booking?.customerPhone ?? '-'} /> } label="Fecha" value={formatDate(booking?.date) || '-'} /> } label="Horario" value={`${booking?.startTime ?? '--:--'} a ${booking?.endTime ?? '--:--'}`} /> } label="Estado" value={status.label ?? '-'} valueClassName="uppercase text-primary" />

Acciones

} label="Completar" className="border-primary/45 bg-primary/12 text-primary" onClick={onComplete} /> } label="Recordar" className="border-reserved/45 bg-reserved/12 text-reserved" onClick={onReminder} /> } label="Cancelar" className="border-destructive/45 bg-destructive/12 text-destructive" onClick={onCancel} /> } label="No show" className="border-warning/50 bg-warning/12 text-warning" onClick={onNoShow} />
); } function MobileDetailRow({ icon, label, value, valueClassName, }: { icon: React.ReactNode; label: string; value: string; valueClassName?: string; }) { return (
{icon}

{label}

{value}

); } function MobileActionButton({ icon, label, className, onClick, }: { icon: React.ReactNode; label: string; className: string; onClick: () => void; }) { return ( ); } function DetailItem({ icon, label, value, helper, valueClassName, withDivider, className, }: { icon: React.ReactNode; label: string; value: string; helper?: string; valueClassName?: string; withDivider?: boolean; className?: string; }) { return (
{withDivider && (
)}
{icon}

{label}

{value}

{helper &&

{helper}

}
); } function ActionButton({ icon, title, description, className, onClick, }: { icon: React.ReactNode; title: string; description: string; className: string; onClick?: () => void; }) { return ( ); }