import { CheckCircle2, Circle, ClipboardList, PlayCircle, Repeat, Sparkles, XCircle, type LucideIcon } from "lucide-react"; import { Task, TaskStatus } from "@/lib/tasks/types"; import { TASK_STATUS_LABELS } from "@/lib/tasks/labels"; import { DueState } from "@/lib/tasks/today"; import { cn } from "@/lib/utils"; const STATUS_META: Record = { OPEN: { icon: Circle, className: "bg-muted text-foreground/80" }, IN_PROGRESS: { icon: PlayCircle, className: "bg-[color-mix(in_oklch,var(--chart-5)_16%,var(--card))] text-foreground", }, DONE: { icon: CheckCircle2, className: "bg-success/15 text-foreground" }, CANCELLED: { icon: XCircle, className: "bg-muted text-muted-foreground line-through" }, }; /** Status as icon AND word - never colour alone. */ export function TaskStatusPill({ status, className }: { status: TaskStatus; className?: string }) { const meta = STATUS_META[status]; const Icon = meta.icon; return ( {TASK_STATUS_LABELS[status]} ); } /** * Where a task came from. An automatic task is a suggestion to look at * something - it says nothing about work having been done. */ export function TaskSourceBadge({ task, }: { task: Pick; }) { const source = task.sourceAutomationTrigger ? { icon: Sparkles, label: "Vorschlag", title: "Automatisch vorgeschlagen – noch nichts erledigt" } : task.sourceTemplateId ? { icon: Repeat, label: "Wiederkehrend", title: "Aus einer wiederkehrenden Vorlage" } : task.sourceInspectionId ? { icon: ClipboardList, label: "Aus Durchsicht", title: "Bei einer Durchsicht angelegt" } : null; if (!source) return null; const Icon = source.icon; return ( {source.label} ); } const DUE_LABEL: Record, string> = { overdue: "Überfällig", today: "Heute", upcoming: "Geplant", }; export function DueChip({ state, dueDate }: { state: DueState; dueDate: string | null }) { if (state === "none" || !dueDate) { return ohne Termin; } const date = new Date(dueDate).toLocaleDateString("de-DE", { day: "numeric", month: "short", timeZone: "UTC", }); return ( {DUE_LABEL[state]} {state !== "today" ? · {date} : null} ); }