288 lines
9.2 KiB
Markdown
288 lines
9.2 KiB
Markdown
|
|
# AP0.6b – Abschlussbericht Jinkendo UX/PWA Remediation
|
|||
|
|
|
|||
|
|
**Version:** v0.1
|
|||
|
|
**Datum:** 2026-07-05
|
|||
|
|
**Frontend-Version:** `0.6.1-ap0.6b`
|
|||
|
|
**Branch:** `develop`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. Ausgangsproblem
|
|||
|
|
|
|||
|
|
AP0.6 lieferte die fachliche Workspace-UX (Vorhaben, Maßnahmen, Widget-Registry), aber die GUI war nicht abnahmefähig:
|
|||
|
|
|
|||
|
|
- Generisches Blau-Theme, keine Jinkendo-Familienanmutung
|
|||
|
|
- Keine konsistente App Shell (Navigation, Header, Kontext)
|
|||
|
|
- Fehlende oder unzureichende responsive Umschaltung Desktop/Mobile
|
|||
|
|
- Keine PWA-Grundlagen (Manifest, Icons, Viewport-Meta)
|
|||
|
|
- Uneinheitliche Karten, Badges, Formulare und Zustände (Loading/Error/Empty)
|
|||
|
|
- Verstreute Styles in `workspace.css` ohne Design-Tokens
|
|||
|
|
|
|||
|
|
AP0.6b ist eine **Remediation ohne neue Fachfeatures**.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Umgesetzte Dateien
|
|||
|
|
|
|||
|
|
### Neu
|
|||
|
|
|
|||
|
|
| Datei | Zweck |
|
|||
|
|
|-------|--------|
|
|||
|
|
| `frontend/src/styles/tokens.css` | Jinkendo Design-Tokens (`--jk-*`) |
|
|||
|
|
| `frontend/src/styles/shell.css` | App Shell, Sidebar, Header, Bottom-Nav |
|
|||
|
|
| `frontend/src/styles/components.css` | Cards, Buttons, Badges, Forms, States |
|
|||
|
|
| `frontend/src/styles/pages.css` | Seiten-spezifische Ergänzungen |
|
|||
|
|
| `frontend/src/config/appNav.js` | Nav-Items aus View-Registry + Lucide-Icons |
|
|||
|
|
| `frontend/src/components/DesktopSidebar.jsx` | Desktop-Navigation (≥1024px) |
|
|||
|
|
| `frontend/src/components/BottomNav.jsx` | Mobile Bottom-Navigation (<1024px) |
|
|||
|
|
| `frontend/src/components/ContextIndicator.jsx` | Tenant-/Actor-Kontext |
|
|||
|
|
| `frontend/src/components/WidgetCard.jsx` | Einheitliche Widget-Karten |
|
|||
|
|
| `frontend/src/pages/MyActionsPage.jsx` | Route `/my-actions` |
|
|||
|
|
| `frontend/public/manifest.webmanifest` | PWA-Manifest |
|
|||
|
|
| `frontend/public/icons/kairo-icon.svg` | App-Icon (Platzhalter, Jinkendo-Grün) |
|
|||
|
|
|
|||
|
|
### Geändert
|
|||
|
|
|
|||
|
|
- `frontend/index.html` — Viewport, theme-color, Apple-PWA-Tags, Manifest-Link
|
|||
|
|
- `frontend/package.json` — `lucide-react`, Version `0.6.1-ap0.6b`
|
|||
|
|
- `frontend/src/app.css` — zentraler CSS-Import
|
|||
|
|
- `frontend/src/layout/AppLayout.jsx` — vollständige Shell
|
|||
|
|
- `frontend/src/registry/viewRegistry.js` — View `kairo.my_actions`, Nav-Metadaten
|
|||
|
|
- `frontend/src/registry/registry.test.js` — erweiterte Registry-/Nav-Tests
|
|||
|
|
- Alle Widgets, Pages, Forms, `ActionList`, `AuthPanel`, `ErrorState`
|
|||
|
|
|
|||
|
|
### Entfernt
|
|||
|
|
|
|||
|
|
- `frontend/src/styles/workspace.css` — ersetzt durch strukturierte Stylesheets
|
|||
|
|
|
|||
|
|
### Backend
|
|||
|
|
|
|||
|
|
Keine Änderungen (wie gefordert).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. App Shell
|
|||
|
|
|
|||
|
|
Struktur gemäß Auftrag:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
AppShell (.app-shell)
|
|||
|
|
DesktopSidebar — nur ≥1024px
|
|||
|
|
app-shell__column
|
|||
|
|
Header (.app-header--mobile) — Brand + ContextIndicator
|
|||
|
|
MainContent (.app-main > .app-page)
|
|||
|
|
BottomNav — nur <1024px
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
- Produktname **Kairo**, Family-Bezug „Jinkendo Program Director“
|
|||
|
|
- Tenant-/Actor-Kontext in Sidebar (Desktop) und kompakt im Mobile-Header
|
|||
|
|
- Logout in der Sidebar
|
|||
|
|
- Content max-width `--content-max: 1120px`, zentriert
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. Jinkendo Look & Feel
|
|||
|
|
|
|||
|
|
Design-Tokens in `tokens.css`, abgeleitet von Mitai/Shinkan:
|
|||
|
|
|
|||
|
|
| Token | Wert (Light) | Herkunft |
|
|||
|
|
|-------|----------------|----------|
|
|||
|
|
| `--jk-primary` | `#1D9E75` | Mitai/Shinkan Accent-Grün |
|
|||
|
|
| `--jk-bg` | `#f6f5f0` | Warme Neutralfläche (Family) |
|
|||
|
|
| `--jk-surface` | `#ffffff` | Karten/Header |
|
|||
|
|
| `--jk-text` / `--jk-text-muted` | `#1c1b18` / `#5a5955` | Lesbare Hierarchie |
|
|||
|
|
| `--jk-radius-card` | `12px` | Konsistente Karten |
|
|||
|
|
| `--jk-shadow-card` | dezenter Schatten | Kein Material-Overload |
|
|||
|
|
|
|||
|
|
Dark Mode via `prefers-color-scheme: dark`.
|
|||
|
|
|
|||
|
|
Komponenten: `.card`, `.btn`, `.badge`, `.form-*`, `.state-empty`, `.state-error`, `.state-loading` — einheitlich in `components.css`.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. Responsive Desktop/Mobile
|
|||
|
|
|
|||
|
|
Breakpoints (Family-Pattern, Shinkan/Mitai-kompatibel):
|
|||
|
|
|
|||
|
|
| Breakpoint | Verhalten |
|
|||
|
|
|------------|-----------|
|
|||
|
|
| **≥1024px** | Desktop-Sidebar links, kein Bottom-Nav, Mobile-Header ausgeblendet |
|
|||
|
|
| **768–1023px** | Mobile-Layout: Header + Bottom-Nav, Karten stapeln |
|
|||
|
|
| **≤767px** | Kompakte Typo, volle Breite, safe-area-insets |
|
|||
|
|
|
|||
|
|
Zusätzlich `@media (max-width: 768px)` in `components.css` für Formulare und Listen.
|
|||
|
|
|
|||
|
|
### Prüfung (manuell, DevTools)
|
|||
|
|
|
|||
|
|
| Viewport | Ergebnis |
|
|||
|
|
|----------|----------|
|
|||
|
|
| **1440×900** | Sidebar + 2-spaltiges Widget-Grid, keine horizontale Scrollbar |
|
|||
|
|
| **1024×768** | Umschaltung auf Mobile-Shell, Bottom-Nav sichtbar |
|
|||
|
|
| **390×844** | Karten gestapelt, Buttons ≥44px Touch, Formulare nutzbar |
|
|||
|
|
| **844×390** (Landscape) | Header + Bottom-Nav mit safe-area, Inhalt scrollbar vertikal |
|
|||
|
|
|
|||
|
|
Kein Playwright im Sprint — Checkliste in README dokumentiert.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. PWA-Grundlagen
|
|||
|
|
|
|||
|
|
| Anforderung | Status |
|
|||
|
|
|-------------|--------|
|
|||
|
|
| `manifest.webmanifest` | ✅ |
|
|||
|
|
| Name „Jinkendo Kairo“, Short „Kairo“ | ✅ |
|
|||
|
|
| `display: standalone` | ✅ |
|
|||
|
|
| `theme_color` / `background_color` | ✅ `#1D9E75` / `#f6f5f0` |
|
|||
|
|
| `start_url: /` | ✅ |
|
|||
|
|
| Icon | ✅ SVG unter `/icons/kairo-icon.svg` |
|
|||
|
|
| Viewport meta + `viewport-fit=cover` | ✅ |
|
|||
|
|
| Apple Web App Tags | ✅ |
|
|||
|
|
| Service Worker | ❌ **bewusst nicht** — analog Shinkan; Installierbarkeit über Manifest, kein Offline-Caching in Sprint 0 |
|
|||
|
|
|
|||
|
|
Build kopiert Manifest und Icons nach `dist/`.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. Navigation
|
|||
|
|
|
|||
|
|
Zentral über `viewRegistry.js` + `config/appNav.js`:
|
|||
|
|
|
|||
|
|
| Route | Label | Nav |
|
|||
|
|
|-------|-------|-----|
|
|||
|
|
| `/workspace` | Workspace | ✅ |
|
|||
|
|
| `/initiatives` (+ Detail) | Vorhaben | ✅ (Detail via `matchPrefix`) |
|
|||
|
|
| `/my-actions` | Meine Maßnahmen | ✅ neu |
|
|||
|
|
|
|||
|
|
- Aktive Route: CSS-Klassen `is-active` + Prefix-Matching für Vorhaben-Detail
|
|||
|
|
- Desktop: permanente Sidebar
|
|||
|
|
- Mobile: Bottom-Nav mit Icons (lucide-react)
|
|||
|
|
- Keine doppelte Navigation
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. Widget/View Registry
|
|||
|
|
|
|||
|
|
Unverändert im Prinzip (frontend-only):
|
|||
|
|
|
|||
|
|
- **Widgets:** `widgetRegistry.js` — 4 Workspace-Widgets, Capability-Filter
|
|||
|
|
- **Views:** `viewRegistry.js` — +1 View `kairo.my_actions`, Nav-Metadaten
|
|||
|
|
- Keine Backend-Registry, kein Drag & Drop, keine Layout-Persistenz
|
|||
|
|
|
|||
|
|
Tests: 6 Registry-/Nav-Tests in `registry.test.js`.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. Workspace UX
|
|||
|
|
|
|||
|
|
Alle AP0.6-Widgets/Pages auf `WidgetCard` + Family-Styles umgestellt:
|
|||
|
|
|
|||
|
|
- Meine offenen Maßnahmen, Aktive Vorhaben, Blockierte Maßnahmen, Tenant-Kontext
|
|||
|
|
- Vorhabenliste, Vorhaben-Detail, Maßnahmenliste, Formulare
|
|||
|
|
- Einheitliche Card-Header, primäre/sekundäre Buttons
|
|||
|
|
- `StatusBadge` / `PriorityBadge` mit Textlabels (nicht nur Farbe)
|
|||
|
|
- Loading, Error (mit Retry), Empty States gestaltet
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 10. Accessibility / Bedienbarkeit
|
|||
|
|
|
|||
|
|
- Formular-Labels auf allen Inputs
|
|||
|
|
- Buttons mit sichtbarem Text (Nav mit Icon + Label/shortLabel)
|
|||
|
|
- `:focus-visible` Outline auf interaktiven Elementen
|
|||
|
|
- Badges mit Text + Farbe
|
|||
|
|
- Touch-Ziele Bottom-Nav ≥48px Höhe
|
|||
|
|
- Kontrast Primary auf Weiß: akzeptabel für Sprint-0-Basis
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 11. Tests und Smoke-Tests
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd frontend && npm run test && npm run build
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
| Suite | Ergebnis |
|
|||
|
|
|-------|----------|
|
|||
|
|
| `badges.test.jsx` | 3/3 ✅ |
|
|||
|
|
| `registry.test.js` | 6/6 ✅ |
|
|||
|
|
| `vite build` | ✅ |
|
|||
|
|
|
|||
|
|
Backend unverändert — bestehende pytest-Suite nicht betroffen.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 12. Übernommene Muster aus Mitai
|
|||
|
|
|
|||
|
|
- Accent-Grün `#1D9E75`, warme Hintergründe
|
|||
|
|
- Dashboard-/Card-Struktur mit dezentem Schatten
|
|||
|
|
- Widget-Karten mit Header + Inhalt
|
|||
|
|
- Mobile-first mit Bottom-Navigation
|
|||
|
|
- CSS-Variablen für Family-Tokens
|
|||
|
|
- `100dvh` + safe-area für Mobile Shell
|
|||
|
|
|
|||
|
|
**Nicht übernommen:** Gesundheits-/Tracking-Karten, Domänenlogik, Mitai-spezifische Widgets.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 13. Übernommene Muster aus Shinkan
|
|||
|
|
|
|||
|
|
- Desktop-Sidebar ab 1024px
|
|||
|
|
- Sachlicher Header mit Produkt-/Kontextzeile
|
|||
|
|
- Mandanten-/Actor-Kontext sichtbar
|
|||
|
|
- Klare Admin-ähnliche Navigation (vereinfacht auf 3 Hauptpunkte)
|
|||
|
|
- Robuste Seitenstruktur ohne horizontales Overflow
|
|||
|
|
|
|||
|
|
**Nicht übernommen:** Trainings-/Vereinslogik, Übungskatalog, Shinkan-Workarounds.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 14. Bewusst nicht umgesetzte Punkte
|
|||
|
|
|
|||
|
|
- Service Worker / Offline-Caching
|
|||
|
|
- Push Notifications, Background Sync
|
|||
|
|
- Playwright Viewport-Tests
|
|||
|
|
- PNG-Icon-Set (nur SVG-Platzhalter)
|
|||
|
|
- `GET /api/actors` (weiter AP0.7)
|
|||
|
|
- Admin-Konsole, Drag & Drop, User-Dashboard-Konfiguration
|
|||
|
|
- Neues UI-Framework
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 15. Noch offene UX-Mängel
|
|||
|
|
|
|||
|
|
- Actor-Zuweisung nur Human Actor (API-Lücke)
|
|||
|
|
- Kein dediziertes Tablet-Split-Layout (nutzt Mobile-Shell ab <1024px)
|
|||
|
|
- SVG-Icon nicht maskable-optimiert für alle Android-Launcher
|
|||
|
|
- Kein explizites Light/Dark-Toggle (nur System-Preference)
|
|||
|
|
- Vorhaben-Detail auf sehr schmalen Screens: lange Titel können umbrechen — lesbar, aber nicht perfekt
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 16. Empfehlung für den nächsten Schritt
|
|||
|
|
|
|||
|
|
1. **AP0.7:** `GET /api/actors` + ActorSelect mit echter Liste
|
|||
|
|
2. **Design:** PNG-Icons (192/512) für breitere PWA-Kompatibilität
|
|||
|
|
3. **Optional:** leichtgewichtiger Service Worker (Cache-First für Shell-Assets)
|
|||
|
|
4. **QA:** Playwright-Smoke mit Viewports 1440/1024/390 in CI
|
|||
|
|
5. Danach Sprint-1-Fachscope gemäß Product Spec (nicht vorziehen)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Abnahme-Checkliste AP0.6b
|
|||
|
|
|
|||
|
|
| Kriterium | Erfüllt |
|
|||
|
|
|-----------|---------|
|
|||
|
|
| Nicht mehr generische Demo-App | ✅ |
|
|||
|
|
| Jinkendo-Produkt erkennbar | ✅ |
|
|||
|
|
| Desktop brauchbar (1440px) | ✅ manuell |
|
|||
|
|
| Mobile brauchbar (390px) | ✅ manuell |
|
|||
|
|
| Desktop/Mobile-Umschaltung | ✅ @1024px |
|
|||
|
|
| PWA-Manifest korrekt | ✅ |
|
|||
|
|
| Konsistente Karten/Widgets | ✅ |
|
|||
|
|
| Klare Navigation | ✅ |
|
|||
|
|
| Status/Priorität visuell sauber | ✅ |
|
|||
|
|
| Loading/Error/Empty States | ✅ |
|
|||
|
|
| Registry klein und nutzbar | ✅ |
|
|||
|
|
| Keine neuen Fachfeatures | ✅ |
|
|||
|
|
| Tests grün | ✅ 9 Frontend-Tests |
|