import React from 'react'; import { WEEKDAYS_SHORT, addDays, fromIso, monthEnd, todayIso, weekdayIndex } from '../../lib/format'; import { Avatar } from '../ui/controls'; import type { CalendarUser } from '../../lib/api'; import { holidaysOn, userColor, type CalendarIndex } from './calendarData'; /** * Zeitleiste: Personen in Zeilen, Tage des Monats in Spalten. Zeigt auf einen * Blick, wo sich Urlaube ueberschneiden. Breiter als das Handy - die Tabelle * scrollt seitlich, die Namensspalte bleibt stehen. */ export const Timeline: React.FC<{ month: string; index: CalendarIndex; users: CalendarUser[]; selected: string | null; onSelect: (day: string) => void; }> = ({ month, index, users, selected, onSelect }) => { const today = todayIso(); const days: string[] = []; for (let d = month; d <= monthEnd(month); d = addDays(d, 1)) days.push(d); return (
{days.map((day) => { const weekend = weekdayIndex(day) >= 5; const holidays = holidaysOn(index, day); return ( ); })} {users.map((user) => { const entries = index.byUser.get(user.id); const color = userColor(user); return ( {days.map((day) => { const entry = entries?.get(day); const weekend = weekdayIndex(day) >= 5; const vacation = entry?.kind === 'vacation'; // Aneinanderstossende Urlaubstage als ein Balken zeichnen. const prev = entries?.get(addDays(day, -1))?.kind === 'vacation'; const next = entries?.get(addDays(day, 1))?.kind === 'vacation'; return ( ); })} ); })}
Mitarbeiter onSelect(day)} className={`min-w-[28px] cursor-pointer border-b border-ink-200 px-0 py-1.5 text-center font-extrabold ${ day === selected ? 'bg-brand-100 text-brand-700' : holidays.length ? 'bg-amber-50 text-amber-700' : weekend ? 'bg-ink-50 text-ink-400' : 'text-ink-600' }`} > {WEEKDAYS_SHORT[weekdayIndex(day)].slice(0, 2)} {fromIso(day).getDate()}
{user.name} onSelect(day)} className={`h-9 cursor-pointer border-b border-ink-100 px-0 py-1 ${ day === selected ? 'bg-brand-50' : entry?.kind === 'holiday' ? 'bg-amber-50' : weekend ? 'bg-ink-50/70' : '' }`} > {vacation && ( )} {entry?.kind === 'holiday' && }
); };