/** * Colored segments (pill bar) for calendar day: duty (green), unavailable (amber), vacation (blue), events (accent). * Ported from webapp calendar day-indicator markup and markers.css. * * Rounding is position-based (first / last segment), so one or multiple segments always form a pill: * first segment gets left rounding, last segment gets right rounding (single segment gets both). */ import { cn } from "@/lib/utils"; export interface DayIndicatorsProps { /** Number of duty slots this day. */ dutyCount: number; /** Number of unavailable slots. */ unavailableCount: number; /** Number of vacation slots. */ vacationCount: number; /** Whether the day has external calendar events (e.g. holiday). */ hasEvents: boolean; /** When true (e.g. today cell), use darker segments for contrast. */ isToday?: boolean; className?: string; } export function DayIndicators({ dutyCount, unavailableCount, vacationCount, hasEvents, isToday = false, className, }: DayIndicatorsProps) { const hasAny = dutyCount > 0 || unavailableCount > 0 || vacationCount > 0 || hasEvents; if (!hasAny) return null; const dotClass = (variant: "duty" | "unavailable" | "vacation" | "events") => cn( "min-w-0 flex-1 h-1 max-h-1.5", variant === "duty" && "bg-duty", variant === "unavailable" && "bg-unavailable", variant === "vacation" && "bg-vacation", variant === "events" && "bg-accent", isToday && variant === "duty" && "bg-[var(--indicator-today-duty)]", isToday && variant === "unavailable" && "bg-[var(--indicator-today-unavailable)]", isToday && variant === "vacation" && "bg-[var(--indicator-today-vacation)]", isToday && variant === "events" && "bg-[var(--indicator-today-events)]" ); return (
:first-child]:rounded-l-[3px]", "[&>:last-child]:rounded-r-[3px]", className )} aria-hidden > {dutyCount > 0 && } {unavailableCount > 0 && } {vacationCount > 0 && } {hasEvents && }
); }