Umbenennung presseportale → pressekonto in Domains, Themes und Dokumentation. Design-Tokens, Portal-Shell, Customer-Dashboard, Auth- und Admin-PM-Views. Artisan-Befehl migrate:legacy-media mit Tests und Hub-Flux-Entwicklungsdocs. Co-authored-by: Cursor <cursoragent@cursor.com>
7.5 KiB
Phase 2 — Customer-Dashboard auf Mockup-Stil
Detail-Plan analog zu
01-PHASE-0-TOKENS.mdund02-PHASE-1-PORTAL-SHELL.md. Wird beim Abschluss auf Status✅ abgeschlossengesetzt; Lessons learned wandern inPROGRESS.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 | <flux:card> mit <flux:heading> „Willkommen“ |
Hub-Badge + Eyebrow + großes H1 + Untertitel + rechts Status-Pille |
| KPI-Reihe | 4 schmale <flux:card> mit <flux:text>-Zahl |
4 stat-cards mit Strip links, Mono-Zahl groß, Sub-Info, Sparkline |
| Pressemitteilungen-Block | <flux:card> mit Liste / Empty-State |
panel mit section-eyebrow, Empty-State mit Schritt-Karten 01/02/03 |
| Datenqualität | Grid aus <flux:badge>-Karten |
panel rechts mit 2 hint-cards (Progress-Bar + Action-Link) |
| Firmen-Slot | <flux:card> 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 | draftqualityHints[]recent(PressRelease-Collection, max. 5)companies
Mockup verlangt zusätzlich:
stats.deltaMonth— Veränderung ggü. Vormonat (Total)profileCompleteness— Prozentwert für Profil-Progress-BarbillingCompleteness— Prozentwert für RechnungsadressebridgeStatus—['presseecho' => 'connected'|'pending', 'businessportal24' => …](vorerstconnectedfest 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(nachflux.css)resources/css/web/shared-styles.css(nachdesign-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
- Varianten:
.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
<x-portal.stat-card variant="primary|ok|warn|muted" label="Gesamt" :value="$stats['total']">
<x-slot:meta>2026</x-slot:meta> {{-- rechts oben --}}
<x-slot:trend>0 ggü. Vormonat</x-slot:trend> {{-- unten --}}
</x-portal.stat-card>
Render: <article class="stat-card is-{variant}"> + 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
<x-portal.hint-card :icon="$hint['icon']" :title="$hint['title']" :percent="60" :href="$hint['href']">
{{ $hint['description'] }}
<x-slot:action>Profil öffnen</x-slot:action>
</x-portal.hint-card>
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 <div class="space-y-8">-Container):
- Page-Header —
<header>mit Grid1fr auto:- Links: Hub-Badge
User Backend+ Eyebrow +<h1>Mein Dashboard</h1>- 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“
- Wenn
- Links: Hub-Badge
- KPI-Reihe — 4
<x-portal.stat-card>(Gesamt/Veröffentlicht/Prüfung/Entwürfe) - Zweispalten-Grid (
2fr 1fr):- Links:
<article class="panel">mit Pressemitteilungen — Liste oder Empty-State (3 Schritt-Karten) - Rechts:
<article class="panel">mit<x-portal.hint-card>s
- Links:
- Unteres Grid (
2fr 1fr):- Links:
<article class="panel">Firmen — Liste oder Empty-Slot-Karten - Rechts:
<article class="panel-dark">Brand-Bridge (inline)
- Links:
- Footer — kleine Link-Reihe in
text-ink-3
4. Volt with() ergänzen
stats.deltaMonthvia zweiter Query (Vormonats-Counts vs. Aktuell)profileCompletenessals simpler Heuristik-Wert (firstname/lastname/phone/etc.)billingCompletenessanalog (Vorhanden = 100, sonst 0; oder Ist-Felder/Soll-Felder)bridgeStatusvorerst 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
- Phase-2-Plan-Dokument geschrieben
shared/hub-components.cssexistiert, importiert in beiden Builds<x-portal.stat-card>und<x-portal.hint-card>rendern wie Mockup/admin/mezeigt das neue Dashboard ohne Console-Errors- Empty-State für Pressemitteilungen ist sichtbar, wenn keine vorhanden
- Quality-Hints rendern mit Progress-Bar
- Brand-Bridge-Dark-Card unten rechts zeigt presseecho + businessportal24
- Neuer Smoke-Test
tests/Feature/Customer/DashboardTest.phpmit 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. - Pint clean
PROGRESS.md-Eintrag
Risiken & Mitigation
- FluxUI-Klassen vs. Custom-CSS-Kollisionen — wir mischen
<flux:badge>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.