"use client"; import { useState, useMemo } from "react"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { useCalendar } from "./CalendarContext"; import { ChevronLeft, ChevronRight, Calendar as CalendarIcon, Clock, MapPin, } from "lucide-react"; import { format, startOfMonth, endOfMonth, startOfWeek, endOfWeek, addDays, isSameMonth, isSameDay, addMonths, subMonths, parseISO, isToday, } from "date-fns"; import { cn } from "@/lib/utils"; interface CalendarGridProps { onEventClick?: (event: CalendarEvent) => void; } interface CalendarEvent { id: string; summary: string; description?: string; start: { dateTime?: string; date?: string; }; end: { dateTime?: string; date?: string; }; location?: string; calendarId: string; calendarName: string; } function getEventDate(event: { start: { dateTime?: string; date?: string } }): Date { if (event.start.dateTime) { return parseISO(event.start.dateTime); } if (event.start.date) { return parseISO(event.start.date); } return new Date(); } function isAllDayEvent(event: { start: { dateTime?: string; date?: string } }): boolean { return !!event.start.date && !event.start.dateTime; } function getCalendarColor(calendarName: string): string { const colors: Record = { personal: "bg-pink-500 text-white", work: "bg-blue-500 text-white", health: "bg-green-500 text-white", social: "bg-purple-500 text-white", family: "bg-yellow-500 text-black", task: "bg-orange-500 text-white", primary: "bg-blue-600 text-white", }; const lower = calendarName.toLowerCase(); for (const [key, color] of Object.entries(colors)) { if (lower.includes(key)) return color; } return "bg-muted text-muted-foreground"; } export function CalendarGrid({ onEventClick }: CalendarGridProps) { const { events } = useCalendar(); const [currentMonth, setCurrentMonth] = useState(new Date()); const [selectedDate, setSelectedDate] = useState(null); // Get calendar days const calendarDays = useMemo(() => { const monthStart = startOfMonth(currentMonth); const monthEnd = endOfMonth(monthStart); const calendarStart = startOfWeek(monthStart, { weekStartsOn: 0 }); const calendarEnd = endOfWeek(monthEnd, { weekStartsOn: 0 }); const days: Date[] = []; let day = calendarStart; while (day <= calendarEnd) { days.push(day); day = addDays(day, 1); } return days; }, [currentMonth]); // Get events for a specific day const getEventsForDay = (date: Date): CalendarEvent[] => { return events.filter((event) => { const eventDate = getEventDate(event); return isSameDay(eventDate, date); }).sort((a, b) => { // All-day events first, then by time const aAllDay = isAllDayEvent(a); const bAllDay = isAllDayEvent(b); if (aAllDay && !bAllDay) return -1; if (!aAllDay && bAllDay) return 1; const aDate = getEventDate(a); const bDate = getEventDate(b); return aDate.getTime() - bDate.getTime(); }); }; const handlePrevMonth = () => setCurrentMonth(subMonths(currentMonth, 1)); const handleNextMonth = () => setCurrentMonth(addMonths(currentMonth, 1)); const handleToday = () => { const today = new Date(); setCurrentMonth(today); setSelectedDate(today); }; const weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; const selectedDateEvents = selectedDate ? getEventsForDay(selectedDate) : []; return (
{/* Calendar Header */}

{format(currentMonth, "MMMM yyyy")}

{/* Calendar Grid */} {/* Week Day Headers */}
{weekDays.map((day) => (
{day}
))}
{/* Calendar Days */}
{calendarDays.map((date, index) => { const dayEvents = getEventsForDay(date); const isCurrentMonth = isSameMonth(date, currentMonth); const isTodayDate = isToday(date); const isSelected = selectedDate && isSameDay(date, selectedDate); return ( ); })}
{/* Selected Day Details */} {selectedDate ? (

{isToday(selectedDate) ? "Today" : format(selectedDate, "EEEE, MMMM d")}

{selectedDateEvents.length} event {selectedDateEvents.length !== 1 ? "s" : ""}

{selectedDateEvents.length === 0 ? (

No events scheduled

) : (
{selectedDateEvents.map((event) => (
onEventClick?.(event)} className="p-3 rounded-lg border hover:bg-accent cursor-pointer transition-colors" >
{event.calendarName}

{event.summary}

{isAllDayEvent(event) ? ( All day ) : ( {format(getEventDate(event), "h:mm a")} )}
{event.location && (
{event.location}
)}
))}
)}
) : (

Select a date to view events

)}
); }