export type LifecycleStatus = "draft" | "scheduled" | "published" | "archived"; export function slugify(text: string): string { return text .toLowerCase() .normalize("NFKD") .replace(/[^a-z0-9\s-]/g, "") .replace(/\s+/g, "-") .replace(/-+/g, "-") .slice(0, 100) .replace(/^-|-$/g, ""); } function stripHtml(html: string): string { return html.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim(); } export function extractH1Title(html: string): string { const match = html.match(/]*>([\s\S]*?)<\/h1>/i); if (!match?.[1]) return ""; return stripHtml(match[1]).slice(0, 160).trim(); } export function toDateValue(date?: Date | string | null) { if (!date) return ""; return new Date(date).toISOString().slice(0, 10); } export function toTimeValue(date?: Date | string | null) { if (!date) return ""; return new Date(date).toISOString().slice(11, 16); } export function combineDateTime(date: string, time: string) { if (!date || !time) return undefined; return new Date(`${date}T${time}:00`); } export function isSchedulingVisible(status: LifecycleStatus) { return status === "draft" || status === "scheduled"; } export function validatePublishInputs( status: LifecycleStatus, publishDate: string, publishTime: string, ) { if (!isSchedulingVisible(status)) return null; if (status === "scheduled" && (!publishDate || !publishTime)) { return "Für den Status Geplant sind Datum und Uhrzeit erforderlich."; } if ((publishDate && !publishTime) || (!publishDate && publishTime)) { return "Bitte Datum und Uhrzeit gemeinsam setzen."; } return null; } export function resolveSubmitStatus( status: LifecycleStatus, publishDate: string, publishTime: string, ) { if (status === "draft" && publishDate && publishTime) return "scheduled" as const; return status; } export function statusLabel(status: LifecycleStatus) { if (status === "archived") return "Archiviert"; if (status === "published") return "Veröffentlicht"; if (status === "scheduled") return "Geplant"; return "Entwurf"; } export function statusClass(status: LifecycleStatus) { if (status === "archived") return "bg-gray-200 text-gray-700 dark:bg-neutral-700 dark:text-neutral-300"; if (status === "published") return "bg-green-50 text-green-700 dark:bg-green-950/50 dark:text-green-400"; if (status === "scheduled") return "bg-indigo-50 text-indigo-700 dark:bg-indigo-950/50 dark:text-indigo-400"; return "bg-gray-100 text-gray-500 dark:bg-neutral-700 dark:text-neutral-400"; }