import { useState } from 'react'; import { format, startOfMonth, endOfMonth, startOfWeek, endOfWeek, eachDayOfInterval, isSameMonth, isSameDay, addMonths, subMonths, isWithinInterval, parseISO, isBefore } from 'date-fns'; import { es } from 'date-fns/locale/es'; import { ChevronLeft, ChevronRight } from 'lucide-react'; import { toast } from 'sonner'; import type { Reservation } from '../types'; interface Props { reservations: Reservation[]; onSelectRange: (start: Date, end: Date) => void; onSelectReservation: (reservation: Reservation) => void; } export function CustomMobileCalendar({ reservations, onSelectRange, onSelectReservation }: Props) { const [currentDate, setCurrentDate] = useState(new Date()); const [selectionStart, setSelectionStart] = useState(null); const monthStart = startOfMonth(currentDate); const monthEnd = endOfMonth(monthStart); const startDate = startOfWeek(monthStart, { weekStartsOn: 1, locale: es }); const endDate = endOfWeek(monthEnd, { weekStartsOn: 1, locale: es }); const days = eachDayOfInterval({ start: startDate, end: endDate }); const nextMonth = () => setCurrentDate(addMonths(currentDate, 1)); const prevMonth = () => setCurrentDate(subMonths(currentDate, 1)); const getReservationForDay = (day: Date) => { return reservations.find(res => isWithinInterval(day, { start: parseISO(res.start_date), end: parseISO(res.end_date) }) ); }; const rangeHasOverlap = (start: Date, end: Date) => { const rangeDays = eachDayOfInterval({ start, end }); return rangeDays.some(day => getReservationForDay(day)); }; const handleDayClick = (day: Date) => { const existingRes = getReservationForDay(day); if (existingRes) { onSelectReservation(existingRes); setSelectionStart(null); return; } if (!selectionStart) { setSelectionStart(day); return; } let start = selectionStart; let end = day; if (isBefore(day, selectionStart)) { start = day; end = selectionStart; } if (rangeHasOverlap(start, end)) { toast.error("No puedes seleccionar un rango que incluya días ya reservados."); setSelectionStart(null); return; } onSelectRange(start, end); setSelectionStart(null); }; return (
{/* Header */}

{format(currentDate, 'MMMM yyyy', { locale: es })}

{/* Week Days */}
{['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'].map(day => (
{day}
))}
{/* Days Grid - NUEVO DISEÑO TIPO AIRBNB */}
{days.map((day) => { const dayRes = getReservationForDay(day); const isSelected = selectionStart && isSameDay(day, selectionStart); const isCurrentMonth = isSameMonth(day, monthStart); // Palette de colores según referencia let bgColor = 'bg-white'; let numberBgColor = ''; let numberTextColor = 'text-gray-400'; if (dayRes) { if (dayRes.origin === 'Teneriffa2000') { bgColor = 'bg-blue-100'; // Fondo azul pastel numberBgColor = 'bg-blue-500'; // Círculo azul intenso numberTextColor = 'text-white'; } else { bgColor = 'bg-yellow-100'; // Fondo amarillo pastel numberBgColor = 'bg-yellow-500'; // Círculo amarillo intenso numberTextColor = 'text-white'; } } else if (isSelected) { bgColor = 'bg-gray-800'; numberBgColor = 'bg-white'; numberTextColor = 'text-gray-800'; } else if (isCurrentMonth) { numberTextColor = 'text-gray-900'; } return (
handleDayClick(day)} className={` relative h-12 flex items-center justify-center cursor-pointer transition-all duration-150 ${bgColor} `} >
{format(day, 'd')}
); })}
); }