import { useEffect, useState } from 'react'; import { supabase } from '@/integrations/supabase/client'; import { AppLayout } from '@/components/AppLayout'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Skeleton } from '@/components/ui/skeleton'; import { Calendar as CalendarIcon, Video, BookOpen, Users, Clock, ChevronLeft, ChevronRight } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { format, startOfMonth, endOfMonth, eachDayOfInterval, isSameDay, isSameMonth, addMonths, subMonths, parseISO } from 'date-fns'; import { id } from 'date-fns/locale'; import { cn } from '@/lib/utils'; interface CalendarEvent { id: string; title: string; type: 'bootcamp' | 'webinar' | 'consulting'; date: string; start_time?: string; end_time?: string; description?: string; } export default function Calendar() { const [events, setEvents] = useState([]); const [loading, setLoading] = useState(true); const [currentMonth, setCurrentMonth] = useState(new Date()); const [selectedDate, setSelectedDate] = useState(null); useEffect(() => { fetchEvents(); }, [currentMonth]); const fetchEvents = async () => { const start = format(startOfMonth(currentMonth), 'yyyy-MM-dd'); const end = format(endOfMonth(currentMonth), 'yyyy-MM-dd'); // Fetch bootcamp events const { data: bootcamps } = await supabase .from('products') .select('id, title, event_start') .eq('type', 'bootcamp') .eq('is_active', true) .gte('event_start', start) .lte('event_start', end); // Fetch webinar events const { data: webinars } = await supabase .from('products') .select('id, title, event_start, duration_minutes') .eq('type', 'webinar') .eq('is_active', true) .gte('event_start', start) .lte('event_start', end); // Fetch confirmed consulting slots const { data: consultings } = await supabase .from('consulting_slots') .select('id, date, start_time, end_time, topic_category') .eq('status', 'confirmed') .gte('date', start) .lte('date', end); const allEvents: CalendarEvent[] = []; bootcamps?.forEach(b => { if (b.event_start) { allEvents.push({ id: b.id, title: b.title, type: 'bootcamp', date: b.event_start.split('T')[0], }); } }); webinars?.forEach(w => { if (w.event_start) { const eventDate = new Date(w.event_start); const durationMs = (w.duration_minutes || 60) * 60 * 1000; const endDate = new Date(eventDate.getTime() + durationMs); allEvents.push({ id: w.id, title: w.title, type: 'webinar', date: format(eventDate, 'yyyy-MM-dd'), start_time: format(eventDate, 'HH:mm'), end_time: format(endDate, 'HH:mm'), }); } }); consultings?.forEach(c => { allEvents.push({ id: c.id, title: `Konsultasi: ${c.topic_category}`, type: 'consulting', date: c.date, start_time: c.start_time?.substring(0, 5), end_time: c.end_time?.substring(0, 5), }); }); setEvents(allEvents); setLoading(false); }; const days = eachDayOfInterval({ start: startOfMonth(currentMonth), end: endOfMonth(currentMonth), }); const getEventsForDate = (date: Date) => { return events.filter(e => isSameDay(parseISO(e.date), date)); }; const getEventIcon = (type: string) => { switch (type) { case 'bootcamp': return ; case 'webinar': return