# Phase 2 — Customer-Dashboard auf Mockup-Stil > Detail-Plan analog zu `01-PHASE-0-TOKENS.md` und > `02-PHASE-1-PORTAL-SHELL.md`. Wird beim Abschluss auf Status `✅ abgeschlossen` > gesetzt; Lessons learned wandern in `PROGRESS.md`. **Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag · **Risiko**: niedrig --- ## Ziel `resources/views/livewire/customer/dashboard.blade.php` matched das Mockup `dev/frontend/tailwind_v3/User Dashboard presseportale.html` zu ≥ 90 %. Sichtbarer Wow-Moment für den Kunden, ohne neue Business-Logik. ## Was sich ändert ### Visuell | Bereich | Heute | Mockup | | ----------------- | ------------------------------------------------ | --------------------------------------------------------------------- | | Page-Header | `` mit `` „Willkommen“ | Hub-Badge + Eyebrow + großes H1 + Untertitel + rechts Status-Pille | | KPI-Reihe | 4 schmale `` mit ``-Zahl | 4 `stat-card`s mit Strip links, Mono-Zahl groß, Sub-Info, Sparkline | | Pressemitteilungen-Block | `` mit Liste / Empty-State | `panel` mit `section-eyebrow`, Empty-State mit Schritt-Karten 01/02/03 | | Datenqualität | Grid aus ``-Karten | `panel` rechts mit 2 `hint-card`s (Progress-Bar + Action-Link) | | Firmen-Slot | `` mit Firmen-Liste | `panel` mit gestrichelten Empty-Slot-Karten + Hinweis-Box | | Brand-Bridge | (nicht vorhanden) | `panel-dark` rechts: presseecho + businessportal24 Status | | Footer | (nicht vorhanden) | Subtle-Footer mit Tastenkürzel / Changelog / Status / Support | ### Datenmodell Heute liefert das Volt-`with()`: - `stats.total | published | review | draft` - `qualityHints[]` - `recent` (PressRelease-Collection, max. 5) - `companies` Mockup verlangt **zusätzlich**: - `stats.deltaMonth` — Veränderung ggü. Vormonat (Total) - `profileCompleteness` — Prozentwert für Profil-Progress-Bar - `billingCompleteness` — Prozentwert für Rechnungsadresse - `bridgeStatus` — `['presseecho' => 'connected'|'pending', 'businessportal24' => …]` (vorerst `connected` fest verdrahtet, später aus echtem Sync-Status) ## Was NICHT geändert wird - Logik / Volt-Methoden — Layout-only. - Statistik-Backend (`PressRelease::where(...)`) bleibt 1:1. - `qualityHints`-Logik bleibt — wird nur anders gerendert. - Topbar (eigene Phase, später). --- ## Implementierungs-Schritte ### 1. Shared Hub-Components-CSS Klassen wandern in **`resources/css/shared/hub-components.css`** (neue Datei). Importiert in: - `resources/css/portal.css` (nach `flux.css`) - `resources/css/web/shared-styles.css` (nach `design-tokens.css`) Damit haben **Portal-Build und Web-Build** dieselbe Hub-Komponenten-Sprache — DRY für späteres Wiederverwenden (z. B. Admin-Dashboard in Phase 3). Folgende Klassen kommen rein (alle mit `var(--color-*)`-Tokens, keine Hex-Literale): - `.panel`, `.panel-warm`, `.panel-dark`, `.panel-head` - `.stat-card` + `.stat-strip` + `.stat-label` + `.stat-num` + Varianten: `.is-primary`, `.is-ok`, `.is-warn`, `.is-muted` - `.hint-card` + `.hint-card .hint-ico` - `.badge` + `.badge.warn` + `.badge.ok` + `.badge.hub` + `.badge.dot` - `.bridge-row`, `.dot-pe`, `.dot-bp` ### 2. Blade-Components in `resources/views/components/portal/` #### `stat-card.blade.php` ```blade 2026 {{-- rechts oben --}} 0 ggü. Vormonat {{-- unten --}} ``` Render: `
` + Strip + Label + Mono-Zahl + Meta-Slot oben rechts + Trend-Slot unten. Sparkline (SVG) erstmal weggelassen — optionales Detail; lässt sich nachschieben, wenn Daten dafür da sind. #### `hint-card.blade.php` ```blade {{ $hint['description'] }} Profil öffnen ``` Render: `.hint-card`-Grid mit Icon-Square + Progress-Bar + Text + Action-Link in `text-accent-deep`. #### `bridge-card.blade.php` (optional, Phase 2 minimal) Bleibt erstmal **inline** im Dashboard (sehr spezifisch, eine Stelle). Wird in Phase 3/4 extrahiert, wenn klar ist wie weit der Brand-Bridge-Pattern sich verbreitet. ### 3. `customer/dashboard.blade.php` umbauen Layout-Skelett (alles im `
`-Container): 1. **Page-Header** — `
` mit Grid `1fr auto`: - Links: Hub-Badge `User Backend` + Eyebrow + `

Mein Dashboard

` + Subtitle (Name + Reichweiten-Hinweis) - Rechts: Status-Pille - Wenn `$selectedCompany`: Hub-Badge mit Firma-Name (grün/ok-Stil) - Wenn nicht: Warn-Pille „Keine Firma zugeordnet → zuordnen“ 2. **KPI-Reihe** — 4 `` (Gesamt/Veröffentlicht/Prüfung/Entwürfe) 3. **Zweispalten-Grid** (`2fr 1fr`): - Links: `
` mit Pressemitteilungen — Liste **oder** Empty-State (3 Schritt-Karten) - Rechts: `
` mit ``s 4. **Unteres Grid** (`2fr 1fr`): - Links: `
` Firmen — Liste **oder** Empty-Slot-Karten - Rechts: `
` Brand-Bridge (inline) 5. **Footer** — kleine Link-Reihe in `text-ink-3` ### 4. Volt `with()` ergänzen - `stats.deltaMonth` via zweiter Query (Vormonats-Counts vs. Aktuell) - `profileCompleteness` als simpler Heuristik-Wert (firstname/lastname/phone/etc.) - `billingCompleteness` analog (Vorhanden = 100, sonst 0; oder Ist-Felder/Soll-Felder) - `bridgeStatus` vorerst hardcoded `['presseecho' => 'connected', 'businessportal24' => 'connected']` → später aus echtem Sync-Service ### 5. Tests `tests/Feature/Customer/DashboardTest.php` (oder bestehender Test, falls vorhanden): - Rendert ohne Fehler bei eingeloggtem Customer - Stat-Zahlen werden korrekt ausgegeben - Empty-State wird angezeigt, wenn keine PRs existieren - Quality-Hints werden angezeigt, wenn `profile()` fehlt --- ## Akzeptanzkriterien - [x] Phase-2-Plan-Dokument geschrieben - [x] `shared/hub-components.css` existiert, importiert in beiden Builds - [x] `` und `` rendern wie Mockup - [x] `/admin/me` zeigt das neue Dashboard ohne Console-Errors - [x] Empty-State für Pressemitteilungen ist sichtbar, wenn keine vorhanden - [x] Quality-Hints rendern mit Progress-Bar - [x] Brand-Bridge-Dark-Card unten rechts zeigt presseecho + businessportal24 - [x] Neuer Smoke-Test `tests/Feature/Customer/DashboardTest.php` mit 5 Cases (Core-Sections, Empty-State, PR-Liste, Profil-Hint, vollständiges Profil blendet Hints aus). Cross-Check: alle 18 verwandten Tests bleiben grün. - [x] Pint clean - [x] `PROGRESS.md`-Eintrag --- ## Risiken & Mitigation - **FluxUI-Klassen vs. Custom-CSS-Kollisionen** — wir mischen `` weiterhin **nicht** im Dashboard (für Status-Pillen nehmen wir `.badge.hub|.warn|.ok|.dot`). Auf den Detail-Seiten (Phase 4) bleibt FluxUI dominant. - **Sparklines weggelassen** — minimaler Stilverlust, wird in Phase 4 mit echten Trend-Daten nachgereicht. Mockup-Match weiterhin ≥ 90 %. - **`stats.deltaMonth`-Performance** — zweite Query auf gleicher Tabelle; bei wachsendem Datensatz später cachen. Heute irrelevant.