/** * Pure functions: group duties and calendar events by local date (YYYY-MM-DD). * Ported from webapp/js/calendar.js (dutiesByDate, calendarEventsByDate). */ import type { CalendarEvent, DutyWithUser } from "@/types"; import { localDateString } from "./date-utils"; /** Max days to iterate per duty; prevents infinite loop on corrupted API data (end_at < start_at). */ const MAX_DAYS_PER_DUTY = 366; /** * Build { localDateKey -> array of summary strings }. API date is UTC YYYY-MM-DD; map to local. */ export function calendarEventsByDate( events: CalendarEvent[] | null | undefined ): Record { const byDate: Record = {}; (events ?? []).forEach((e) => { const utcMidnight = new Date(e.date + "T00:00:00Z"); const key = localDateString(utcMidnight); if (!byDate[key]) byDate[key] = []; if (e.summary) byDate[key].push(e.summary); }); return byDate; } /** * Group duties by local date (start_at/end_at are UTC). */ export function dutiesByDate(duties: DutyWithUser[]): Record { const byDate: Record = {}; duties.forEach((d) => { const start = new Date(d.start_at); const end = new Date(d.end_at); if (end < start) return; const endLocal = localDateString(end); let cursor = new Date(start); let iterations = 0; while (iterations <= MAX_DAYS_PER_DUTY) { const key = localDateString(cursor); if (!byDate[key]) byDate[key] = []; byDate[key].push(d); if (key === endLocal) break; cursor.setDate(cursor.getDate() + 1); iterations++; } }); return byDate; }