'use client'; import { useState, useEffect } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Calendar, Clock, MapPin, ChevronLeft, ChevronRight } from 'lucide-react'; import { useToast } from '@/hooks/use-toast'; interface Court { id: string; name: string; isActive: boolean; } interface Booking { id: string; courtId: string; date: string; startTime: string; endTime: string; status: string; userId: string; } interface BookingSlot { time: string; courtId: string; courtName: string; available: boolean; bookingId?: string; } export function BookingCalendar() { const [selectedDate, setSelectedDate] = useState(new Date()); const [courts, setCourts] = useState([]); const [bookings, setBookings] = useState([]); const [bookingSlots, setBookingSlots] = useState([]); const [loading, setLoading] = useState(false); const { toast } = useToast(); // Time slots for booking (7 PM to 11 PM) const timeSlots = ['19:00', '20:00', '21:00', '22:00']; useEffect(() => { fetchCourts(); }, []); useEffect(() => { if (courts.length > 0) { fetchBookings(); } }, [selectedDate, courts]); const fetchCourts = async () => { try { const response = await fetch('/api/admin/courts'); if (response.ok) { const data = await response.json(); setCourts(data.courts.filter((court: Court) => court.isActive)); } } catch (error) { console.error('Error fetching courts:', error); toast({ title: 'Error', description: 'Failed to fetch courts', variant: 'destructive', }); } }; const fetchBookings = async () => { try { const response = await fetch('/api/bookings'); if (response.ok) { const data = await response.json(); setBookings(data.bookings); generateBookingSlots(data.bookings); } } catch (error) { console.error('Error fetching bookings:', error); toast({ title: 'Error', description: 'Failed to fetch bookings', variant: 'destructive', }); } }; const generateBookingSlots = (existingBookings: Booking[]) => { const dateStr = selectedDate.toISOString().split('T')[0]; const slots: BookingSlot[] = []; courts.forEach((court) => { timeSlots.forEach((time) => { const existingBooking = existingBookings.find( (booking) => booking.courtId === court.id && booking.date === dateStr && booking.startTime === time && booking.status === 'active' ); slots.push({ time, courtId: court.id, courtName: court.name, available: !existingBooking, bookingId: existingBooking?.id, }); }); }); setBookingSlots(slots); }; const handleBookSlot = async (courtId: string, timeSlot: string) => { setLoading(true); try { const dateStr = selectedDate.toISOString().split('T')[0]; const response = await fetch('/api/bookings', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ courtId, date: dateStr, timeSlot, }), }); const data = await response.json(); if (response.ok) { toast({ title: 'Success', description: 'Booking created successfully!', }); fetchBookings(); // Refresh bookings } else { toast({ title: 'Error', description: data.error || 'Failed to create booking', variant: 'destructive', }); } } catch (error) { console.error('Error booking slot:', error); toast({ title: 'Error', description: 'Failed to create booking', variant: 'destructive', }); } finally { setLoading(false); } }; const navigateDate = (direction: 'prev' | 'next') => { const newDate = new Date(selectedDate); newDate.setDate(newDate.getDate() + (direction === 'next' ? 1 : -1)); setSelectedDate(newDate); }; const isToday = (date: Date) => { const today = new Date(); return date.toDateString() === today.toDateString(); }; const isPastDate = (date: Date) => { const today = new Date(); today.setHours(0, 0, 0, 0); return date < today; }; return ( Book Your Court
{/* Date Navigation */}

{selectedDate.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', })} {isToday(selectedDate) && (Today)}

{/* Loading State */} {loading && (

Loading booking slots...

)} {/* No Courts Available */} {!loading && courts.length === 0 && (

No courts available for booking

)} {/* Past Date Warning */} {isPastDate(selectedDate) && (

You cannot book courts for past dates. Please select a current or future date.

)} {/* Time Slots Grid */} {!loading && courts.length > 0 && !isPastDate(selectedDate) && (
{bookingSlots.map((slot, index) => (
{slot.time} -{' '} {String(parseInt(slot.time.split(':')[0]) + 1).padStart(2, '0')}:00
{slot.courtName}
{!slot.available && (
Already booked
)}
))}
)} {/* No Slots Message */} {!loading && courts.length > 0 && bookingSlots.length === 0 && !isPastDate(selectedDate) && (

No booking slots available for this date

)}
); }