Files
bun-notes/src/lib/snippetDeadline.ts
T
2026-04-16 16:30:29 +02:00

56 lines
1.8 KiB
TypeScript

/** Kalendertag lokal als `YYYY-MM-DD` (für Vergleich mit DB). */
export function localDateKey(d: Date): string {
const y = d.getFullYear();
const m = String(d.getMonth() + 1).padStart(2, "0");
const day = String(d.getDate()).padStart(2, "0");
return `${y}-${m}-${day}`;
}
/** UI-Wert für `<input type="date" />` aus API-Wert. */
export function deadlineToDateInput(deadlineAt: string | null | undefined): string {
if (!deadlineAt) return "";
const s = deadlineAt.trim();
if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return s;
const t = new Date(s);
if (Number.isNaN(t.getTime())) return "";
return localDateKey(t);
}
export type DeadlineTone = "none" | "upcoming" | "today" | "overdue";
/** Blau = künftig (nicht heute), Orange = heute fällig, Rot = überschritten. */
export function deadlineTone(deadlineAt: string | null | undefined): DeadlineTone {
if (!deadlineAt) return "none";
const key = deadlineToDateInput(deadlineAt);
if (!key) return "none";
const today = localDateKey(new Date());
if (key < today) return "overdue";
if (key === today) return "today";
return "upcoming";
}
export function deadlineBadgeClass(tone: DeadlineTone): string {
switch (tone) {
case "upcoming":
return "text-blue-500/70 text-blue-800 dark:text-blue-200";
case "today":
return "text-orange-500/80 text-orange-900 dark:text-orange-100";
case "overdue":
return "text-destructive/80 text-destructive";
default:
return "";
}
}
export function formatDeadlineLabel(deadlineAt: string): string {
const key = deadlineToDateInput(deadlineAt);
if (!key) return deadlineAt;
try {
const [y, m, d] = key.split("-").map(Number);
const dt = new Date(y, m - 1, d);
return dt.toLocaleDateString(undefined, { dateStyle: "medium" });
} catch {
return key;
}
}