# Epic 22 — UI-Redesign Runde 2 (Patterns aus ai-coding-starter-kit-v2) Details zu UI2-001 … UI2-010, alle offen/ungeplant (Backlog-Planung, bewusst noch nicht gestartet). Ausgangspunkt: Subagenten-Analyse von `gitea.perlbach24.de/scripte/ai-coding-starter-kit-v2` (2026-09-08), vertieft am 2026-09-09, reines shadcn/ui-Komponenten-Skelett (Vite/React/TS, Tailwind v3, Radix, react-hook-form+zod). Kein Framework-Wechsel, kein Neubau — Epic 20 (UI-001..008) bleibt Grundlage, hier werden zusätzliche, im Code konkret nachgewiesene Lücken geschlossen. **Kein kompletter Frontend-Neubau** — bewusste Entscheidung, siehe Chat 2026-09-08. --- ## UI2-001 — Granularere Design-Tokens (Card/Popover/Sidebar) - **Ziel:** Card-/Popover-/Sidebar-Hintergründe über eigene Tokens statt generischem `--color-primary`/`bg-white`. - **Beschreibung:** `--color-card`, `--color-card-foreground`, `--color-popover` etc. in `frontend/src/styles/global/tokens.css` ergänzen (Light+Dark), bestehende Komponenten schrittweise umstellen. - **Benutzerwert:** Konsistentere Flächenhierarchie, einfacheres Dark-Mode-Feintuning. - **Abhängigkeiten:** UI-001 (bereits erledigt) - **Backend:** keins - **Frontend:** `styles/global/tokens.css` - **Rechte:** keine Änderung - **Akzeptanzkriterien:** neue Tokens vorhanden, mind. Card-Komponente nutzt sie statt Hardcoded-Werten. - **Tests:** keine (reines Styling). - **ACHTUNG (QA-Review 2026-09-09, siehe CLAUDE.md „Wichtige Stolperfallen"):** Neue Token-Namen in `tokens.css` dürfen NIEMALS denselben Namen wie ein Tailwind-`@theme`-Token bekommen — führte in diesem Projekt bereits zweimal zu app-weit kaputten Farben (zirkuläre Custom-Properties, guaranteed-invalid value). Vor dem Anlegen von `--color-card` etc. gegen `tailwind.css`/`@theme` prüfen, keine Namenskollision. Diese Warnung gilt für UI2-001 als Basis genauso wie für UI2-010 (Dark-Mode-Vorbereitung), die direkt darauf aufbaut. - **DoD:** offen. ## UI2-002 — AdminPage Sidebar/Sheet-Umschaltung - **Ziel:** Touch-taugliche Navigation für AdminPage-Tabs — Desktop Sidebar, Mobile Sheet-Overlay statt aktuellem Tab-Leisten-Umbruch. - **Beschreibung:** Pattern aus Starter-Kit (`useIsMobile`-Hook + Radix-Dialog-Sheet), MABEA hat bereits `useIsDesktop` — Umschaltung analog, kein natives Drag&Drop. - **Benutzerwert:** Bessere Bedienbarkeit auf Tablet im Feld. - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** `AdminPage.tsx`, ggf. neue `components/ui/sheet.tsx` - **Mobile:** Priorität — Zielgerät Tablet - **Rechte:** keine Änderung - **Akzeptanzkriterien:** AdminPage-Tabs auf schmalem Viewport über Sheet erreichbar, bestehende Tab-Inhalte unverändert. - **Tests:** keine neuen (reines UI/Routing). - **DoD:** offen. ## UI2-003 — Formular-Feld-Komposition - **Ziel:** Wiederverwendbarer Feld-Baustein (Label+Input+Fehlermeldung) statt individueller State-Verdrahtung pro Feld in Formularen. - **Beschreibung:** Leichtgewichtiges `FormField`-Pattern (kein react-hook-form/zod nötig, MABEA nutzt bereits einfache `useState`-Formulare — nur Layout/Fehler- Darstellung vereinheitlichen), zuerst in `ObjektAnlegenFormular.tsx` und `ObjekttypSection.tsx` angewendet. - **Benutzerwert:** Einheitliche Fehlerdarstellung, weniger Boilerplate bei neuen Formularen. - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** neue `components/ui/form-field.tsx`, `ObjektAnlegenFormular.tsx`, `ObjekttypSection.tsx` darauf umgestellt - **Rechte:** keine Änderung - **Akzeptanzkriterien:** beide Formulare nutzen den neuen Baustein, Verhalten unverändert. - **Tests:** bestehende Vitest-Tests bleiben grün. - **DoD:** offen. - **Referenz (vertiefte Starter-Kit-Analyse 2026-09-09):** `form.tsx` im Quell-Repo verdrahtet a11y konkret statt nur visuell — `FormLabel` wird bei Fehler rot, `FormControl` setzt `aria-invalid`, `FormMessage` nur bei vorhandenem Error gerendert, `aria-describedby` verlinkt zur Fehlermeldung. 1:1 mit MABEAs `useState`-Ansatz nachbaubar (kein react-hook-form/Context nötig) — sollte in den `FormField`-Baustein mit einfließen, nicht nur reines Layout. ## UI2-009 — Formular-Fehlerzustand-Verdrahtung (a11y, ergänzt UI2-003) - **Ziel:** `aria-invalid`/`aria-describedby`/Fehlerfarbe systematisch statt nur visuell. - **Beschreibung:** siehe Referenz-Absatz bei UI2-003 — kein eigenständiges Feature, sondern eine konkrete Ausbaustufe von UI2-003, aus organisatorischen Gründen als eigene Kachel geführt (klar abhakbar, statt in UI2-003 zu verschwimmen). - **Benutzerwert:** Bessere Screenreader-/Assistive-Tech-Unterstützung, klarere Fehlererkennung bei schlechtem Licht/Handschuhen (Fehlerfarbe + Text statt nur Farbe). - **Abhängigkeiten:** UI2-003 - **Backend:** keins - **Frontend:** `components/ui/form-field.tsx` - **Rechte:** keine Änderung - **Akzeptanzkriterien:** Fehlerfeld hat `aria-invalid="true"` und `aria-describedby` auf die Fehlermeldung, kein Verlust bestehender Funktionalität. - **Tests:** keine neuen (reines Markup/Attribut). - **DoD:** offen. ## UI2-004 — Skeleton-Loading für Dashboard-Kacheln - **Ziel:** Skeleton-Platzhalter statt Spinner/nichts beim Nachladen von Dashboard-Kacheln. - **Beschreibung:** Einfache `animate-pulse`-Komponente (`components/ui/skeleton.tsx`), in Dashboard-Tiles während Ladezustand eingesetzt. - **Benutzerwert:** Wahrgenommene Ladezeit sinkt, weniger Layout-Sprung. - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** neue `components/ui/skeleton.tsx`, Dashboard-Tiles (`*Tile.tsx`) - **Rechte:** keine Änderung - **Akzeptanzkriterien:** sichtbarer Skeleton-Zustand vor Dateneintreffen, kein Layout-Sprung beim Einblenden der echten Daten. - **Tests:** keine neuen. - **DoD:** offen. ## UI2-005 — Scrollbarer Table-Wrapper für Materiallisten - **Ziel:** Materiallisten/Kontroll-Tabellen brechen auf schmalem Tablet-Viewport nicht das Seiten-Layout, sondern scrollen innerhalb eines eigenen Containers. - **Beschreibung:** Gemeinsamer Table-Wrapper (`overflow-x: auto`) statt Ad-hoc-Lösung je Seite, zuerst in `KontrollPage.tsx`-Listen angewendet. - **Benutzerwert:** Kein horizontales Seiten-Scrollen mehr auf kleinen Screens. - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** `KontrollPage.tsx` bzw. betroffene Listen-Komponenten - **Mobile:** Priorität — Tablet-Ziel - **Rechte:** keine Änderung - **Akzeptanzkriterien:** Tabelle scrollt intern, Seite selbst nie horizontal. - **Tests:** keine neuen. - **DoD:** offen. ## UI2-006 — Toast/Benachrichtigungskomponente - **Ziel:** Aktionsfeedback (gespeichert/Fehler/Sync-Status) ohne Modal-Unterbrechung. - **Beschreibung:** Leichtgewichtige Toast-Komponente (kein `sonner`-Paket-Zwang, Pattern nachbaubar: Portal + Auto-Dismiss-Timer + Stapel-Anzeige bei mehreren gleichzeitigen Meldungen). - **Benutzerwert:** Häufige kleine Aktionen (Kontrolle bestätigen, Position speichern) unterbrechen den Arbeitsfluss nicht mit einem Wegklick-Dialog. - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** neue `components/ui/toast.tsx`, zentrale Toast-Provider-Einbindung - **Mobile:** Dauer konfigurierbar halten (bei schlechtem Netz/langsamer Interaktion reicht kurze Anzeigedauer sonst nicht) - **Rechte:** keine Änderung - **Akzeptanzkriterien:** Toast erscheint bei Erfolg/Fehler, verschwindet automatisch, mehrere gleichzeitige Toasts stapeln statt überschreiben. - **Tests:** keine neuen (reines UI). - **DoD:** offen. ## UI2-007 — Dialog/AlertDialog-Baustein für Bestätigungen - **Ziel:** Einheitliche Bestätigungsdialoge (z.B. „Material löschen?") statt nativem `window.confirm()`. - **Beschreibung:** Radix-artiges Dialog-Pattern mit Fokus-Trap und Escape-zum-Schließen, große Touch-taugliche Buttons. - **Benutzerwert:** Konsistentes Aussehen statt Browser-natives, unstyliertes `confirm()`-Popup; Fokus-Trap verhindert versehentliches Wegtippen auf Tablet. - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** neue `components/ui/dialog.tsx`/`alert-dialog.tsx`, schrittweise bestehende `confirm()`-Aufrufe ersetzen - **Mobile:** Priorität — Fokus-Trap/Escape wichtig bei externer Tastatur an Tablets mit Kartenleser - **Rechte:** keine Änderung - **Akzeptanzkriterien:** mind. eine bestehende `confirm()`-Stelle ersetzt, Verhalten (Bestätigen/Abbrechen) unverändert. - **Tests:** bestehende Tests an der ersetzten Stelle bleiben grün. - **DoD:** offen. ## UI2-008 — Badge-Komponente für Status-Chips - **Ziel:** Bestandsstatus/Ablaufdatum-Kennzeichnung visuell einheitlich statt Ad-hoc-Farbklassen je Stelle. - **Beschreibung:** Kleine `Badge`-Komponente mit Varianten (ok/warnung/kritisch/ abgelaufen), nutzt UI2-001-Tokens. - **Benutzerwert:** Schneller visueller Überblick in Listen/Kacheln, geringer Aufwand. - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** neue `components/ui/badge.tsx`, Einsatz in Materiallisten/Dashboard - **Rechte:** keine Änderung - **Akzeptanzkriterien:** mind. eine Liste (z.B. Ablaufdatum-Übersicht) nutzt Badge statt Inline-Farbklassen. - **Tests:** keine neuen. - **DoD:** offen. ## UI2-010 — Dark-Mode-fähige Token-Struktur (Vorbereitung, kein Umschalter) - **Ziel:** UI2-001-Tokens so anlegen, dass ein späterer Dark-Mode-Umschalter keinen Umbau der Token-Struktur erfordert — auch wenn der Umschalter selbst kein aktueller Bedarf ist (Tablet im Feld, meist Tageslicht). - **Beschreibung:** Je Token aus UI2-001 (`--color-card`, `--color-popover`, etc.) zusätzlich einen `.dark`/`[data-theme=dark]`-Override-Block in `tokens.css` vorsehen, auch wenn er anfangs mit denselben Werten wie Light gefüllt ist. - **Benutzerwert:** Kein nachträglicher Breaking-Umbau, falls Dark Mode später doch gebraucht wird (z.B. Nachteinsätze). - **Abhängigkeiten:** UI2-001 - **Backend:** keins - **Frontend:** `styles/global/tokens.css` - **Rechte:** keine Änderung - **Akzeptanzkriterien:** jeder neue UI2-001-Token hat einen Dark-Override-Platzhalter, keine funktionale Änderung im Light-Modus. - **Tests:** keine neuen (reines CSS). - **DoD:** offen. **Achtung MABEA-spezifisch:** Cascade-Layer-Struktur beachten (`global-css`-Layer niedriger als Tailwind-Layer, siehe CLAUDE.md „Wichtige Stolperfallen") — Dark-Override darf keine Layer-Kollision mit Tailwinds `@theme` erzeugen, insbesondere keinen Tailwind-Token-Namen doppelt vergeben. --- **Reihenfolge (empfohlen, nicht blockierend innerhalb der Gruppen):** UI2-001 zuerst (Basis für alle). Danach zwei unabhängige Gruppen: UI2-002/003+009/010 (Struktur/ Formulare/Tokens) und UI2-004/005/006/007/008 (einzelne UI-Bausteine) — Reihenfolge innerhalb der Gruppen nach Nutzerpriorität. **Nicht-Ziele:** kein Wechsel auf react-hook-form/zod/Radix, kein kompletter Frontend-Neubau, keine Breaking Changes an bestehender Fachlogik/API. Bewusst NICHT übernommen (Overkill/Desktop-lastig für ein Fach-Tool, siehe vertiefte Analyse 2026-09-09): Command-Palette/Combobox, Navigation-Menu, Accordion/Collapsible, Avatar, Pagination, Tooltip (auf Touch unzuverlässig), Sidebar-Zusatzfeatures wie Cookie-Persistenz/Keyboard-Shortcuts. ## Referenzen Subagenten-Analyse `ai-coding-starter-kit-v2`, Chat 2026-09-08 (kein Frontend-Neubau, Patterns schrittweise als Kacheln übernehmen). Vertiefte Analyse derselben Quelle 2026-09-09 (vollständige Komponentenliste, a11y-Patterns, Dark-Mode-Struktur) ergab UI2-006..010.