'use client'; import { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import { useTranslation } from 'react-i18next'; import { Calendar, ChevronLeft, ChevronRight, Home, Building, MapPin, Bed, Bath, Square, DollarSign, Eye, ArrowLeft, Loader2, Filter, Download, Printer, ChevronDown, X, CheckCircle, XCircle, Clock, Users, TrendingUp, CalendarDays, LayoutGrid, List, AlertCircle, XCircle as XCircleIcon, Calendar as CalendarIcon } from 'lucide-react'; import toast, { Toaster } from 'react-hot-toast'; import AuthService from '../../services/AuthService'; const MonthlyCalendar = ({ properties, selectedPropertyId, onDateClick, onPropertySelect }) => { const { t } = useTranslation(); const [currentMonth, setCurrentMonth] = useState(new Date()); const [selectedDate, setSelectedDate] = useState(null); const [viewType, setViewType] = useState('grid'); const monthNames = [ t('calendar.month1'), t('calendar.month2'), t('calendar.month3'), t('calendar.month4'), t('calendar.month5'), t('calendar.month6'), t('calendar.month7'), t('calendar.month8'), t('calendar.month9'), t('calendar.month10'), t('calendar.month11'), t('calendar.month12') ]; const daysInMonth = new Date( currentMonth.getFullYear(), currentMonth.getMonth() + 1, 0 ).getDate(); const firstDayOfMonth = new Date( currentMonth.getFullYear(), currentMonth.getMonth(), 1 ).getDay(); const isDateBookedForProperty = (date, property) => { if (!property?.bookings) return false; const dateStr = date.toISOString().split('T')[0]; return property.bookings.some(booking => { const start = new Date(booking.startDate); const end = new Date(booking.endDate); const current = new Date(date); return current >= start && current <= end; }); }; const getDayStatus = (date) => { if (selectedPropertyId === 'all') { const totalProperties = properties.length; const bookedCount = properties.filter(p => isDateBookedForProperty(date, p)).length; if (bookedCount === 0) return { status: 'all_available', label: t('calendar.allAvailable'), color: 'bg-green-100 text-green-800' }; if (bookedCount === totalProperties) return { status: 'all_booked', label: t('calendar.allBooked'), color: 'bg-red-100 text-red-800' }; return { status: 'partial', label: t('calendar.bookedCount', { count: bookedCount, total: totalProperties }), color: 'bg-yellow-100 text-yellow-800' }; } else { const property = properties.find(p => p.id === selectedPropertyId); if (!property) return { status: 'no_property', label: t('calendar.notAvailable'), color: 'bg-gray-100 text-gray-500' }; const isBooked = isDateBookedForProperty(date, property); return { status: isBooked ? 'booked' : 'available', label: isBooked ? t('calendar.booked') : t('calendar.available'), color: isBooked ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800' }; } }; const handleDateClick = (date) => { setSelectedDate(date); onDateClick?.(date); }; const changeMonth = (direction) => { setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + direction, 1)); }; const renderDays = () => { const days = []; const totalDays = daysInMonth + firstDayOfMonth; for (let i = 0; i < totalDays; i++) { if (i < firstDayOfMonth) { days.push(
); } else { const dayNumber = i - firstDayOfMonth + 1; const date = new Date( currentMonth.getFullYear(), currentMonth.getMonth(), dayNumber ); const isToday = date.toDateString() === new Date().toDateString(); const status = getDayStatus(date); const isSelected = selectedDate?.toDateString() === date.toDateString(); days.push( ); } } return days; }; return (

{monthNames[currentMonth.getMonth()]} {currentMonth.getFullYear()}

{[t('calendar.day1'), t('calendar.day2'), t('calendar.day3'), t('calendar.day4'), t('calendar.day5'), t('calendar.day6'), t('calendar.day7')].map((day, index) => (
{day}
))}
{renderDays()}
{t('calendar.available')}
{t('calendar.booked')}
{t('calendar.partiallyBooked')}
{t('calendar.today')}
{t('calendar.selected')}
); }; const PropertyCalendarList = ({ properties, selectedDate, onPropertyClick }) => { const { t } = useTranslation(); const formatCurrency = (amount) => { return amount?.toLocaleString() + ' ' + t('calendar.syp'); }; const isDateBooked = (property, date) => { if (!property?.bookings || !date) return false; const dateStr = date.toISOString().split('T')[0]; return property.bookings.some(booking => { const start = new Date(booking.startDate); const end = new Date(booking.endDate); const current = new Date(date); return current >= start && current <= end; }); }; const getBookingForDate = (property, date) => { if (!property?.bookings || !date) return null; const dateStr = date.toISOString().split('T')[0]; return property.bookings.find(booking => { const start = new Date(booking.startDate); const end = new Date(booking.endDate); const current = new Date(date); return current >= start && current <= end; }); }; if (!selectedDate) { return (

{t('calendar.selectDate')}

{t('calendar.clickDayHint')}

); } const formattedDate = selectedDate.toLocaleDateString('ar-SA', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); return (

{t('calendar.statusForDate')} {formattedDate}

{properties.map((property) => { const isBooked = isDateBooked(property, selectedDate); const booking = getBookingForDate(property, selectedDate); return ( onPropertyClick(property)} >

{property.title}

{isBooked ? t('calendar.booked') : t('calendar.available')}
{property.location}
{property.bedrooms} {t('calendar.rooms')}
{property.bathrooms} {t('calendar.bathrooms')}
{property.area} {t('calendar.sqm')}
{formatCurrency(property.price)}
{t('calendar.perDay')}
{isBooked && booking && (
{t('calendar.tenant')}: {booking.tenantName || t('calendar.unknown')}
{t('calendar.from')} {booking.startDate} {t('calendar.to')} {booking.endDate}
)}
); })}
); }; const PropertyDetailsModal = ({ property, isOpen, onClose }) => { const { t } = useTranslation(); if (!isOpen || !property) return null; const formatCurrency = (amount) => { return amount?.toLocaleString() + ' ' + t('calendar.syp'); }; return ( e.stopPropagation()} >

{property.title}

{property.location}

{property.images && property.images.length > 0 && (

{t('calendar.propertyImages')}

{property.images.slice(0, 4).map((image, index) => (
{`${property.title}
))}
)}
{property.bedrooms}
{t('calendar.bedrooms')}
{property.bathrooms}
{t('calendar.bathrooms')}
{property.area}
{t('calendar.sqm')}
{formatCurrency(property.price)}
{t('calendar.perDay')}
{property.features && property.features.length > 0 && (

{t('calendar.features')}

{property.features.map((feature, index) => ( {feature} ))}
)} {property.bookings && property.bookings.length > 0 && (

{t('calendar.upcomingBookings')}

{property.bookings.slice(0, 3).map((booking, index) => (

{booking.startDate} - {booking.endDate}

{t('calendar.tenant')}: {booking.tenantName || t('calendar.unknown')}

{formatCurrency(booking.totalAmount)}
))}
)}
{t('calendar.editProperty')}
); }; export default function OwnerCalendarPage() { const { t, i18n } = useTranslation(); const router = useRouter(); const [user, setUser] = useState(null); const [properties, setProperties] = useState([]); const [filteredProperties, setFilteredProperties] = useState([]); const [isLoading, setIsLoading] = useState(true); const [selectedPropertyId, setSelectedPropertyId] = useState('all'); const [selectedDate, setSelectedDate] = useState(null); const [selectedProperty, setSelectedProperty] = useState(null); const [showFilters, setShowFilters] = useState(false); useEffect(() => { const authUser = AuthService.getUser(); if (authUser && AuthService.isOwner()) { setUser({ name: authUser.name || authUser.email, email: authUser.email, role: 'owner', }); loadCalendar(); } else { router.push('/auth/choose-role'); } }, [router]); const loadProperties = () => { const storedProperties = localStorage.getItem('ownerProperties'); if (storedProperties) { const props = JSON.parse(storedProperties); setProperties(props); setFilteredProperties(props); } else { const mockProperties = [ { id: 1, title: t('calendar.mockVillaTitle'), location: t('calendar.mockVillaLocation'), bedrooms: 5, bathrooms: 4, area: 450, price: 500000, features: [t('swimmingPool'), t('privateGarden'), t('parking'), t('propertyService.security247')], images: ['/villa1.jpg'], status: 'available', bookings: [ { startDate: '2024-03-10', endDate: '2024-03-15', totalAmount: 2500000, tenantName: t('calendar.mockTenant1') }, { startDate: '2024-03-20', endDate: '2024-03-25', totalAmount: 2500000, tenantName: t('calendar.mockTenant2') } ] }, { id: 2, title: t('calendar.mockApartmentTitle'), location: t('calendar.mockApartmentLocation'), bedrooms: 3, bathrooms: 2, area: 180, price: 250000, features: [t('equippedKitchen'), t('balcony'), t('parking'), t('propertyService.elevator')], images: ['/apartment1.jpg'], status: 'available', bookings: [ { startDate: '2024-03-05', endDate: '2024-03-08', totalAmount: 750000, tenantName: t('calendar.mockTenant3') } ] }, { id: 3, title: t('calendar.mockHouseTitle'), location: t('calendar.mockHouseLocation'), bedrooms: 4, bathrooms: 3, area: 300, price: 350000, features: [t('largeGarden'), t('parking'), t('fireplace'), t('garage')], images: ['/house1.jpg'], status: 'booked', bookings: [] } ]; setProperties(mockProperties); setFilteredProperties(mockProperties); localStorage.setItem('ownerProperties', JSON.stringify(mockProperties)); } setIsLoading(false); }; const calendarStats = { totalProperties: properties.length, availableToday: properties.filter(p => { const today = new Date(); const isBooked = p.bookings?.some(b => { const start = new Date(b.startDate); const end = new Date(b.endDate); return today >= start && today <= end; }); return !isBooked; }).length, bookedToday: properties.filter(p => { const today = new Date(); return p.bookings?.some(b => { const start = new Date(b.startDate); const end = new Date(b.endDate); return today >= start && today <= end; }); }).length, upcomingBookings: properties.reduce((sum, p) => sum + (p.bookings?.length || 0), 0) }; if (isLoading) { return (

{t('calendar.loading')}

); } return (
setSelectedProperty(null)} />

{t('calendar.pageTitle')}

{t('calendar.welcomeMessage', { name: user?.name })}

{/* */}
{calendarStats.totalProperties}
{t('calendar.totalProperties')}
{calendarStats.availableToday}
{t('calendar.availableToday')}
{calendarStats.bookedToday}
{t('calendar.bookedToday')}
{calendarStats.upcomingBookings}
{t('calendar.upcomingBookings')}
{showFilters && (
)}
{selectedDate && ( {t('calendar.clickPropertyHint')} )}
); }