import React from 'react'; import { format, startOfWeek, endOfWeek, eachDayOfInterval, isToday, addHours, } from 'date-fns'; interface CalendarEvent { id: string; title: string; start: Date; end: Date; type: 'task' | 'event' | 'google'; color?: string; } interface CalendarWeekViewProps { currentDate: Date; events: CalendarEvent[]; onDateClick?: (date: Date) => void; onEventClick?: (event: CalendarEvent) => void; onTimeSlotClick?: (date: Date, hour: number) => void; } const CalendarWeekView: React.FC = ({ currentDate, events, onEventClick, onTimeSlotClick, }) => { const weekStart = startOfWeek(currentDate, { weekStartsOn: 1 }); const weekEnd = endOfWeek(currentDate, { weekStartsOn: 1 }); const weekDays = eachDayOfInterval({ start: weekStart, end: weekEnd }); const hours = Array.from({ length: 24 }, (_, i) => i); const getEventsForTimeSlot = (day: Date, hour: number) => { return events.filter((event) => { const eventDay = format(event.start, 'yyyy-MM-dd'); const slotDay = format(day, 'yyyy-MM-dd'); const eventHour = event.start.getHours(); return eventDay === slotDay && eventHour === hour; }); }; const handleTimeSlotClick = (day: Date, hour: number) => { if (onTimeSlotClick) { onTimeSlotClick(day, hour); } }; const handleEventClick = (event: CalendarEvent, e: React.MouseEvent) => { e.stopPropagation(); if (onEventClick) { onEventClick(event); } }; return (
{/* Header with days */}
Time
{weekDays.map((day) => (
{format(day, 'EEE')}
{isToday(day) ? ( {format(day, 'd')} ) : ( format(day, 'd') )}
))}
{/* Time slots */}
{hours.map((hour) => (
{/* Time column */}
{format( addHours(new Date().setHours(hour, 0, 0, 0), 0), 'HH:mm' )}
{/* Day columns */} {weekDays.map((day) => { const timeSlotEvents = getEventsForTimeSlot( day, hour ); return (
handleTimeSlotClick(day, hour) } className={`h-12 p-1 border-l border-gray-100 dark:border-gray-800 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 relative ${ isToday(day) ? 'bg-blue-50/30 dark:bg-blue-900/10' : '' }`} > {timeSlotEvents.map((event) => (
handleEventClick(event, e) } className={`text-xs p-1 rounded text-white truncate cursor-pointer hover:opacity-80 transition-opacity absolute inset-1 ${ event.type === 'task' ? 'border-l-2 border-l-white/50' : '' }`} style={{ backgroundColor: event.color || '#3b82f6', }} title={`${event.type === 'task' ? '📋 ' : ''}${event.title} - ${format(event.start, 'HH:mm')} to ${format(event.end, 'HH:mm')}`} > {event.type === 'task' && '📋 '} {event.title}
))}
); })}
))}
); }; export default CalendarWeekView;