/** * Day-tab helpers (MSEP-3): users didn't discover the prev/next arrows, so the * calendar shows one labeled tab per fair day. Pure functions, kept * dependency-free so they are unit-testable without FullCalendar. */ /** Local-timezone ISO date (YYYY-MM-DD) — avoids toISOString() UTC shifts. */ export function isoDateOf(date: Date): string { const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${date.getFullYear()}-${month}-${day}`; } /** * All fair days as ISO dates, inclusive of the end date. * Accepts the API's datetime strings ("2026-06-17T23:59:59") or bare dates. * Capped at 60 days as a runaway guard for malformed ranges. */ export function listFairDays(startIso: string, endIso: string): string[] { const startDate = new Date(String(startIso).slice(0, 10) + 'T12:00:00'); const endDate = new Date(String(endIso).slice(0, 10) + 'T12:00:00'); if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) { return []; } const days: string[] = []; for ( let current = new Date(startDate); current <= endDate && days.length < 60; current.setDate(current.getDate() + 1) ) { days.push(isoDateOf(current)); } return days; } /** Localized tab label: weekday + short date (e.g. de: "Mo., 15.06."). */ export function formatDayLabel(isoDate: string, locale?: string): string { const date = new Date(isoDate + 'T12:00:00'); if (isNaN(date.getTime())) { return isoDate; } return date.toLocaleDateString(locale || undefined, { weekday: 'short', day: '2-digit', month: '2-digit', }); }