import { Calendar, CalendarEvent } from '/lib/models/calendar.ts'; import { getCalendarEventStyle } from '/lib/utils/calendar.ts'; interface CalendarViewDayProps { startDate: Date; visibleCalendars: Calendar[]; calendarEvents: CalendarEvent[]; onClickAddEvent: (startDate?: Date, isAllDay?: boolean) => void; onClickOpenEvent: (calendarEvent: CalendarEvent) => void; timezoneId: string; } export default function CalendarViewDay( { startDate, visibleCalendars, calendarEvents, onClickAddEvent, onClickOpenEvent, timezoneId }: CalendarViewDayProps, ) { const today = new Date().toISOString().substring(0, 10); const hourFormat = new Intl.DateTimeFormat('en-GB', { hour12: false, hour: '2-digit', minute: '2-digit', timeZone: timezoneId, // Calendar dates are parsed are stored without timezone info, so we need to force to a specific one so it's consistent across db, server, and client }); const dayFormat = new Intl.DateTimeFormat('en-GB', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric', timeZone: timezoneId, // Calendar dates are parsed without timezone info, so we need to force to a specific one so it's consistent across db, server, and client }); const allDayEvents: CalendarEvent[] = calendarEvents.filter((calendarEvent) => { if (!calendarEvent.isAllDay) { return false; } const startDayDate = new Date(startDate); const endDayDate = new Date(startDate); endDayDate.setUTCHours(23); endDayDate.setUTCMinutes(59); endDayDate.setUTCSeconds(59); endDayDate.setUTCMilliseconds(999); const eventStartDate = new Date(calendarEvent.startDate); const eventEndDate = new Date(calendarEvent.endDate); // Event starts and ends on this day if (eventStartDate >= startDayDate && eventEndDate <= endDayDate) { return true; } // Event starts before and ends after this day if (eventStartDate <= startDayDate && eventEndDate >= endDayDate) { return true; } // Event starts on and ends after this day if ( eventStartDate >= startDayDate && eventStartDate <= endDayDate && eventEndDate >= endDayDate ) { return true; } // Event starts before and ends on this day if ( eventStartDate <= startDayDate && eventEndDate >= startDayDate && eventEndDate <= endDayDate ) { return true; } return false; }); const hours: { date: Date; isCurrentHour: boolean }[] = Array.from({ length: 24 }).map((_, index) => { const hourNumber = index; const date = new Date(startDate); date.setUTCHours(hourNumber); const shortIsoDate = date.toISOString().substring(0, 10); const isCurrentHour = shortIsoDate === today && new Date().getUTCHours() === hourNumber; return { date, isCurrentHour, }; }); return (
{dayFormat.format(startDate)}
{allDayEvents.length > 0 ? (
    {allDayEvents.map((calendarEvent) => (
  1. onClickOpenEvent(calendarEvent)} >

    {calendarEvent.title}

  2. ))}
) : null} {hours.map((hour, hourIndex) => { const shortIsoDate = hour.date.toISOString().substring(0, 10); const startHourDate = new Date(shortIsoDate); startHourDate.setUTCHours(hour.date.getUTCHours()); const endHourDate = new Date(shortIsoDate); endHourDate.setUTCHours(hour.date.getUTCHours()); endHourDate.setUTCMinutes(59); endHourDate.setUTCSeconds(59); endHourDate.setUTCMilliseconds(999); const isLastHour = hourIndex === 23; const hourEvents = calendarEvents.filter((calendarEvent) => { if (calendarEvent.isAllDay) { return false; } const eventStartDate = new Date(calendarEvent.startDate); const eventEndDate = new Date(calendarEvent.endDate); eventEndDate.setUTCSeconds(eventEndDate.getUTCSeconds() - 1); // Take one second back so events don't bleed into the next hour // Event starts and ends on this hour if (eventStartDate >= startHourDate && eventEndDate <= endHourDate) { return true; } // Event starts before and ends after this hour if (eventStartDate <= startHourDate && eventEndDate >= endHourDate) { return true; } // Event starts on and ends after this hour if ( eventStartDate >= startHourDate && eventStartDate <= endHourDate && eventEndDate >= endHourDate ) { return true; } // Event starts before and ends on this hour if ( eventStartDate <= startHourDate && eventEndDate >= startHourDate && eventEndDate <= endHourDate ) { return true; } return false; }); return (
{hourEvents.length > 0 ? (
    {hourEvents.map((hourEvent) => (
  1. onClickOpenEvent(hourEvent)} >

    {hourEvent.title}

  2. ))}
) : null}
); })}
); }