"""Hilfsfunktionen des Projekte-Moduls. Enthält die feste Farbpalette (zyklisch zugewiesen), die Fälligkeits-Badge-Logik (portiert aus dem Prototyp `dueBadge`), die Aufgaben-Sortierung und ein locale-unabhängiges deutsches Datumslabel. """ from datetime import date # Feste Palette wie im Prototyp — neue Projekte bekommen zyklisch die nächste Farbe. PROJECT_COLORS = [ "#e94560", "#f5a623", "#4ecca3", "#a78bfa", "#60a5fa", "#f472b6", "#34d399", "#fb923c", "#818cf8", "#38bdf8", ] _WEEKDAYS_DE = [ "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag", ] _MONTHS_DE = [ "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", ] def next_color(existing_count: int) -> str: """Nächste Farbe aus der Palette (zyklisch nach Anzahl vorhandener Projekte).""" return PROJECT_COLORS[existing_count % len(PROJECT_COLORS)] def _fmt(d: date) -> str: """Datum als dd.mm.yy (wie im Prototyp).""" return f"{d.day:02d}.{d.month:02d}.{str(d.year)[2:]}" def due_badge(due: date | None, done: bool) -> dict: """Fälligkeits-Badge: CSS-Klasse + Text. Portiert aus dem Prototyp. - kein Datum -> 'kein Datum' (neutral) - erledigt -> Datum neutral - überfällig -> rot, mit Tagen drüber - <= 7 Tage -> orange, mit Resttagen - sonst -> grün """ if due is None: return {"cls": "due-none", "text": "kein Datum"} label = _fmt(due) if done: return {"cls": "due-none", "text": label} diff = (due - date.today()).days if diff < 0: return {"cls": "due-overdue", "text": f"⚠ {label} ({abs(diff)}d über)"} if diff <= 7: return {"cls": "due-soon", "text": f"⏳ {label} ({diff}d)"} return {"cls": "due-ok", "text": f"📅 {label}"} def sort_tasks(tasks: list) -> list: """Sortierung wie im Prototyp: offen vor erledigt, dann nach Datum (ohne zuletzt).""" return sorted( tasks, key=lambda t: (t.done, t.due_date is None, t.due_date or date.max), ) def today_label() -> str: """Deutsches Datumslabel ohne Locale-Abhängigkeit (z.B. 'Donnerstag, 11. Juni 2026').""" d = date.today() return f"{_WEEKDAYS_DE[d.weekday()]}, {d.day}. {_MONTHS_DE[d.month - 1]} {d.year}"