From aae25097b149090a78e75bf616deb738b4b9c0b3 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 10 Oct 2025 22:03:55 +0000 Subject: [PATCH] Fix: Connect Reservations Manager to Frontend --- src/components/BookingModal.tsx | 197 ++++++++++++++++++++++++++++++ src/components/BookingSidebar.tsx | 75 +++++++++++- src/contexts/CartContext.tsx | 1 + src/hooks/useBooking.ts | 74 +++++++++++ src/pages/Checkout.tsx | 109 ++++++++++++----- src/pages/ListingDetails.tsx | 86 +++++++------ 6 files changed, 466 insertions(+), 76 deletions(-) create mode 100644 src/components/BookingModal.tsx create mode 100644 src/hooks/useBooking.ts diff --git a/src/components/BookingModal.tsx b/src/components/BookingModal.tsx new file mode 100644 index 0000000..f4e2d48 --- /dev/null +++ b/src/components/BookingModal.tsx @@ -0,0 +1,197 @@ +import React, { useState } from 'react'; +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { Loader2 } from 'lucide-react'; +import { useAuth } from '@/contexts/AuthContext'; +import { useBooking } from '@/hooks/useBooking'; +import { useToast } from '@/hooks/use-toast'; + +interface BookingModalProps { + open: boolean; + onClose: () => void; + listingId: string; + listingTitle: string; + listingPrice: number; + selectedDate?: Date; + selectedTimeSlot?: string; + guests: number; + onSuccess?: () => void; +} + +export const BookingModal: React.FC = ({ + open, + onClose, + listingId, + listingTitle, + listingPrice, + selectedDate, + selectedTimeSlot, + guests, + onSuccess +}) => { + const { user } = useAuth(); + const { createBooking, loading } = useBooking(); + const { toast } = useToast(); + + const [formData, setFormData] = useState({ + guestName: (user as any)?.name || '', + guestEmail: (user as any)?.email || '', + guestPhone: '', + specialRequests: '', + }); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!selectedDate) { + toast({ + title: 'Error', + description: 'Por favor selecciona una fecha', + variant: 'destructive', + }); + return; + } + + const checkInDate = new Date(selectedDate); + if (selectedTimeSlot) { + const [hours, minutes] = selectedTimeSlot.split(':'); + checkInDate.setHours(parseInt(hours), parseInt(minutes), 0, 0); + } + + const bookingData = { + listingId, + guestName: formData.guestName, + guestEmail: formData.guestEmail, + guestPhone: formData.guestPhone, + checkIn: checkInDate.toISOString(), + guests, + totalAmount: listingPrice * guests, + specialRequests: formData.specialRequests, + }; + + const result = await createBooking(bookingData); + + if (result.success) { + toast({ + title: '¡Reserva creada!', + description: 'Tu reserva ha sido creada exitosamente. Te enviaremos un correo de confirmación.', + }); + onClose(); + if (onSuccess) onSuccess(); + } else { + toast({ + title: 'Error', + description: result.error || 'No se pudo crear la reserva', + variant: 'destructive', + }); + } + }; + + const handleChange = (field: string, value: string) => { + setFormData(prev => ({ ...prev, [field]: value })); + }; + + return ( + + + + Confirmar Reserva + + Completa tus datos para confirmar la reserva de {listingTitle} + + + +
+ {/* Booking Summary */} +
+
+ Propiedad: + {listingTitle} +
+
+ Fecha: + + {selectedDate?.toLocaleDateString('es-ES', { + year: 'numeric', + month: 'long', + day: 'numeric' + })} + {selectedTimeSlot && ` - ${selectedTimeSlot}`} + +
+
+ Huéspedes: + {guests} {guests === 1 ? 'persona' : 'personas'} +
+
+ Total: + ${(listingPrice * guests).toLocaleString()} +
+
+ + {/* Guest Information */} +
+
+ + handleChange('guestName', e.target.value)} + required + placeholder="Tu nombre completo" + /> +
+ +
+ + handleChange('guestEmail', e.target.value)} + required + placeholder="tu@email.com" + /> +
+ +
+ + handleChange('guestPhone', e.target.value)} + required + placeholder="+1 234 567 890" + /> +
+ +
+ +