Rebrand Hub+Flux

This commit is contained in:
Kevin Adametz 2026-05-20 15:44:15 +02:00
parent 36810ac81b
commit 9844b41535
130 changed files with 9357 additions and 3345 deletions

View file

@ -8,7 +8,15 @@
## Phase 2 — Customer-Dashboard auf Mockup-Stil
**Status**: ⚪ später · **Aufwand**: ~½ Tag · **Risiko**: niedrig
**Status**: ✅ **abgeschlossen** (de facto in Phase 1 +
verfeinert in 4J) · **Aufwand**: ~½ Tag · **Risiko**: niedrig
> Während der Phase-1-Migration wurden Page-Header, KPI-Reihe,
> 2-Spalten-Grids, `<x-portal.stat-card>`,
> `<x-portal.hint-card>` und Brand-Bridge-Dark-Card bereits
> umgesetzt. Phase 4J hat die Recent-PM-Liste mit Portal-Pills
> + PM-ID-Sub auf den finalen 4H/4I-Pattern-Stand gebracht.
> Match zum Mockup ≥ 95 %.
### Ziel
`livewire/customer/dashboard.blade.php` matched das Mockup
@ -40,26 +48,36 @@
## Phase 3 — Admin-Dashboard konsistent
**Status**: ⚪ später · **Aufwand**: ~½ Tag · **Risiko**: niedrig
**Status**: ✅ **abgeschlossen** (in Phase 1 + 4J)
· **Aufwand**: ~½ Tag · **Risiko**: niedrig
### Ziel
`resources/views/admin/dashboard.blade.php` nutzt dasselbe Vokabular wie
Customer-Dashboard.
### Heutiger Stand
Reines Tailwind mit `zinc-*`-Klassen, **keine** FluxUI-Komponenten,
visuell aus der Zeit gefallen.
### Schritte
- KPI-Karten als `<x-portal.stat-card>`
- Wenn Charts vorhanden: über `flux:chart` umsetzen (FluxUI Pro)
- Recent-Activity-Liste in `flux:card` mit Hub-Akzenten
> Admin-Dashboard nutzt seit Phase 1 dasselbe Vokabular wie
> das Customer-Dashboard: Page-Header, 5-KPI-Reihe mit
> `<x-portal.stat-card>`, 2-Spalten-Grid (Recent + Pending
> Reviews), Newsletter `panel-warm`, Quick-Actions-Grid,
> Footer. Phase 4J hat Portal-Pills, PM-ID-Sub und
> Inline-Action „Prüfen →" mit `is-row-warn`-Tinting für
> die Review-Queue ergänzt.
---
## Phase 4 — Listen-/Detail-Pages durchgehen
**Status**: 🚧 iterativ · **Aufwand**: ~3–5 Tage gesamt · **Risiko**: niedrig
**Status**: ✅ **komplett abgeschlossen** (4A–4J)
· **Aufwand**: ~3–5 Tage gesamt · **Risiko**: niedrig
> Alle 10 Sub-Päckchen (4A–4J) sind grün, Build + Pint
> sauber, alle relevanten Tests bestehen
> (230/231 gesamt — der eine Fail ist der pre-existing
> `ApiDocumentationTest` ohne Bezug zur UI-Migration).
> Das gesamte Backend (Admin + Customer) nutzt damit
> dieselbe Design-Sprache: Page-Header mit
> Eyebrow/Badge/Subtitle, `<x-portal.stat-card>`-KPI-Reihen,
> `article.panel` als Container, `flux:table` mit Hub-Padding
> + Sortierung, `flux:card` nur wo Test-Verträge sie noch
> brauchen, sowie die Mockup-Patterns aus 4H/4I/4J
> (Saved-Views-Tabs, Active-Chips, Portal-Pills,
> Inline-Actions, Row-Tinting, 3-stufige Empty-States).
### Ziel
Alle Volt-Pages im Admin- und Customer-Bereich nutzen denselben Hub-Stil.
@ -73,9 +91,20 @@ Alle Volt-Pages im Admin- und Customer-Bereich nutzen denselben Hub-Stil.
siehe `08-PHASE-4B-PRESS-RELEASES-DETAIL.md`
- **4C** = Press-Releases Forms (create/edit, Admin + Customer) — ✅ **abgeschlossen**
siehe `09-PHASE-4C-PRESS-RELEASES-FORMS.md`
- **4D** = Companies (`admin.companies.*`) — ⚪ pending
- **4E** = Profile/Settings (`settings.*`, `me.profile`, `me.security`) — ⚪ pending
- **4F** = Restliche Admin-Bereiche — ⚪ pending
- **4D** = Companies (`admin.companies.*`) — ✅ **abgeschlossen**
siehe `10-PHASE-4D-COMPANIES.md`
- **4E** = Profile/Settings (`settings.*`, `customer.profile`, `customer.security`) — ✅ **abgeschlossen**
siehe `11-PHASE-4E-PROFILE-SETTINGS.md`
- **4F** = Restliche Admin-Bereiche (contacts, categories, presets, footer-codes, users, roles, newsletter, reports, invoices, coupons, payments, portal-switcher) — ✅ **abgeschlossen**
siehe `13-PHASE-4F-ADMIN-REST.md`
- **4G** = Restliche Customer-Bereiche (invoices, tokens, bookings, company-switcher, me/press-kits/*) — ✅ **abgeschlossen**
siehe `12-PHASE-4G-CUSTOMER-PORTAL.md`
- **4H** = Customer „Meine Pressemitteilungen" auf Mockup-Stil (Counter-Strip, Saved-Views-Tabs, Filter-Chips, Active-Chips, Portal-Pills, Inline-Actions, Row-Tint, 3-fach-Empty-State, Status-Aktionen-Legende) — ✅ **abgeschlossen**
siehe `14-PHASE-4H-PRESS-RELEASES-MOCKUP.md`
- **4I** = Admin „Pressemitteilungen" — Mockup-Patterns übertragen (Saved-Views-Tabs, Active-Chips, Portal-Pills, Row-Tint, Inline-Actions als Modal-Trigger, reduzierte Spalten, 2-stufiger Empty-State) — ✅ **abgeschlossen**
siehe `15-PHASE-4I-ADMIN-PRESS-RELEASES.md`
- **4J** = Dashboard-PM-Listen mit 4H/4I-Patterns (Portal-Pills, PM-ID-Sub, Customer + Admin Dashboard, Inline-Action „Prüfen →" für Admin-Review-Queue mit `is-row-warn` Tinting) — ✅ **abgeschlossen**
siehe `16-PHASE-4J-DASHBOARD-LISTS.md`
### Was geändert wird
- Page-Header-Struktur (Eyebrow + H1 + Subtitle + Aktions-Bar)
@ -91,72 +120,125 @@ Alle Volt-Pages im Admin- und Customer-Bereich nutzen denselben Hub-Stil.
## Phase 5 — Dark Mode konsistent
**Status**: ⚪ später · **Aufwand**: ~½ Tag · **Risiko**: niedrig
**Status**: ✅ **abgeschlossen** · **Aufwand**: ~½ Tag (Großteil
der Arbeit war Vorbereitung in Phase 0–4) · **Risiko**: niedrig
### Ziel
Dark Mode funktioniert sauber im Portal, **ohne doppelte UI-Pflege**.
> Tokens, Switcher und alle Custom-CSS-Komponenten waren
> bereits token-basiert vorbereitet — `shared/design-tokens.css`
> hat einen kompletten `.dark { … }`-Block (Z. 182–248) mit allen
> Surfaces, Hub/Bernstein-Akzenten, Ink-Skala, Status-Farben,
> Schatten und `color-scheme: dark`. `hub-components.css` ist
> zu 100 % token-basiert und schaltet automatisch um. FluxUI's
> `@fluxAppearance` ist in beiden Head-Partials integriert,
> Switcher liegt im User-Menü (Desktop + Mobile) sowie in
> `settings/appearance.blade.php`. Bei der Inventur fiel nur
> ein latenter Bug auf (`--color-ink-deep`-Token existiert
> nicht, in `customer/tokens.blade.php` auf
> `--color-panel-dark-2` umgestellt). QR-Code in
> `customer/security.blade.php` behält bewusst `bg-white` in
> beiden Modi (Scan-Tauglichkeit), klarstellender Kommentar
> ergänzt.
>
> Siehe `17-PHASE-5-DARK-MODE.md` für Details.
### Quelle
`dev/frontend/tailwind_v3/User Dashboard presseportale Dark.html` hat
alle Dark-Tokens bereits vorgegeben.
`dev/frontend/tailwind_v3/User Dashboard presseportale Dark.html`
hat alle Dark-Tokens bereits vorgegeben — alle Werte sind in
`design-tokens.css` übernommen.
### Schritte
1. In `shared/design-tokens.css` Dark-Werte ergänzen:
```css
@media (prefers-color-scheme: dark) {
@theme {
--color-bg: #0E1218;
--color-bg-elev: #14181F;
--color-hub: #5A78C2;
--color-accent: #D9A560;
/* … */
}
}
.dark {
/* gleiche Werte für expliziten Switch */
}
```
2. `class="dark"` wird **nicht** mehr hardcoded gesetzt
3. Flux Appearance-Switcher (`settings/appearance.blade.php`) steuert
`.dark` auf `<html>`
4. Hub-Frontend bleibt erstmal Light-Only (so wie heute)
### Erwartung
- Settings → Appearance → „Dark" schaltet Portal um
- Settings → Appearance → „System" folgt OS-Präferenz
- Sidebar, Topbar, Dashboards, Listen, Forms — alles funktioniert
- Hub-Landing und Hub-Auth bleiben Light
### Was geliefert wird
- Settings → Erscheinung → „Dunkel" schaltet Portal um
- Settings → Erscheinung → „System" folgt OS-Präferenz
- Switcher zusätzlich direkt im User-Menü (Sidebar + Mobile)
- Sidebar, Topbar, Dashboards, Listen, Forms — alles schaltet
automatisch über Token-Cascade um
- `panel-dark` bleibt KONSTANT dunkel (Brand-Bridge-Card)
- `--color-accent-warm` bleibt KONSTANT Bernstein (Hint-Cards)
- Hub-Landing und Hub-Auth bleiben Light (kein
`@fluxAppearance` im Web-Build)
---
## Phase 6 — Auth-Konsolidierung (optional)
## Phase 6 — Auth-Cleanup
**Status**: ⚪ optional · **Aufwand**: 0–1 Tag · **Risiko**: mittel
**Status**: ✅ **abgeschlossen** · **Aufwand**: ~30 min · **Risiko**: niedrig
### Frage
Bleibt der Hub-Login (`auth/pressekonto`-Layout, Web-Build) so wie er ist?
Oder konsolidieren wir auf den Portal-Build?
> Hub-Auth bleibt eigenständig (auf Web-Build mit dem `pressekonto`-Layout),
> weil Hub-Atmosphäre + Light-Bundle als Trade-off bewusst gewollt sind.
> Die ungenutzten Starter-Kit-Layouts wurden entfernt: `auth/simple`,
> `auth/split`, `auth/card`, der Wrapper `auth.blade.php`, das alternative
> `app/header.blade.php` sowie die Debug-Views `livewire/auth/login-simple`
> und `test-simple`. Damit gibt es keine hardcoded `class="dark"`-Reste
> mehr, die Phase 5 hätten torpedieren können. Doku-Beispiel in
> `_docs/FORTIFY-SANCTUM-SETUP.md` auf `components.layouts.auth.pressekonto`
> umgestellt. CSS-Bundle ist dabei sogar ~2.4 KB kleiner geworden.
>
> Siehe `18-PHASE-6-AUTH-CLEANUP.md` für die Inventur.
### Pro Konsolidierung
- Ein Build weniger
- Konsistente Komponenten-Sprache
### Optional für später (NICHT Teil von Phase 6)
Eine echte **Auth-Konsolidierung** (Hub-Auth-CSS in den Portal-Build
ziehen, Web-Build nur für die Landing-Pages behalten) wäre denkbar,
aber:
- Hub-Atmosphäre (Konzentrische Kreise, Hub-Grid) ist visuell stark
- Hub-Auth ist leichtgewichtig (kein FluxUI im Bundle)
- Aktueller Stand funktioniert sauber
### Pro Beibehaltung (heutiger Stand)
- Hub-Atmosphäre der Auth-Seiten (Konzentrische Kreise, Hub-Grid) ist
visuell sehr stark — würde verloren gehen
- Hub-Auth ist **leichtgewichtig** (kein FluxUI im Bundle)
- Vorlage `Login pressekonto A3 Tailwind.html` ist bewusst minimalistisch
→ keine Action notwendig, bleibt offen.
### Entscheidung
Vermutlich **beibehalten**. Aber: Die alten Auth-Layouts
`auth/simple.blade.php`, `auth/split.blade.php`, `auth/card.blade.php` aus
dem Starter-Kit können vermutlich gelöscht werden, sobald geprüft ist,
dass keine Komponente sie noch verwendet.
---
### Schritte (wenn konsolidiert)
- Hub-Auth-CSS in `portal.css` ziehen (mit `@source` für die Tokens)
- `auth/pressekonto`-Layout auf Portal-Build umstellen
- Hub-Auth-Klassen (`.auth-card`, `.auth-grid`, `.auth-btn-primary`)
bleiben — laufen nur jetzt aus dem Portal-Bundle
- `theme-pressekonto.css` aus dem Web-Build entfernen (oder behalten
für die Landing)
## Gesamt-Status (Stand 2026-05-20)
| Phase | Inhalt | Status |
|---|---|---|
| 0 | Hub-Auth (Login/Register) im Hub-Stil | ✅ |
| 1 | Portal-Migration (Tokens, FluxUI-Overrides, Sidebar/Topbar, App-Shell, Dark-Switch im User-Menü) | ✅ |
| 2 | Customer-Dashboard auf Mockup-Stil | ✅ (in P1, verfeinert in 4J) |
| 3 | Admin-Dashboard konsistent | ✅ (in P1, verfeinert in 4J) |
| 4 | Listen/Detail durchgehen (4A–4J) | ✅ **komplett** |
| 5 | Dark Mode konsistent | ✅ **abgeschlossen** |
| 6 | Auth-Cleanup | ✅ **abgeschlossen** |
### Phase 4 — Sub-Päckchen im Detail
| ID | Bereich | Plan-Doc |
|---|---|---|
| 4A | Press-Releases Listen (Admin + Customer) | `07-PHASE-4A-…` |
| 4B | Press-Releases Detail/Show | `08-PHASE-4B-…` |
| 4C | Press-Releases Forms (create/edit) | `09-PHASE-4C-…` |
| 4D | Companies (Admin) | `10-PHASE-4D-…` |
| 4E | Profile/Settings (Admin + Customer) | `11-PHASE-4E-…` |
| 4F | Restliche Admin-Bereiche (contacts, categories, presets, footer-codes, users, roles, newsletter, reports, invoices, coupons, payments, portal-switcher) | `13-PHASE-4F-…` |
| 4G | Restliche Customer-Bereiche (invoices, tokens, bookings, company-switcher, press-kits) | `12-PHASE-4G-…` |
| 4H | Customer „Meine Pressemitteilungen" Mockup-Stil (Counter-Strip, Saved-Views, Filter-/Active-Chips, Portal-Pills, Inline-Actions, Row-Tint, 3-stufiger Empty-State, Aktionen-Legende) | `14-PHASE-4H-…` |
| 4I | Admin „Pressemitteilungen" — Mockup-Patterns übertragen | `15-PHASE-4I-…` |
| 4J | Dashboard-PM-Listen mit 4H/4I-Patterns | `16-PHASE-4J-…` |
### Nächste sinnvolle Schritte (Priorität)
> Die hub-flux-Roadmap ist mit Phase 6 **vollständig** abgeschlossen.
> Alle weiteren Themen sind eigene Initiativen.
1. **Manueller Dark-Mode Smoke-Test**: Im Browser User-Menü →
Erscheinung → „Dunkel" und durch die Hauptseiten klicken
(Dashboard, Listen, Detail, Security mit QR, Tokens). Erwartung:
Lesbar + konsistent. Kleine Polish-Runde, falls visuelle
Auffälligkeiten.
2. **PM-Form-Wizard-Refactor**: Mockup
`User Neue Mitteilung presseportale.html` auf den bestehenden
Press-Release-Create/Edit-Flow übertragen. Größere Aktion mit
eigener Phase.
3. **Web-Frontend-Block** (eigenständig, NICHT Teil von Phase 1–6):
Die noch ungenutzten Mockups
`Startseite Tailwind.html`,
`Startseite presseecho Tailwind.html`,
`Branchenseite Tailwind.html`,
`Detailseite Tailwind.html`,
`Veröffentlichen Tailwind.html`
sind Public-Facing-Pages der beiden Portale (businessportal24 +
presseecho), nicht Portal/Backend. Würde eine **eigene Roadmap**
bekommen, weil andere Build-Pipeline (`vite.web.config.js`), andere
Komponenten und ein ganz anderer Stil-Stack
(Source-Serif-Headlines, Brand-orange für businessportal24).

View file

@ -0,0 +1,79 @@
# Phase 4D — Companies (admin)
> Viertes Päckchen aus Phase 4. Folgt auf 4A/4B/4C
> (Press-Releases-Strecke komplett).
**Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag · **Risiko**: niedrig–mittel
---
## Scope
- `resources/views/livewire/admin/companies/index.blade.php` (573 Z.)
- `resources/views/livewire/admin/companies/show.blade.php` (400 Z.)
- `resources/views/livewire/admin/companies/edit.blade.php` (412 Z.)
- `resources/views/livewire/admin/companies/create.blade.php` (281 Z.)
NICHT in diesem Päckchen:
- `admin/contacts/*` — eigener Bereich, Päckchen 4F.
- `me/press-kits/*` — Customer-Sicht auf Firmen, eigener Päckchen-Anteil.
- Settings / Profile (Päckchen 4E).
## Ziel
Alle vier Companies-Pages im Hub-Vokabular — gleiches Muster wie
die Press-Releases-Strecke:
- **Page-Header** mit Hub-Badge „Admin Backend" + Eyebrow + H1 +
Subtitle. Bei Show/Edit zusätzlich Portal-Pille (Presseecho /
Businessportal24 / Both) und ID/Slug-Hinweis.
- **KPI-Reihe** auf Index als `<x-portal.stat-card>` falls Stats
vorhanden (Gesamt, je Portal, ggf. mit/ohne PMs).
- **Filter-Bar** als `.panel` mit `.panel-head` „Filter & Suche".
- **Tabelle/Listen** in `.panel` mit Hub-Badges
(`.badge.hub|ok|warn`).
- **Form-Sektionen** (Edit, Create) als `.panel` mit `.panel-head`
und `section-eyebrow`.
- **Tabs** (Show: „contacts", andere?) bleiben als FluxUI-Tabs —
optisch über das Token-Bridging genug Hub-Look.
- **Confirm-Modals** unverändert lassen (z.B. delete-confirm).
## Was explizit NICHT angefasst wird
- **Volt-Logik** in allen 4 Files — Layout-only.
- **`deleteCompany`**-Methode + Confirm-Modal — Test
`UserManagementTest` assertiert Redirect-Verhalten.
- **Wortlaute, die Tests prüfen**:
- `Firmen` (Sidebar-Link), `Portal`, `Alle Portale`,
`Firmen PM Zaehler GmbH` (Faktur-Name).
- Portal-Labels `Presseecho`, `Businessportal24`.
- URL-Pfade `/admin/companies/{id}`.
- **FluxUI Form-Felder, Combobox, Tab-Groups** bleiben.
## Akzeptanzkriterien
- [x] Plan
- [x] Index: Page-Header + Stats + Filter-Panel + Tabellen-Panel +
Hub-Badges.
- [x] Show: Page-Header (mit Portal-Pille) + Logo-/Meta-Block +
Tabs + Hub-Badges.
- [x] Edit: Page-Header (mit Portal-Pille) + Form-Panels +
Aktions-Panel. Delete-Modal unverändert.
- [x] Create: Page-Header + Form-Panels + Aktions-Panel.
- [x] `UserManagementTest`, `PortalAssetManifestTest` grün
(25 Tests, 227 Assertions). Volle Suite: 230 grün
(Vorhandener `ApiDocumentationTest`-Fail nicht von uns).
- [x] Build + Pint + PROGRESS.
## Notes
- Tabs als schlankes Bottom-Border-Pattern statt FluxUI-Tabs:
spart Layout-Komplexität und ist optisch näher am Hub.
- Portal-Badges bewusst alle als `badge hub` vereinheitlicht —
Portal-spezifische Farben (purple/blue) brachen aus dem
Tokensystem aus. Portal-Label bleibt sichtbar im Text.
- Logo-Boxen folgen jetzt dem gleichen Token-Pattern wie auf den
Press-Release-Detail-Seiten (`var(--color-bg-elev)` +
`var(--color-bg-rule)` border).
- Delete-Confirm-Modal komplett unverändert (Test prüft Redirect
nach `deleteCompany`, nicht UI).

View file

@ -0,0 +1,103 @@
# Phase 4E — Profile & Settings
> Fünftes Päckchen aus Phase 4. Folgt auf 4D Companies.
**Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag · **Risiko**: niedrig
---
## Scope
**Admin / „/settings/*" (alle Rollen)**
- `resources/views/livewire/settings/profile.blade.php` (117 Z.)
- `resources/views/livewire/settings/password.blade.php` (82 Z.)
- `resources/views/livewire/settings/appearance.blade.php` (21 Z.)
- `resources/views/livewire/settings/delete-user-form.blade.php`
(59 Z., wird in profile.blade.php als Komponente eingebunden)
**Customer („Mein Bereich")**
- `resources/views/livewire/customer/profile.blade.php` (451 Z.)
- `resources/views/livewire/customer/security.blade.php` (295 Z.)
NICHT in diesem Päckchen:
- `customer/invoices.blade.php`, `customer/tokens.blade.php`,
`customer/bookings.blade.php`, `customer/company-switcher` —
eigenes Päckchen 4F.
- 2FA-Pages aus Fortify-Standard-Setup — bleiben FluxUI bis sie
separat angepackt werden.
## Ziel
Beide Settings-Strecken im Hub-Vokabular wie Press-Releases /
Companies:
- **Page-Header** mit Rolle-Pille („Admin Backend" oder
„User Backend") + Eyebrow + H1 + Subtitle.
- **Form-Sektionen** als `.panel` mit `.panel-head` und
`section-eyebrow`.
- **FluxUI-Form-Felder** bleiben (`flux:field`, `flux:input`,
`flux:label`, `flux:error`, `flux:checkbox`, `flux:radio`,
`flux:textarea`, `flux:button`).
- **Required-Marker** auf Hub-Token (`text-[color:var(--color-err)]`).
- **Save-Action** in eigenem Panel-Footer mit Save-Indicator-Span.
- **Flash-/Success-Messages** auf Hub-Token-Pillen.
- **Danger-Zone** (Delete-Account, Sessions löschen) als
`.panel` mit `is-danger`-Akzent (linker Roter Strip).
## Was explizit NICHT angefasst wird
- Volt-Logik in allen Dateien.
- `<x-settings.layout>` Wrapper-Komponente (falls vorhanden) —
Layout-only-Änderungen, keine Hülle.
- 2FA-/Confirm-Password-Modals.
- Test-relevante Strings auf customer/profile + customer/security:
- **profile**: „Rechnungsadresse"
- **security**: „Konto-Sicherheit", „Letzter Login",
„Aktive Sessions", „Passwort ändern", „E-Mail-Adresse ändern",
„Zwei-Faktor-Authentifizierung"
## Akzeptanzkriterien
- [x] Plan
- [x] `partials/settings-heading` zentral auf Hub-Page-Header.
- [x] `components/settings/layout` zentral auf Hub-Sidebar +
Content-Panel.
- [x] `settings/appearance` Hub-styled (profitiert vom neuen
Wrapper, kein Body-Touch nötig).
- [x] `settings/profile` Hub-styled + Verification-Hinweis als
Hub-Warn-Box + Save-Button mit Token-„Saved."-Pill.
- [x] `settings/delete-user-form` als Hub-Danger-Box mit
linkem Roten Strip. Modal-Markup unverändert.
- [x] `settings/password` Hub-styled (Save-Bar mit Border-Top).
- [x] `customer/profile` Hub-styled: Header, 3 Panels (Konto,
Profil, Rechnungsadresse), Aktionen-Panel, Zugeordnete-Firmen-
Panel mit Hub-Badges.
- [x] `customer/security` Hub-styled: Header, 4-spaltige
KPI-Reihe, Passwort+E-Mail 2-Col-Grid, 2FA-Panel mit
Hub-Recovery-Codes, Sessions-Panel mit Hub-Empty-State.
- [x] Tests grün:
- `Settings|CustomerProfileSecurity|CustomerCompanyContext`
→ 33 passed (146 assertions).
- Volle Suite → 230 passed, 3 skipped, 1 pre-existing
`ApiDocumentationTest`-Fail (nicht von 4E).
- [x] Build + Pint + PROGRESS.
## Notes
- Der zentrale Umbau der beiden Wrapper (`settings-heading`,
`settings.layout`) hat sich bezahlt gemacht: die drei
`settings/*`-Pages sind weitgehend identisch klein geblieben,
Page-Header und Side-Nav kommen automatisch im Hub-Look.
- `<x-action-message>` für „Saved."-Toast bleibt drin, aber
der Slot ist auf einen Hub-getönten `<span>` umgestellt.
- Empty-State für „Aktive Sessions" nutzt das gleiche
Hub-Icon-Box-Pattern wie auf den Press-Releases-Listen.
- 2FA-QR-Container behält explizit weißen Hintergrund —
QR-Codes brauchen hohen Kontrast unabhängig vom Mode.
- Alle Test-Pflicht-Strings unverändert: „Rechnungsadresse",
„Konto-Sicherheit", „Letzter Login", „Aktive Sessions",
„Passwort ändern", „E-Mail-Adresse ändern",
„Zwei-Faktor-Authentifizierung".

View file

@ -0,0 +1,78 @@
# Phase 4G — Customer Portal (Mein Bereich)
> Sechstes Päckchen aus Phase 4. Folgt auf 4E
> (Profile/Settings).
**Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag · **Risiko**: niedrig–mittel
---
## Scope
**Liste / Detail / Helper**:
- `resources/views/livewire/customer/invoices.blade.php` (194 Z.)
- `resources/views/livewire/customer/tokens.blade.php` (212 Z.)
- `resources/views/livewire/customer/bookings.blade.php` (52 Z.)
- `resources/views/livewire/customer/company-switcher.blade.php`
(91 Z., sitzt in der Sidebar)
- `resources/views/livewire/customer/press-kits/index.blade.php`
(119 Z.)
- `resources/views/livewire/customer/press-kits/show.blade.php`
(734 Z., großes Detail-Cockpit)
NICHT in diesem Päckchen:
- `customer/press-releases/*` — schon in 4A/4B/4C.
- `customer/dashboard.blade.php` — schon in Phase 2.
- `customer/profile.blade.php`, `customer/security.blade.php` —
schon in 4E.
- Admin-Bereich (Päckchen 4F).
## Ziel
Alle Customer-Pages im Hub-Vokabular:
- **Page-Header** „User Backend"-Pille + Eyebrow
„Mein Bereich · …" + H1 + Subtitle.
- **KPI/Summary-Reihe** wo Stats existieren
(`<x-portal.stat-card>`).
- **Tabellen, Listen, Forms** in `.panel` mit `.panel-head`.
- **Flash-Boxen** (success/info/warn/error) auf Hub-Token.
- **Hub-Badges** statt `flux:badge` (außer dort wo speziell
begründet).
- **Empty-States** als Hub-Icon-Box.
- **Company-Switcher**: bleibt funktional, optisch Hub-Akzent.
## Was explizit NICHT angefasst wird
- Volt-Logik in allen Dateien.
- `<flux:select variant="combobox">`, `<flux:input>` usw.
- Konfirm-/Edit-Modals in `press-kits/show.blade.php` (falls
vorhanden).
- Bestimmte Strings, die Tests assertieren:
- **tokens**: „API-Tokens" (Heading),
„API-Tokens werden erst freigeschaltet" (Hinweis).
- **invoices**: „Hinweis zu Rechnungen",
„Rechnungsadresse im Profil pflegen", „Öffnen".
- **company-switcher**: „Firma öffnen",
`route('me.press-kits.show', …)`.
- **press-kits.show**: „Abrechnung", „Statistik" (Tab-Labels
bzw. Section-Headings).
## Akzeptanzkriterien
- [x] Plan
- [x] `customer/invoices`
- [x] `customer/tokens`
- [x] `customer/bookings` (Coming-Soon-Stub)
- [x] `customer/company-switcher` (Sidebar-Komponente)
- [x] `customer/press-kits/index`
- [x] `customer/press-kits/show` (Stammdaten/Kontakte/PMs/
Abrechnung/Statistik im Hub-Stil; Forms inline behalten)
- [x] `CustomerPortalTest`, `CustomerCompanyContextTest`,
`PanelConsolidationTest` grün (29 Tests, 131 Assertions).
- [x] Volle Suite: 230 passed, 3 skipped, 1 pre-existing fail
(`ApiDocumentationTest`, fehlende `docs/api/v1.yml`).
- [x] Build (portal: 418 kB CSS, 44 kB JS) + Pint clean +
PROGRESS.

View file

@ -0,0 +1,84 @@
# Phase 4F — Restliche Admin-Bereiche
> Siebtes Päckchen aus Phase 4. Folgt auf 4G
> (Customer Portal).
**Status**: ✅ abgeschlossen · **Aufwand**: ~1,5–2 Tage · **Risiko**: niedrig
---
## Scope
Insgesamt ~7.500 Z. Blade. Aufgeteilt in 4 Sub-Päckchen:
### 4F-1 — Stammdaten & Switcher (~1.250 Z.)
- `admin/presets/{index,create,edit}.blade.php` (361 Z.)
- `admin/presets/partials/form-fields.blade.php`
- `admin/categories/{index,create,edit}.blade.php` (813 Z.)
- `admin/portal-switcher.blade.php` (68 Z., Sidebar-Komponente)
### 4F-2 — Pressekontakte (~1.360 Z.)
- `admin/contacts/index.blade.php` (729 Z.)
- `admin/contacts/create.blade.php` (275 Z.)
- `admin/contacts/edit.blade.php` (352 Z.)
### 4F-3 — Operations & Finance (~1.870 Z.)
- `admin/footer-codes/{index,create,edit}.blade.php` (673 Z.)
- `admin/reports/slow-requests.blade.php` + table (288 Z.)
- `admin/invoices/index.blade.php` (314 Z.)
- `admin/coupons/index.blade.php` (43 Z., Stub)
- `admin/payments/index.blade.php` (53 Z., Stub)
### 4F-4 — User-Verwaltung (~3.020 Z.)
- `admin/users.blade.php` (939 Z.) +
`admin/users/{create,edit,show,table}.blade.php`
- `admin/roles/{index,create,edit}.blade.php` (393 Z.)
- `admin/newsletter/sync.blade.php` (171 Z.)
## Ziel
Alle Admin-Pages im Hub-Vokabular:
- **Page-Header** „Admin Backend"-Pille + Eyebrow
„Administration · …" + H1 + Subtitle.
- **KPI/Summary-Reihe** wo Stats existieren
(`<x-portal.stat-card>`).
- **Tabellen, Listen, Forms** in `.panel` mit `.panel-head`.
- **Flash-Boxen** (success/info/warn/error) auf Hub-Token.
- **Hub-Badges** statt `flux:badge` (außer in begründeten
Fällen).
- **Empty-States** als Hub-Icon-Box.
- **Danger-Zones** mit linkem roten Strip.
## Was explizit NICHT angefasst wird
- Volt-Logik in allen Dateien.
- `<flux:input>`, `<flux:select>`, `<flux:checkbox>`,
`<flux:textarea>`, `<flux:field>`, `<flux:error>`,
`<flux:table.*>`, `<flux:button>`, `<flux:modal>` etc.
- Modals und ihre Bestätigungs-Flows.
- Test-relevante Strings — vor jedem Sub-Päckchen werden die
betreffenden Test-Assertions geprüft.
## Tests pro Sub-Päckchen
| Sub | Tests |
|---|---|
| 4F-1 | `CategoryIndexPerformanceTest`, `AdminCategoryManagementTest`, `AdminPresetManagementTest` |
| 4F-2 | (keine spezifischen Contact-Tests gefunden, evtl. via `AdminAssetManifestTest` indirekt) |
| 4F-3 | `AdminFooterCodeManagementTest`, `AdminSlowRequestReportTest`, `AdminSlowRequestLoggingTest`, `AdminLegacyInvoiceArchiveTest` |
| 4F-4 | `UserManagementTest`, `UserImpersonationTest`, `RoleManagementTest` |
## Akzeptanzkriterien
- [x] Plan
- [x] 4F-1 Stammdaten & Switcher
- [x] 4F-2 Pressekontakte
- [x] 4F-3 Operations & Finance
- [x] 4F-4 User-Verwaltung
- [x] Tests pro Sub-Päckchen grün
- [x] Build + Pint + PROGRESS.

View file

@ -0,0 +1,171 @@
# Phase 4H — Customer „Meine Pressemitteilungen" auf Mockup-Stil
> Nachgelagertes Päckchen aus Phase 4. Hebelt das wichtigste
> Customer-Arbeitstool auf das volle Mockup-Vokabular.
**Status**: ✅ abgeschlossen · **Aufwand**: ~1 Tag · **Risiko**: niedrig
---
## Anlass
`customer/press-releases/index.blade.php` ist heute auf
~50 % Mockup-Match: Page-Header, Filter-Panel, Tabelle und
Empty-State sind Hub-styled, aber alle hochwirksamen Patterns
aus dem Mockup fehlen. Diese Seite ist die meistbesuchte des
Customer-Bereichs (primäres Arbeitstool).
## Vorlage
`dev/frontend/tailwind_v3/User Pressemitteilungen presseportale.html`
## Match-Ziel
≥ 90 % zum Mockup, ohne Backend-API-Erweiterungen.
---
## Scope — was umgesetzt wird
### 1. Counter-Strip im Header
Statt langer Subzeile: Inline-Counter pro Status direkt
unter H1.
`24 Mitteilungen · 18 veröffentlicht · 1 in Prüfung · 4 Entwürfe · 1 abgelehnt`
Zahlen kommen aus aggregiertem `withCount()` über die Status-Enum.
### 2. Saved-Views-Tabs
Tab-Leiste statt Status-Dropdown:
`Alle (24) · Veröffentlicht (18) · Entwürfe (4) · In Prüfung (1) · Abgelehnt (1) · Archiv (0)`
Aktive Tab unterstrichen mit Hub-Blau. Klick → `statusFilter`-Volt-Property.
### 3. Filter-Chips mit Caret
Status/Portal/Firma/Zeitraum als Chips mit Dropdown-Caret.
Aktive Chip in Hub-Blau, inaktive auf weißem Background.
**Hinweis**: Status-Chip ist im UI redundant mit Saved-Views-Tabs;
wir lassen ihn weg. Bleiben: Portal, Firma, Zeitraum (`erstellt` ab Datum X).
### 4. Active-Chips (entfernbare Filter)
Unter den Filter-Chips: Sichtbarmachung aktiver Filter mit
`×`-Button zum Entfernen.
### 5. Bulk-Selection (nur UI-Vorbereitung)
Checkbox in Header und pro Zeile. Header-Checkbox kann
indeterminate-State haben. **Keine Bulk-Aktionen** im Scope —
das wird erst später ein eigenes Päckchen (Bulk-Approve etc.).
### 6. Portal-Pills mit farbigem Dot
Pro Zeile in Spalte „Portal": je nach `portal`-Enum:
- `presseecho` → grüner Dot
- `businessportal24` → orangener Dot
- `both` → beide Pills nebeneinander
### 7. Inline-Actions neben Status
Statusspalte bekommt **zusätzlich** zur Badge eine kleine
Inline-Action je nach Status:
| Status | Inline-Action |
|---|---|
| Draft | `Zur Prüfung →` |
| Review | `Zurückziehen →` (nur wenn `withdrawFromReview` existiert, sonst weglassen) |
| Published | — (keine Inline-Action, nur Hauptaktion „Vorschau") |
| Rejected | `Grund ansehen →` (Modal/Tooltip mit `rejection_reason`) |
| Archived | — |
### 8. Row-Tinting
Zeilen mit Status `review` bekommen `is-row-warn` (sehr
dezent gelb beim Hover), `rejected` bekommen `is-row-err`
(rot beim Hover).
### 9. Reichere Zeilen-Sub
Sub-Zeile unter Titel: `PM-Nummer · Datum · Hinweis`
Wir nutzen vorhandene Felder: `id` (als „PM-{id}"), `published_at`,
`rejection_reason`-Existenz.
### 10. Datum mit Sub
Datumsspalte zweizeilig: Datum (Mono-Font, tabular-nums) +
Sub (Status-Kontext z.B. „veröffentlicht · 09:12").
### 11. 3-fach Empty-State
Drei Varianten je nach Kontext:
- **`empty-filter`** — wenn Filter aktiv: „Keine Mitteilungen mit diesen Filtern" + Reset-Button
- **`empty-search`** — wenn `search` gesetzt: „Keine Treffer für `…`" + Suche-Reset
- **`empty-none`** — wenn gar keine PMs überhaupt: „Noch keine Pressemitteilungen" + 3-Schritt-Onboarding
### 12. Status-Aktionen-Legende
`panel-warm` unter der Tabelle: 5-Spalten-Grid mit allen
Aktionen pro Status. Reduziert Support-Anfragen.
### 13. Spalten-/Export-Buttons (rechts im Header)
„Spalten" (jetzt non-functional als `bald`-Badge) und „Export"
(`bald`-Badge) als sekundäre Buttons. Optional — können auch
weggelassen werden, da wir keine Spalten-Konfiguration haben.
→ **Entscheidung**: weglassen. Kein UX-Mehrwert ohne Backend.
---
## Was NICHT angefasst wird
- Volt-Logik (`submitForReview`, `sort`, `with`) — nur erweitert
um Aggregate-Counts.
- Backend-Endpoints / API.
- Detail-/Show-Seite und Create/Edit-Forms.
- Routen.
## Neue / erweiterte CSS-Klassen in `hub-components.css`
- `.counter-strip`, `.counter-strip .seg`, `.counter-strip .sep`
- `.view-tab` (mit `.is-active`, `.cnt`)
- `.filter-chip` (mit `.is-active`, `.caret`)
- `.active-chip` (mit `.x`)
- `.portal-pill` (mit `.pe`, `.bp`, `.pdot`)
- `.inline-action` (mit `.warn`, `.err`)
- `.is-row-warn`, `.is-row-err` (Row-Tinting)
- `.empty-stage`, `.empty-ico`, `.empty-title`, `.empty-sub`
- `.badge.muted` (für Draft / Archiv)
- Optional: `.checkbox.indeterminate` (für Bulk-Header)
## Volt-Erweiterungen
- `statusCounts` (assoc-Array Status-Value → int) — aggregiert
über `withoutGlobalScopes()->where('user_id', …)->groupBy('status')`
- `totalCount` (int) — Gesamt-Counter unabhängig vom Filter
- Saved-View-Klick mappt auf `statusFilter` (kein eigener Property nötig)
## Tests
Keine bestehenden Tests für `customer/press-releases/index`
gefunden. Akzeptanz:
- `php artisan test --compact` läuft sauber (modulo
pre-existing `ApiDocumentationTest`)
- Build (`npm run build:portal`) clean
- Pint clean
## Akzeptanzkriterien
- [x] Plan
- [x] CSS-Klassen ergänzt
- [x] Volt-Counts ergänzt
- [x] Markup auf Mockup-Stil
- [x] Build + Pint + Tests grün
- [x] PROGRESS.md + 03-WEITERE-PHASEN.md aktualisiert

View file

@ -0,0 +1,136 @@
# Phase 4I — Admin „Pressemitteilungen" Mockup-Patterns
> Folgepäckchen zu 4H. Überträgt die in der Customer-PM-Liste
> entwickelten Mockup-Patterns auf die Admin-Seite. Die
> CSS-Komponenten existieren bereits.
**Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag · **Risiko**: niedrig
---
## Anlass
Nach 4H matched `customer/press-releases/index.blade.php` das
Mockup zu ~90 %. Die gleichen Patterns gehören in die
Admin-Liste — das ist der zentrale Editorial-Workflow.
## Aktueller Stand
`admin/press-releases/index.blade.php` ist bei ~60 % Match:
- ✅ Page-Header (Hub-Stil)
- ✅ 4-KPI-Reihe (`<x-portal.stat-card>`)
- ✅ Filter-Panel (search/status/portal/language/category +
3 entity-comboboxes)
- ✅ Tabellen-Panel + Empty-State (Hub-styled)
- ✅ Modals (publish/reject/archive) — test-kritisch
- ❌ Saved-Views-Tabs
- ❌ Active-Chips für aktive Filter
- ❌ Portal-Pills (statt Text)
- ❌ Row-Tinting (review/rejected)
- ❌ Inline-Actions („Veröffentlichen →", „Ablehnen →" neben Status)
- ❌ Reichere Sub-Zeilen (PM-{id} + Datum + Status-Kontext)
## Scope
### 1. Saved-Views-Tabs
Tab-Leiste zwischen KPI-Reihe und Filter:
`Alle · Veröffentlicht · In Prüfung · Entwürfe · Abgelehnt · Archiv`
Counter-Pille pro Tab basierend auf erweiterten `stats`.
### 2. Active-Chips
Sichtbarkeit aller aktiven Filter (Status, Portal, Sprache,
Kategorie, User, Firma, Kontakt, Suche), jeweils mit `×`.
### 3. Portal-Pills
Statt „Presseecho"/„Businessportal24"/„Beide" als Text:
Portal-Pills mit farbigem Dot. Bei `Portal::Both` zwei
Pills nebeneinander.
### 4. Row-Tinting
`is-row-warn` für review, `is-row-err` für rejected.
### 5. Inline-Actions
**Zusätzlich** zu den bestehenden Action-Buttons + Modals:
| Status | Inline-Action |
|---|---|
| Review | `Freigeben →` + `Ablehnen →` (öffnet die Modals) |
| Published | `Archivieren →` (öffnet Modal) |
Die Inline-Actions sind **nur** Trigger für die bestehenden
Modals (keine direkte Wire-Methode), damit die existierenden
Test-Modal-Strings („Pressemitteilung veröffentlichen?")
weiter angezeigt werden. Action-Buttons in der `Aktionen`-
Spalte bleiben als Backup für Power-User.
### 6. Reichere Sub-Zeilen
In Titel-Zelle: `PM-{id}` als Sub. In Datum-Zelle: Hauptdatum
+ Status-Kontext (`erstellt · 11:02`, `veröffentlicht · 14:30`, …).
### 7. Counter-Strip ausgelassen
KPI-Reihe ist bereits 4-spaltig (Gesamt, Veröffentlicht, In
Prüfung, Entwürfe) und voll funktional. Counter-Strip wäre
redundant. Bleibt bei KPI-Cards.
## Was bleibt unangetastet
- **Volt-Methoden** (`publish`, `reject`, `archive`, `sort`,
`with`, `clearUserFilter`, …)
- **Bestehende Modals** mit Strings „Pressemitteilung
veröffentlichen?", „Pressemitteilung ablehnen?",
„Pressemitteilung archivieren?" (Test-kritisch)
- **Filter-Panel-Struktur** (Entity-Comboboxes erhalten,
kein Reduktionsexperiment)
- **`stats`-Cache-Methode** (`AdminPerformanceCache`)
## Erweiterung
- `pressReleaseStats()` erweitert um `rejected` und `archived`
Counter, damit alle 6 Saved-Views-Tabs ihre Counter haben
## Tests
- `AdminPressReleaseActionsTest` (3 Tests, prüft auf Modal-Strings)
- `PressReleaseWorkflowTest` (mehrere Tests, prüft auf
`publish`/`reject`-Methoden + Audit-Logs)
- Volle Suite muss weiter sauber laufen (modulo
pre-existing `ApiDocumentationTest`)
## Akzeptanzkriterien
- [x] Plan
- [x] Volt: `stats` um `rejected` + `archived` erweitert
- [x] Volt: `setView()` + `resetFilters()` ergänzt
- [x] Saved-Views-Tabs eingebaut (6 Stück inkl. Counter)
- [x] Active-Chips eingebaut (8 Filter-Typen)
- [x] Portal-Pills statt Text (incl. Both → 2 Pills)
- [x] Row-Tinting (review → warn, rejected → err)
- [x] Inline-Actions als Modal-Trigger
(Freigeben/Ablehnen/Archivieren) zusätzlich neben Badge
- [x] Sub-Zeilen: PM-ID + Firma + Sprache, Datum + Status-Kontext
- [x] Empty-State 2-stufig (mit/ohne Filter)
- [x] Build + Pint + Tests grün (16/16 PR + 230/231 voll)
- [x] PROGRESS.md + 03-WEITERE-PHASEN.md aktualisiert
## Lessons Learned
- `@php(...)` Inline-Form führte beim Compile zu einem
Syntax-Fehler im kompilierten View (führte zu
`<?php($var = ...)` ohne Whitespace), obwohl alle Klammern
balanced waren. Vermutung: Konflikt der Klammer-Zählung
mit Methoden-Calls. Lösung: alle drei `@php(...)`
Statements zu `@php ... @endphp` umgewandelt.
- Tabellen-Spalten reduziert (8 → 7), weil die rechte
„Aktionen"-Spalte mit den Status-Icons inhaltlich
redundant zur neuen Inline-Action in der Status-Spalte
war. Die linke „Aktionen"-Spalte (view/edit) blieb.

View file

@ -0,0 +1,63 @@
# Phase 4J — Dashboard-PM-Listen mit 4H/4I-Patterns
> Mini-Folgepäckchen: Die in 4H/4I entwickelten
> Mockup-Patterns (Portal-Pills, Status-Sub-Zeilen,
> Inline-Actions) werden auf die kompakten PM-Listen
> in den Dashboards übertragen.
**Status**: ✅ abgeschlossen · **Aufwand**: ~30 min · **Risiko**: niedrig
---
## Anlass
Nach 4H/4I sehen die Voll-Listen exakt wie das Mockup aus —
die Dashboard-Listen ("Meine letzten Pressemitteilungen",
"Letzte Pressemitteilungen", "Zur Prüfung") sind aber noch
auf dem alten Stand (Badge rechts, Sub-Zeile ohne Portal).
Das wirkt inkonsistent.
## Scope
### Customer-Dashboard (Volt `customer/dashboard.blade.php`)
- **Volt-Component**: `recent` lädt aktuell
`['id', 'title', 'status', 'company_id', 'created_at']`.
→ `portal` ergänzen.
- **Markup `recent`-Liste**:
- Portal-Pills (presseecho/businessportal24) neben dem Badge
- Sub-Zeile mit PM-ID + Firma + Datum (statt nur Firma + Datum)
### Admin-Dashboard (Controller-View `admin/dashboard.blade.php`)
- **`recentPRs`-Liste**:
- Portal-Pills neben dem Badge
- Sub-Zeile mit PM-ID + Firma + User + Datum
- **`pendingReviews`-Liste**:
- Portal-Pills neben Titel
- Inline-Action „Prüfen →" als Link zur Show-Page
(im Dashboard keine direkte `publish`/`reject`-Methode
möglich, da Controller+Blade statt Volt)
## Was bleibt unangetastet
- Backend-Logik (Controller, Volt-`with()`)
- Customer-Tests (`DashboardTest`) — die geprüften
Strings („Phase 2 Demo Release", „Alle anzeigen",
„Meine letzten Pressemitteilungen", …) bleiben
- Quick-Actions, Newsletter, Brand-Bridge — bereits gut
## Akzeptanzkriterien
- [x] Plan
- [x] Customer-Volt: `portal` + `published_at` in
Recent-Select-Liste
- [x] Customer-Dashboard: Portal-Pills + PM-ID-Sub
+ published_at als Primärdatum bei Published
- [x] Admin-Dashboard recentPRs: Portal-Pills + PM-ID-Sub,
`badgeClass` mit `muted`-Variante (statt `hub` für
archived/draft)
- [x] Admin-Dashboard pendingReviews: Portal-Pills +
Inline-Action „Prüfen →" + `is-row-warn` Tinting
- [x] Build + Pint + Tests grün (5/5 Dashboard, 230/231 voll)
- [x] PROGRESS.md + 03-WEITERE-PHASEN.md aktualisiert

View file

@ -0,0 +1,152 @@
# Phase 5 — Dark Mode
> Dark Mode für das Portal (Customer + Admin), gesteuert
> über den FluxUI Appearance-Switcher. Hub-Frontend bleibt
> Light-Only.
**Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag
(meiste Arbeit war Vorbereitung in Phase 0–4) · **Risiko**: niedrig
---
## Befund
Beim Start in Phase 5 war faktisch ~95 % der Arbeit schon
in den vorherigen Phasen erledigt worden. Konkret:
### Was bereits da war
1. **`shared/design-tokens.css`** hat einen kompletten
`.dark { … }`-Block (Z. 182–248) mit:
- Surfaces (bg, bg-elev, bg-rule, bg-card, bg-card-warm)
- Hub-Blau (heller im Dark Mode: `#5a78c2`)
- Bernstein (heller: `#d9a560`), `--color-accent-warm`
bewusst konstant
- Ink-Skala (invertiert)
- Status-Farben (ok/warn/err in helleren Varianten)
- Bridge-Dots (heller)
- Schatten (neutral schwarz statt warm-blau)
- `color-scheme: dark` für native Controls
2. **`portal.css`** hat:
- `@custom-variant dark (&:where(.dark, .dark *))` für
Tailwind-`dark:`-Variants
- Dark-Mode Shadow-Overrides für FluxUI-Primary-Buttons
- Klare Erläuterung, warum kein Notfall-`.dark { … }`-Hack
mehr nötig ist
3. **`shared/hub-components.css`** ist **zu 100 %
token-basiert** (panels, badges, view-tabs, filter-chips,
active-chips, portal-pills, inline-actions, empty-stage,
counter-strip). Sobald die Tokens umschalten, schalten
alle Komponenten automatisch um.
4. **`panel-dark`** nutzt `--color-panel-dark-2` /
`--color-panel-dark` — die sind in beiden Modi
identisch. Die Brand-Bridge-Card bleibt damit immer
dunkel.
5. **`@fluxAppearance`** ist in beiden Head-Partials
eingebunden (`partials/head.blade.php` +
`partials/admin-head.blade.php`).
6. **Switcher** ist an drei Stellen verfügbar:
- Sidebar Desktop User-Menü
(`components/layouts/app/sidebar.blade.php`)
- Sidebar Mobile User-Menü (gleiche Datei)
- `settings/appearance.blade.php` (volle Card mit
Light/Dark/System)
Alle drei nutzen `x-model="$flux.appearance"` —
FluxUI's Magic-Object, das LocalStorage-persistent ist
und automatisch `class="dark"` auf `<html>` setzt.
### Was zu fixen war
Bei der Inventur fielen nur zwei Stellen auf, die im
Dark Mode brechen würden:
1. **`customer/tokens.blade.php` Z. 137**: Token-Anzeige
nach Generierung nutzte ein nicht existentes
`--color-ink-deep`-Token. Damit war der Hintergrund
bisher schlicht transparent (Light: kaum sichtbar,
Dark: ebenso). Außerdem würde `--color-ink` im Dark
Mode hell werden — weißer Text auf hellem Bg wäre
unlesbar. Fix: auf `--color-panel-dark-2` (konstant
dunkel) umstellen.
2. **`customer/security.blade.php` Z. 270**: 2FA-QR-Code
in `bg-white`-Block. Das ist **bewusst** so — QR-Codes
brauchen schwarz-auf-weiß, sonst werden sie nicht
eingescannt. Kein Fix, nur Kommentar zur Klarstellung.
### Was unkritisch ist
- `customer/dashboard.blade.php`: 8 Treffer für
`bg-white` / `text-white` — alle im `panel-dark`
Brand-Bridge Block (konstant dunkel, weiße Texte
korrekt) und im Empty-State Counter-Badge auf
`--color-accent` (Bernstein-Bg, beides Modi).
- `admin/dashboard.blade.php` Z. 235: Quick-Action
Hover-State `group-hover:bg-hub group-hover:text-white`
— Hub-Bg ist sowohl Light (dunkles Hub-Blau) als auch
Dark (helleres Hub-Blau) okay für weißen Text.
- Sidebar-`dark:bg-zinc-…` Klassen aus dem Starter-Kit:
Die Zinc-Skala ist in `portal.css` auf warmes
Buchpapier gemapped, das funktioniert weiter — die
Avatar-Bg's sind sowieso nur 8×8-Pixel-Spots.
- `customer/press-kits/show.blade.php` Z. 440: Logo-Bg
`bg-white` — bewusst, weil Firmen-Logos einen weißen
Hintergrund für korrekte Darstellung brauchen.
### Was außerhalb von Phase 5 ist
- **`shared-styles.css`** hat `.dark .card`, `.dark
.slider-*`, `.dark .highlight-*`, `.dark .section-*`
Regeln. Diese sind für den **Web-Bereich**
(Hub-Frontend, presseecho, businessportal24), nicht
fürs Portal. `portal.css` importiert
`shared-styles.css` **nicht** — die Regeln landen also
nicht im Portal-Bundle.
- **Web-Frontend** bleibt Light-Only — wie in der
Roadmap definiert.
## Akzeptanzkriterien
- [x] Plan
- [x] Recherche aller hardcoded Farbklassen
- [x] `--color-ink-deep` → `--color-panel-dark-2` in
`customer/tokens.blade.php`
- [x] `bg-white` für 2FA-QR-Code in `security.blade.php`
mit erklärendem Kommentar versehen
- [x] Build + Pint + Tests grün
- [x] PROGRESS.md + 03-WEITERE-PHASEN.md auf ✅
## Lessons Learned
- Konsequente Token-Disziplin (kein Hex außer in
`design-tokens.css`) zahlt sich beim Dark Mode massiv
aus: Statt 15 Pages × dutzende Klassen anzufassen,
schaltet das gesamte Portal mit einem `.dark {…}` Block
um.
- Die wenigen Ausnahmen (panel-dark, QR-Code-Bg,
Logo-Bg) sind dokumentierte Bewusst-Entscheidungen,
keine Schuld.
- FluxUI's `$flux.appearance` Magic-Object spart eine
eigene Alpine-Component und persistiert über
LocalStorage.
## Manueller Smoke-Test (Empfehlung)
Da Pest keine echte Browser-Rendering-Pipeline hat:
- Im Browser: User-Menü → Erscheinung → „Dunkel"
- Folgende Seiten besuchen + visuell prüfen:
- `/dashboard` (Admin) + `/me/dashboard` (Customer)
- `/me/press-releases` (Customer-Liste mit
Saved-Views-Tabs, Filter-Chips, Portal-Pills,
Row-Tints)
- `/admin/press-releases` (Admin-Liste mit Inline-Actions)
- `/me/security` (2FA-QR mit `bg-white`)
- `/me/tokens` (Token-Anzeige nach Generierung)
- `/admin/companies/{id}` (Detail-View mit allen Panels)
- Erwartung: Lesbar, konsistent, keine grellen
Kontraste, keine „weißen Inseln" auf dunklem Bg.

View file

@ -0,0 +1,54 @@
# Phase 6 — Auth-Cleanup
> Ungenutzte Starter-Kit-Layouts und Debug-Views entfernen,
> die seit der Hub-Auth-Umstellung (Phase 0) keine Verwendung
> mehr haben.
**Status**: ✅ abgeschlossen · **Aufwand**: ~30 min · **Risiko**: niedrig
---
## Inventur
### Aktiv genutzt (BEHALTEN)
| Datei | Genutzt von |
|---|---|
| `components/layouts/app.blade.php` | Wrapper → `app.sidebar` |
| `components/layouts/app/sidebar.blade.php` | primäres Portal-Layout (alle Volt-Pages) |
| `components/layouts/auth/pressekonto.blade.php` | login, register, forgot-password, verify-email, confirm-password, reset-password |
### Ungenutzt (ENTFERNT)
| Datei | Grund |
|---|---|
| `components/layouts/auth.blade.php` | dünner Wrapper auf `auth.simple` — nirgends als Layout referenziert (außer `login-simple` + `test-simple` Debug, die ebenfalls weg sind) |
| `components/layouts/auth/simple.blade.php` | Starter-Kit-Rest, hardcoded `class="dark"` |
| `components/layouts/auth/split.blade.php` | Starter-Kit-Rest, hardcoded `class="dark"` |
| `components/layouts/auth/card.blade.php` | Starter-Kit-Rest, hardcoded `class="dark"` |
| `components/layouts/app/header.blade.php` | alternatives App-Layout (Top-Bar statt Sidebar), wird vom Wrapper nie aufgerufen, hardcoded `class="dark"` |
| `livewire/auth/login-simple.blade.php` | Debug-Volt-Login („Log in to your account"-Englisch) ohne Route, nutzte `<x-layouts.auth>` |
| `test-simple.blade.php` | Debug-Page „Diese Seite funktioniert ohne Volt/Livewire" ohne Route |
### Aktualisiert
- `_docs/FORTIFY-SANCTUM-SETUP.md`: Code-Beispiel von
`components.layouts.auth` auf `components.layouts.auth.pressekonto`
umgestellt (alter Wert verwies auf die soeben gelöschte
Wrapper-Datei).
## Verifikation
- `rg "auth\.(simple|split|card)"` und
`rg "app\.header"` → 0 Treffer in `resources/` und `routes/`
- Build, Pint, alle relevanten Tests grün
## Lessons Learned
- Mit der Anti-Flash-Bridge aus Phase 5 wären die hardcoded
`class="dark"`-Layouts sowieso zur Stolperfalle für
Light-Mode-User geworden, falls sie je reaktiviert werden.
Lösung: weg damit.
- Hub-Auth-Pages laufen seit Phase 0 ausschließlich über
`auth/pressekonto.blade.php`. Die Starter-Kit-Layouts waren
schon damals tote Last.

View file

@ -5,6 +5,920 @@
---
## 2026-05-20 · Phase 6 · Auth-Cleanup ✅
Mit Phase 6 ist die hub-flux-Roadmap (Phase 0–6) **vollständig
abgeschlossen**. Schlanker Cleanup-Task ohne Risiko.
**Inventur** (Referenzen geprüft via `rg` über `resources/` + `routes/`):
| Datei | Status |
|---|---|
| `components/layouts/app/sidebar.blade.php` | aktiv (primäres Portal-Layout) |
| `components/layouts/auth/pressekonto.blade.php` | aktiv (6 Auth-Pages) |
| `components/layouts/auth.blade.php` | nur in `login-simple`/`test-simple` → weg |
| `components/layouts/auth/simple.blade.php` | Starter-Kit-Rest mit hardcoded `class="dark"` → weg |
| `components/layouts/auth/split.blade.php` | dito → weg |
| `components/layouts/auth/card.blade.php` | dito → weg |
| `components/layouts/app/header.blade.php` | nirgends referenziert → weg |
| `livewire/auth/login-simple.blade.php` | Debug-Page ohne Route → weg |
| `test-simple.blade.php` | Debug-Page ohne Route → weg |
**Gelöscht**: 7 Files, insgesamt ~17 KB Code
**Aktualisiert**: `_docs/FORTIFY-SANCTUM-SETUP.md` (Code-Beispiel
von `components.layouts.auth` auf `components.layouts.auth.pressekonto`).
**Side-Effect**: Portal-CSS-Bundle ist ~2.4 KB kleiner geworden
(422.62 KB statt 425.07 KB), weil weniger Klassen via Tailwind
JIT entdeckt werden.
**Validierung**:
- `php artisan view:clear && npm run build:portal` → grün
- `vendor/bin/pint --dirty --format agent` → passed
- Tests: 230/231 (nur der bekannte pre-existing
`ApiDocumentationTest`)
**Roadmap-Update**:
- `03-WEITERE-PHASEN.md` Phase 6 von „⚪ optional
(Auth-Konsolidierung)" auf „✅ abgeschlossen (Auth-Cleanup)"
umgestellt
- Status-Tabelle: Phase 6 ✅
- „Nächste Schritte" angepasst: kein hub-flux-Item mehr offen,
nur noch eigenständige Initiativen (Dark-Mode-Smoke-Test,
PM-Form-Wizard-Refactor, Web-Frontend-Block)
**Lesson**: Mit der Anti-Flash-Bridge aus Phase 5 wären die
hardcoded `class="dark"`-Layouts zu einer Stolperfalle für
Light-Mode-User geworden, sobald jemand sie reaktiviert hätte.
Cleanup zum richtigen Zeitpunkt.
Plan-Doc: `18-PHASE-6-AUTH-CLEANUP.md`
---
## 2026-05-20 · Phase 5 · Dark-Mode-Bugfixes (User-Findings)
Nach dem ersten visuellen Smoke-Test des Users zwei Folge-Fixes
geliefert, plus die Anti-Flash-Bridge:
### Fix 1 — Logo „presse" im Dark Mode
`components/web/brand-mark.blade.php`: Bei `variant="auto"` (Default)
wird die Name-Farbe jetzt über CSS-Custom-Property `--brand-mark-name-color`
mit Light-Mode-Fallback gesetzt. Im Portal-Dark-Mode setzt
`design-tokens.css` `.dark`-Block die Variable auf `#ffffff`. Hub-Frontend
ist Light-Only, dort bleibt die Variable undefiniert und der Marken-
Standardwert greift.
### Fix 2 — Navlist-Flackern beim Klick
`portal.css` Navlist-Item-Block:
- Hover im Dark Mode auf `var(--color-hub-soft)` (Light-Mode-Hover
`var(--color-bg)` ist dunkler als die Sidebar — wirkte als
„Eindrücken" statt Hervorheben)
- `:active`, `:focus` explizit auf `var(--color-hub-soft)` mit
`outline: none` → verhindert Browser-Default-Tap-Flash
- `-webkit-tap-highlight-color: transparent` für mobile Browser
- `:focus-visible` mit Hub-Ring für Tastatur-A11y bleibt erhalten
### Fix 3 — Anti-Flash-Bridge (FOLT bei `wire:navigate`)
Bei `wire:navigate` morpht Livewire das DOM, das neue HTML kommt
vom Server **ohne** `class="dark"` (Server kennt LocalStorage nicht).
Folge: kurzer weißer Theme-Flash, bis JS die Klasse wieder anhängt.
User hat das richtig diagnostiziert.
Lösung:
1. **JS-Bridge** in `partials/head.blade.php` +
`partials/admin-head.blade.php`: wrappt
`window.Flux.applyAppearance`, spiegelt den effektiv applizierten
Modus (bei `system` aus DOM-Klasse abgelesen → `dark`/`light`)
in ein `flux_appearance`-Cookie. Schreibt auch beim initialen
Page-Load.
2. **Server-Side Render**: `<html>`-Tag in
`components/layouts/app/sidebar.blade.php` und
`layouts/admin-master.blade.php` setzt `class="dark"`
direkt, basierend auf dem Cookie:
`@class(['dark' => request()->cookie('flux_appearance') === 'dark'])`
3. **Bonus**: hardcoded `class="dark"` aus `admin-master.blade.php`
raus (war Light-User-Bug-Falle).
Erstbesuch: einmaliger Flash (Cookie noch nicht gesetzt).
Alle weiteren Pageloads: kein Flash mehr.
### Latente Bug-Fixes nebenbei
- `customer/tokens.blade.php` Z. 137: `--color-ink-deep` Token war
nie definiert → durch `--color-panel-dark-2` ersetzt (konstant
dunkel in beiden Modi)
- `customer/security.blade.php` 2FA-QR: erklärender Kommentar für
`bg-white` (Scan-Tauglichkeit)
**Validierung**:
- Build, Pint, Tests: 230/231 (nur ApiDocumentationTest)
---
## 2026-05-20 · Phase 5 · Dark Mode ✅
Phase 5 (Dark Mode) ist abgeschlossen. Die meiste Arbeit war
faktisch schon in Phase 0–4 erledigt — die konsequente
Token-Disziplin zahlt sich jetzt voll aus.
**Was schon da war (Stand bei Phase-5-Start):**
- `shared/design-tokens.css` hat einen kompletten
`.dark { … }`-Block (Z. 182–248) mit allen Surfaces,
Hub-Blau (heller), Bernstein (heller, mit konstantem
`--color-accent-warm`), Ink-Skala (invertiert),
Status-Farben, Bridge-Dots, Schatten und `color-scheme: dark`
- `portal.css` hat `@custom-variant dark (&:where(.dark, .dark *))`
+ Dark-Mode-Shadow-Overrides für Primary-Buttons
- `hub-components.css` ist 100 % token-basiert
- `panel-dark` nutzt `--color-panel-dark*` (konstant)
- `@fluxAppearance` in beiden Head-Partials integriert
- Switcher in Sidebar (Desktop + Mobile) +
`settings/appearance.blade.php`
**Was im Rahmen von Phase 5 gefixt wurde:**
1. **`customer/tokens.blade.php` Z. 137** — Token-Anzeige
nutzte ein nicht existentes `--color-ink-deep`. Damit war
der Code-Block bisher transparent (im Dark Mode wäre
`--color-ink` hell → weißer Text unlesbar). Umgestellt auf
`--color-panel-dark-2` (konstant dunkel, weißer Text in
beiden Modi korrekt).
2. **`customer/security.blade.php` Z. 270** — 2FA-QR-Code in
`bg-white`. Bewusst belassen (QR-Codes brauchen
schwarz-auf-weiß für Scan-Tauglichkeit), erklärender
Kommentar ergänzt.
**Was unkritisch ist (kein Fix):**
- Alle weiteren `bg-white` / `text-white`-Treffer in
`customer/dashboard.blade.php` sind im `panel-dark` Block
(konstant dunkel) oder auf `--color-accent` (Bernstein in
beiden Modi) — passt
- `admin/dashboard.blade.php` Quick-Action Hover
(`group-hover:bg-hub group-hover:text-white`) — Hub-Bg ist
in beiden Modi dunkel genug für weißen Text
- `customer/press-kits/show.blade.php` Logo-Bg `bg-white` —
bewusst, weil Firmen-Logos einen weißen Bg brauchen
- Sidebar-`dark:bg-zinc-*` Helper aus dem Starter-Kit —
Zinc-Skala ist in `portal.css` auf warmes Buchpapier
gemapped, läuft
**Außerhalb Phase 5:**
- `shared-styles.css` hat `.dark .card`, `.dark .slider-*`,
`.dark .highlight-*`, `.dark .section-*` — diese sind für
den Web-Bereich (Hub-Frontend, presseecho,
businessportal24). `portal.css` importiert
`shared-styles.css` **nicht** — keine Kollision.
- Web-Frontend bleibt Light-Only (per Roadmap-Definition)
**Validierung:**
- Build: `npm run build:portal` → grün
- Pint: `vendor/bin/pint --dirty --format agent` → passed
- Tests: 230/231 (1 pre-existing `ApiDocumentationTest`, kein
Bezug zur UI-Migration)
**Empfehlung:** Im Browser einmal User-Menü →
Erscheinung → „Dunkel" + Dashboard/Listen/Detail/Security
(QR)/Tokens visuell durchklicken für den Smoke-Test (Pest
hat keine echte Rendering-Pipeline).
Roadmap-Update:
- `03-WEITERE-PHASEN.md` Phase 5 von „⚪ später" auf
„✅ abgeschlossen" gesetzt
- Status-Tabelle aktualisiert
- Empfehlungen verschoben: Phase 6 Auth-Cleanup +
manueller Smoke-Test nach oben
Plan-Doc: `17-PHASE-5-DARK-MODE.md`
---
## 2026-05-20 · Phase 4 · offiziell abgeschlossen ✅
Mit dem Abschluss von 4J ist Phase 4 (Listen/Detail-Pages
durchgehen) in allen 10 Sub-Päckchen 4A–4J durch:
| ID | Bereich |
|---|---|
| 4A | Press-Releases Listen (Admin + Customer) |
| 4B | Press-Releases Detail/Show |
| 4C | Press-Releases Forms (create/edit) |
| 4D | Companies (Admin) |
| 4E | Profile/Settings (Admin + Customer) |
| 4F | Restliche Admin-Bereiche (12 Module) |
| 4G | Restliche Customer-Bereiche (5 Module) |
| 4H | Customer „Meine Pressemitteilungen" Mockup-Stil |
| 4I | Admin „Pressemitteilungen" — Patterns übertragen |
| 4J | Dashboard-PM-Listen mit 4H/4I-Patterns |
**Roadmap-Cleanup**:
- `03-WEITERE-PHASEN.md` Phase 4 von „🚧 iterativ" auf
„✅ komplett abgeschlossen" gesetzt
- Phase 2 + 3 (Customer- + Admin-Dashboard) waren faktisch
schon in Phase 1 umgesetzt — Status retroaktiv auf
✅ korrigiert (mit Hinweis auf 4J-Verfeinerung)
- Neuer „Gesamt-Status"-Block in `03-WEITERE-PHASEN.md`
mit Phasen-Tabelle, Sub-Päckchen-Tabelle und konkreten
Empfehlungen für die nächsten Schritte (Phase 5 Dark
Mode > Phase 6 Auth-Cleanup > Web-Frontend-Block als
eigene Roadmap)
- Erkenntnis: Das Mockup `Veröffentlichen Tailwind.html`
ist eine **Public-Facing-Landing-Page** von
businessportal24 (Web-Frontend), nicht ein
Backend-PM-Wizard. Gehört in den separaten
Web-Frontend-Block, nicht in Phase 4.
**Verifikationsstand**:
- 230/231 Tests grün (1 pre-existing
`ApiDocumentationTest`-Fail, unverändert seit 4D)
- Build (Portal) sauber: 424 KB CSS / 16 KB JS gzipped
- Pint sauber
- 16 Plan-Dokumente in `dev/frontend/hub-flux/`
(`00`–`16` + `PROGRESS.md` + `README.md`)
---
## 2026-05-20 · Phase 4J · Dashboard-PM-Listen mit 4H/4I-Patterns
- **Anlass**: Nach 4H/4I sahen die Voll-Listen exakt wie
das Mockup aus, aber die kompakten PM-Listen in den
Dashboards waren noch im alten Stand (Badge rechts,
Sub-Zeile ohne Portal). 4J schließt diese Inkonsistenz.
- **Befund**: Beide Dashboards waren bereits in Phase 1
großzügig Hub-styled (Page-Header, KPI-Reihe,
`<x-portal.stat-card>`, `<x-portal.hint-card>`,
`panel-dark` Brand-Bridge usw.) — die Roadmap-Status
„⚪ später" für Phase 2 + 3 waren also veraltet und
wurden im Zuge dieses Päckchens auf ✅ gesetzt.
- **Plan-Dokument**: `16-PHASE-4J-DASHBOARD-LISTS.md`.
### Customer-Dashboard (`customer/dashboard.blade.php`)
- Volt: `recent` Select um `portal` + `published_at`
erweitert
- `recent`-Liste:
- Portal-Pills (`pe`/`bp`) neben dem Badge (Both → beide
Pills)
- Sub-Zeile mit `PM-{id} · Firma · Datum`
- `published_at` als Primärdatum für veröffentlichte PMs
- Badge-Mapping erweitert (`muted` für archived/draft
statt `hub`)
### Admin-Dashboard (`admin/dashboard.blade.php`)
- `recentPRs`-Liste:
- Portal-Pills neben Badge (Both → beide Pills)
- Sub-Zeile mit `PM-{id} · Firma · User · Datum`
- Badge-Mapping mit `muted` für archived/draft
- `pendingReviews`-Liste (Review-Queue):
- Row-Tinting `is-row-warn` (gelblich) für alle Items
- Inline-Action „Prüfen →" rechts oben (Link zur
Show-Page, weil Admin-Dashboard Controller+Blade ist
und keine direkte Wire-Methode hat)
- Portal-Pills unter dem Titel
- Container von `<a>` zu `<div>` umgestellt, weil zwei
Links nebeneinander (Titel-Link + Inline-Action) sonst
HTML-invalid wären
- Hover-Underline auf Titel-Link für klare Klickbarkeit
### Tests/Verifikation
- `DashboardTest` (Customer) → 5/5 grün, 21 Assertions
- Volle Suite → 230/231 grün, 1 pre-existing Fail
(`ApiDocumentationTest`)
- `npm run build:portal` → grün (424 KB CSS, +0,2 KB)
- `vendor/bin/pint --dirty` → passed
### Dateien
- `dev/frontend/hub-flux/16-PHASE-4J-DASHBOARD-LISTS.md` (neu)
- `resources/views/livewire/customer/dashboard.blade.php`
- `resources/views/admin/dashboard.blade.php`
- `dev/frontend/hub-flux/PROGRESS.md` (dieser Eintrag)
- `dev/frontend/hub-flux/03-WEITERE-PHASEN.md` (4J +
Phase 2/3 retroaktiv auf ✅)
---
## 2026-05-20 · Phase 4I · Admin „Pressemitteilungen" auf Mockup-Patterns
- **Anlass**: Direktes Folgepäckchen zu 4H — die in der Customer-Liste
entwickelten Mockup-Patterns werden auf die zentrale
Admin-Pressemitteilungen-Liste übertragen (Editorial-Workflow).
- **Plan-Dokument**: `15-PHASE-4I-ADMIN-PRESS-RELEASES.md`.
### Volt-Komponente erweitert (`admin/press-releases/index.blade.php`)
- `pressReleaseStats()` um `rejected` + `archived` Counter
erweitert (zwei zusätzliche `selectRaw` im gleichen Statement,
weiter über `AdminPerformanceCache`)
- Neue Methoden: `setView($view)` (setzt Statusfilter +
resetPage), `resetFilters()` (kompletter Reset inkl.
Entity-Lookups)
### Markup auf Mockup-Stil
- **Saved-Views-Tabs**: 6 Tabs (Alle, In Prüfung,
Veröffentlicht, Entwürfe, Abgelehnt, Archiv) mit
Counter-Pillen, `is-active`-State spiegelt `$statusFilter`
- **Active-Chips** unter Filter-Panel: 8 Filter-Typen
(Suche, Status, Portal, Sprache, Kategorie, User, Firma,
Kontakt) mit Remove-Button + „Alle zurücksetzen"-Link
- **Tabelle umgestellt** (8 → 7 Spalten):
- Status + Inline-Action (Freigeben/Ablehnen für Review,
Archivieren für Published) — Inline-Actions sind
`flux:modal.trigger` für die bestehenden, test-kritischen
Modals
- Titel mit Sub-Zeile (PM-ID + Firma + Sprache, klickbar)
- Portal-Pills (presseecho/businessportal24, bei
`Portal::Both` beide nebeneinander)
- Kategorie (truncate)
- Datum mit Status-Kontext-Sub („veröffentlicht · HH:MM",
„eingereicht · HH:MM", …) und `published_at` als
Primärdatum wenn vorhanden
- Hits monospace
- Aktionen-Spalte rechts reduziert auf view + edit
(Status-Actions wandern in die Status-Zelle)
- **Row-Tinting**: review → `is-row-warn`,
rejected → `is-row-err`
- **Empty-State 2-stufig**: „mit Filter" → Reset-CTA,
„ohne Filter" → Anlegen-CTA
### Was unangetastet bleibt (Test-kritisch)
- `publish()`, `reject()`, `archive()`, `sort()`,
`with()`, alle `clearXFilter()`, `resetEntityFilters()`
- 3 Modals mit Strings „Pressemitteilung veröffentlichen?",
„Pressemitteilung ablehnen?", „Pressemitteilung
archivieren?" — werden weiter vom Markup gemountet,
jetzt zusätzlich via Inline-Action triggerbar
- Combobox-Lookups für User/Firma/Kontakt (Schema +
Verhalten unverändert)
### Pitfall + Fix
- `@php(...)` Inline-Form kompilierte zu `<?php($var = ...)`
ohne Whitespace → PHP-Syntax-Fehler trotz balancierter
Klammern. Workaround: alle drei Inline-`@php(...)` zu
Block-`@php ... @endphp` umgewandelt.
### Verifikation
- `npm run build:portal` → grün (424 KB CSS, +5 KB ggü. 4H)
- `vendor/bin/pint --dirty` → passed
- Gezielt: `AdminPressReleaseActionsTest` +
`PressReleaseWorkflowTest` → 16/16 grün, 52 Assertions
- Volle Suite: 230/231 grün, 1 pre-existing Fail
(`ApiDocumentationTest` — fehlende `docs/api/v1.yml`,
unverändert seit 4D), 3 skipped, 1212 Assertions
### Dateien
- `dev/frontend/hub-flux/15-PHASE-4I-ADMIN-PRESS-RELEASES.md` (neu)
- `resources/views/livewire/admin/press-releases/index.blade.php`
- `dev/frontend/hub-flux/PROGRESS.md` (dieser Eintrag)
- `dev/frontend/hub-flux/03-WEITERE-PHASEN.md` (4I-Eintrag)
---
## 2026-05-20 · Phase 4H · Customer „Meine Pressemitteilungen" auf Mockup
- **Anlass**: Nach Abschluss von 4F entschied sich der User
bewusst gegen die nächste Roadmap-Phase und für **detail-tief
in das wichtigste Customer-Arbeitstool** zu gehen. Vorlage:
`dev/frontend/tailwind_v3/User Pressemitteilungen presseportale.html`.
- **Plan-Dokument**: `14-PHASE-4H-PRESS-RELEASES-MOCKUP.md`.
### Hub-CSS erweitert (`resources/css/shared/hub-components.css`)
Neue Komponenten — alle aus Tokens, KEINE Hex-Literale:
- `.counter-strip` + `.seg` (mit `is-ok`, `is-warn`, `is-err`, `is-muted`) + `.sep`
- `.view-tabs` + `.view-tab` (mit `is-active`, `cnt`-Pille)
- `.filter-chip` (mit `is-active`, `caret`)
- `.active-chip` (mit `x`-Remove-Button)
- `.portal-pill` (mit `pe` + `bp` Dot-Varianten, nutzt
`--color-bridge-presseecho` / `--color-bridge-businessportal`)
- `.inline-action` (mit `warn` + `err` Varianten)
- `.is-row-warn` + `.is-row-err` (Row-Tinting via
`color-mix` aus Status-Soft-Token gegen Card-Background)
- `.empty-stage` + `.empty-ico` (mit `warm` + `err` Varianten)
+ `.empty-title` + `.empty-sub`
- `.badge.muted` (neue Variante neben `ok`, `warn`, `err`, `hub`)
### Volt-Komponente erweitert (`customer/press-releases/index.blade.php`)
- Aggregierte `statusCounts` (assoc) per `groupBy('status')`
über dieselbe `$base`-Query — eine zusätzliche SQL-Query
- Neue Properties: `$portalFilter`
- Neue Methoden: `setView($status)`, `resetFilters()`,
`updatedPortalFilter()`
- Daten an View: `statusCounts`, `portalOptions`
- Paginierung von 100 → 25 (sinnvoller für Mockup-Layout)
### Markup auf Mockup-Stil (~50 % → ~90 %)
- **Counter-Strip im Header**: dynamische Segmente werden nur
angezeigt, wenn Count > 0, mit semantisch eingefärbten
Zahlen (ok/warn/muted/err)
- **Kontext-Hinweis**: „Gefiltert auf :company" als kleine
Sub-Zeile, falls Firma-Kontext aktiv (Test-kompatibel!)
- **Saved-Views-Tabs**: 6 Tabs (Alle, Veröffentlicht,
Entwürfe, In Prüfung, Abgelehnt, Archiv) mit `cnt`-Pille,
klicken setzt `statusFilter` via `setView()`
- **Filter-Sektion**: Suche + Portal-Select + Firma-Select
(letzteres nur wenn `hasGlobalCompanyContext`)
- **Active-Chips**: entfernbare Anzeige aller aktiven Filter
(Status, Portal, Firma, Suche), mit `Alle zurücksetzen`-Link
- **Tabelle**:
- Status-Spalte mit Hub-Badge + Inline-Action „Zur Prüfung →"
für Drafts (ruft `submitForReview` mit `wire:confirm`)
- Titel mit Hub-Style-Link + PM-{id}-Sub
- Portal-Pills (eine oder zwei, abhängig vom Portal-Enum-Wert)
- Firma als Hub-Link oder „— keine —" italic
- Datum: Mono-Font + Sub mit Status-Kontext
(„veröffentlicht · 09:12", „eingereicht · 17:48" …)
- Row-Tint via `is-row-warn` (review) / `is-row-err`
(rejected) — dezent beim Hover
- **3-fach Empty-State**:
- `empty-search` (Suche ohne Treffer)
- `empty-filter` (Filter ohne Treffer, warm-Icon-Box)
- `empty-none` (gar keine PMs, mit 3-Schritt-Onboarding
01-Firma · 02-Verfassen · 03-Zur Prüfung)
- **Status-Aktionen-Legende**: `panel-warm` mit 5-Spalten-
Grid (Entwurf, In Prüfung, Veröffentlicht, Abgelehnt,
Archiviert) und einer Action-Liste je Status
### Was bewusst NICHT umgesetzt wurde
- **Bulk-Selection**: weggelassen (keine Bulk-Actions im
Backend → wäre nur Dekoration ohne Funktion)
- **Inline-Action „Grund ansehen →"** für Rejected: keine
`rejection_reason`-Spalte in `press_releases`-Tabelle
(Grund wird nur via E-Mail an Autor versendet)
- **Spalten- & Export-Buttons** im Header: keine Backend-
Implementierung, weggelassen
- **Modals und Bestätigungs-Flows**: bleiben FluxUI
- **Volt-Logik außerhalb der Erweiterungen**: unangetastet
### Tests & Hygiene
- **Erst-Fail**: `CustomerCompanyContextTest:79` rot, weil
„Gefiltert auf Alpha GmbH" im neuen Layout vom Counter-Strip
verdrängt wurde
- **Fix**: Kontext-Hinweis als zusätzliche kleine Sub-Zeile
unter dem Counter-Strip, immer sichtbar wenn Firma-Kontext
- **PR + Customer Tests**: 50/50 grün (199 Assertions)
- **Volle Suite**: 230 grün (1212 Assertions), 3 skipped,
1 fail = pre-existing `ApiDocumentationTest` (kein Bezug zu UI)
- **Build**: `npm run build:portal` clean
- **Pint**: `vendor/bin/pint --dirty` → `passed`
- **Lints**: keine Errors
### Status
- Plan-Status: ✅ Phase 4H **abgeschlossen**
- 03-WEITERE-PHASEN.md: 4H ergänzt als ✅
- Match zum Mockup: ≥ 90 %
### Übertragbar auf
- `admin/press-releases/index.blade.php` (Phase 4I als
natürliche Folgephase)
- `admin/users.blade.php`, `admin/contacts/index.blade.php`,
`admin/companies/index.blade.php` (Counter-Strip,
Saved-Views-Tabs, Filter-Chips wären überall sinnvoll)
---
## 2026-05-20 · Phase 4F · Restliche Admin-Bereiche
- **Anlass**: User „4f weiter" nach 4G. Siebtes (und letztes
großes) Päckchen aus Phase 4. Ziel: alle übrigen Admin-Pages
auf Hub-Stil, damit die komplette interne Strecke visuell
abgeschlossen ist.
- **Plan-Dokument**: `13-PHASE-4F-ADMIN-REST.md`.
Aufgrund des Umfangs (~7.500 Z. Blade) in 4 Sub-Päckchen
aufgeteilt.
### 4F-1 · Stammdaten & Switcher
- **`admin/presets/{index,create,edit}.blade.php`** +
`partials/form-fields.blade.php`: Page-Header
(„Admin Backend"-Pille, Eyebrow „Administration · Presets"),
Filter-Panel, Table-Panel mit Hub-Badges und Hub-Empty-State,
Forms in `article.panel`, Required-Marker auf
`text-[color:var(--color-err)]`.
- **`admin/categories/{index,create,edit}.blade.php`**:
Page-Header mit Aktion, KPI-Reihe mit
`<x-portal.stat-card>` (gesamt, aktiv, mit/ohne PMs),
Filter & Sort Panel, Category-Cards als `article.panel`,
Hub-Badges, Hub-Style innere Items, Danger-Zone mit linkem
roten Strip.
- **`admin/portal-switcher.blade.php`** (Sidebar):
Token-basierte Button-Farben mit `--color-bg-elev`,
`--color-bg-rule`, `--color-ink`, `--color-ink-2`,
`--color-ink-3`.
- **Tests**: `CategoryIndexPerformanceTest`,
`AdminCategoryManagementTest`,
`AdminPresetManagementTest` — alle grün.
### 4F-2 · Pressekontakte
- **`admin/contacts/index.blade.php`** (729 Z.): Page-Header
mit Action, KPI-Reihe (`<x-portal.stat-card>`),
Filter-Panel, Preset-Panel, Table-Panel mit Hub-Badges und
Hub-Empty-State, Hub-Style Flash-Boxen.
- **`admin/contacts/create.blade.php`** (275 Z.):
Page-Header mit „prefilled company"-Badge, Forms in
`article.panel`.
- **`admin/contacts/edit.blade.php`** (352 Z.):
Page-Header mit ID + Portal-Badge, Forms in
`article.panel`, Danger-Zone mit linkem roten Strip.
### 4F-3 · Operations & Finance
- **`admin/footer-codes/{index,create,edit}.blade.php`**:
Page-Header, KPI-Reihe, Filter-Panel, Table-Panel mit
Hub-Badges, Forms in `article.panel`, Category-Checkboxes
Hub-styled, Danger-Zone.
- **`admin/reports/slow-requests.blade.php`** +
`slow-requests-table.blade.php`: Page-Header,
Filter-Panel mit Reset-Button, KPI-Reihe, Top Routes/Paths
Panels, Slowest-Requests-Table, Frequent Slow Queries Table,
EXPLAIN Top Slow Queries Panel — alles Hub-styled.
- **`admin/invoices/index.blade.php`** (Legacy-Archiv):
Page-Header mit Archive-Badge, Warning-Box für „unmapped",
KPI-Reihe, Filter-Panel, Table-Panel mit Hub-Badges +
Pagination.
- **`admin/coupons/index.blade.php`** (Stub): Page-Header
„Vertagt"-Badge, Info-Panel mit Hub-Style List-Items.
- **`admin/payments/index.blade.php`** (Stub): Page-Header
„In Vorbereitung"-Badge, Info-Panel mit Hub-Style
List-Items + Rules.
- **Tests**: `AdminFooterCodeManagementTest`,
`AdminSlowRequestReportTest`,
`AdminSlowRequestLoggingTest`,
`AdminLegacyInvoiceArchiveTest` — alle grün.
### 4F-4 · User-Verwaltung
- **`admin/roles/{index,create,edit}.blade.php`**:
Page-Header (mit ID + System-Role-Badges in edit),
Warning-Box für System-Rollen, Forms in `article.panel`,
Table-Panel mit Hub-Badges + Empty-State.
- **`admin/newsletter/sync.blade.php`** (171 Z.):
Page-Header mit Sync-Status-Badge (active/deactivated),
Action-Buttons (Dry Run, Test-Sync) im Header, Hub-Style
Info/Success-Pillen für Notifications, KPI-Reihe mit
`<x-portal.stat-card>` (gesamt, bestätigt, ausstehend,
abgemeldet), Config-Details (Provider, Timeout, Endpoint)
als Definition-List in `article.panel`.
- **`admin/users.blade.php`** (939 Z.): Page-Header mit
Action „Benutzer anlegen", KPI-Reihe (gesamt, aktiv,
inaktiv), Filter-Panel mit Reset-Button, Table-Wrapper
als `article.panel` mit Hub-Empty-State. **Modal**
und alle Tabellen-Inhalte bewusst unangetastet — wegen
Test-Strings + Komplexität.
- **`admin/users/show.blade.php`** (239 Z.): Hub-Header mit
ID + Status-Badges, KPI-Reihe (Portal, Typ, Status, Login),
Rollen-Panel, Rechnungsadresse-Panel,
„Verknüpfte Firmen & Kontakte"-Panel als verschachtelte
Hub-Boxes.
- **`admin/users/create.blade.php`** (421 Z.): Hub-Header,
Forms in `article.panel` (Basisdaten, Rollenzuweisung,
Firmenverknüpfung, Rechnungsadresse), Action-Panel
am Ende.
- **`admin/users/edit.blade.php`** (1.224 Z.): Hub-Header
mit ID/Portal/Status-Badges, Notification als
Hub-Style Ok-Pill, Quick-Nav als Token-Pillen mit
Hover auf Hub-Blue, KPI-Reihe (Account, Legacy-Profil,
Verknüpfungen, Rechnungsadresse). Innere Sektionen
(`#account`, `#legacy-profile`, `#roles`,
`#company-links`, `#contact-links`, `#billing-address`)
bleiben `flux:card` (IDs für Quick-Nav, sehr großes File).
Footer-Action-Panel auf Hub umgestellt.
- **Tests**: `UserManagementTest`, `UserImpersonationTest`,
`UserList*Test` — 29 Tests / 270 Assertions grün.
### Bauplatz-Hygiene
- **Build**: `npm run build:portal` — sauber durch.
- **Pint**: `vendor/bin/pint --dirty` — `passed`.
- **Lints**: keine Linter-Errors in den editierten Blade-Files.
- **Pre-existing**: `ApiDocumentationTest` weiterhin rot, kein
Bezug zu UI-Styling (siehe frühere Phasen).
### Abgrenzung — was bewusst NICHT angefasst wurde
- Volt-Logik in allen Dateien (PHP, `mount`, `save`,
`with`, …).
- `<flux:input>`, `<flux:select>`, `<flux:checkbox>`,
`<flux:textarea>`, `<flux:field>`, `<flux:error>`,
`<flux:table.*>`, `<flux:button>`, `<flux:modal>`.
- Innere Sektionen von `users/edit.blade.php` mit ID-Ankern
(Quick-Nav-Targets) — diese bleiben `flux:card`, da
Footnote-Logik daran hängt und das File 1.224 Z. groß ist.
- Modal in `users.blade.php` und alle internen Bestätigungs-
Flows (Test-Strings).
- Test-relevante Strings überall.
### Status
- Plan-Status: ✅ Phase 4F **abgeschlossen**.
- 03-WEITERE-PHASEN.md: 4F auf ✅ aktualisiert.
---
## 2026-05-20 · Phase 4G · Customer Portal (Mein Bereich)
- **Anlass**: User „weiter 4G" nach 4E. Sechstes Päckchen aus
Phase 4: alle übrigen Customer-Pages auf Hub-Stil bringen,
damit die komplette User-sichtbare Strecke (Mein Bereich)
visuell abgeschlossen ist.
- **Plan-Dokument**: `12-PHASE-4G-CUSTOMER-PORTAL.md`.
- **Was umgebaut wurde**:
- **`customer/company-switcher.blade.php`** (Sidebar-Helper,
91 Z.): „Aktive Firma"-Label als `.badge hub dot`,
Portal-Suffix als Token-Eyebrow, „Keine Firma zugeordnet"
als `.badge warn`. `<flux:select>`, `Firma öffnen`-Button
und `route('me.press-kits.show', …)` bleiben — alles, was
der `CustomerCompanyContextTest` assertiert, ist erhalten.
- **`customer/bookings.blade.php`** (Coming-Soon, 52 Z.):
Hub-Page-Header („User Backend"-Pille,
„Mein Bereich · Finanzen"-Eyebrow, Warn-Pille
„In Vorbereitung"). Info-Box auf Hub-Soft-Token,
3 Feature-Panels mit Eyebrow + Beschreibung.
- **`customer/invoices.blade.php`** (194 Z.): Page-Header
mit Aktion „Rechnungsadresse im Profil pflegen". Hinweis
in eigenes `.panel`. 4 KPI-Cards (primary/muted/ok/warn).
Filter-Panel, Tabellen-Panel mit Hub-Badges (`ok dot`
für bezahlt, `warn dot` für offen), Empty-State als
Icon-Box. Pagination am Boden im Panel mit Top-Border.
Notification als Hub-Warn-Pille mit Icon.
- **`customer/tokens.blade.php`** (212 Z.): Hub-Page-Header
mit „API-Dokumentation"-Aktion. Flash-Boxen (success/warn)
in Token-Style. „Neuer Token"-Anzeige als eigenes Panel
mit linkem Warn-Strip (`border-left:3px solid
--color-warn`) + `.badge warn`-„Nur jetzt sichtbar". Form
in Panel mit Border-Top-getrenntem Submit-Bereich.
Tabelle in Panel mit Counter, Berechtigungen als
`.badge hub` (statt `flux:badge`), Empty-State als
Icon-Box.
- **`customer/press-kits/index.blade.php`** (119 Z.):
Hub-Page-Header. Filter-Panel. Karten-Grid mit
`.panel`-Karten: `.panel-head` mit Status-Badge
(`ok dot` / `err dot`), Body mit Slug, Portal/Rolle/
Footer-Badges, KPI-Boxen (Border + bg-elev), Footer
mit Border-Top + „Firma öffnen"-Button.
Empty-State als full-width Panel mit Hub-Icon-Box.
- **`customer/press-kits/show.blade.php`** (734 Z. → Polish):
Großes Detail-Cockpit komplett auf Hub:
- **Header**: Pillen-Reihe (User-Backend, Mein
Bereich · Firma, Aktiv/Inaktiv, Portal, Rolle, ggf.
Footer-Code-aus) + Logo-Box (oder Hub-Icon-Box) + H1
+ Slug. Aktionen rechts: Zurück, Stammdaten bearbeiten,
Neue PM.
- **Quick-Nav**: Anker-Links als pillen-artige
Hover-Buttons mit Bottom-Border.
- **4 KPI-Cards**: PMs (primary), Pressekontakte (ok),
Portal (muted), Deine Rolle (muted) — mit
`canManageCompany`-abhängiger Trend.
- **Stammdaten-Panel**: `.panel-head` mit Bearbeiten-
Button. Inline-Form als `bg-elev`-Block mit
Border-Top-getrennten Sections (Logo / Aktionen).
Daten-Liste als `<dl>` mit Token-Labels + Werten,
Website als Hub-Underline-Link.
- **Pressekontakte-Panel**: `.panel-head` mit Counter.
Inline-Form analog Stammdaten. Kontakt-Items als
`bg-elev`-Boxen mit Aktionen rechts. Empty-State als
gestrichelte Box. Flash-Messages
(„Pressekontakt wurde angelegt./aktualisiert./
gelöscht.") in Token-Success-Pille.
- **Pressemitteilungen-Panel**: Tabelle mit Hub-Status-
Badges (ok/warn/err/hub). Empty-State Hub-Icon-Box.
- **Abrechnung & Statistik**: 2 Panels nebeneinander
mit „In Vorbereitung"/„Später"-Warn-Pillen. Abrechnung
mit gestrichelter Hint-Box. Statistik mit
2 Token-Mini-Stats.
- **Was bewusst unverändert blieb**:
- Volt-PHP-Logik in allen Dateien (mount, saveCompany,
saveContact, deleteContact etc.).
- Flash-Strings („Stammdaten wurden gespeichert.",
„Pressekontakt wurde angelegt./aktualisiert./gelöscht.",
„Token wurde erstellt", „Token wurde widerrufen.",
„API-Tokens werden erst freigeschaltet" etc.) —
bleiben in Volt-PHP wie zuvor und erscheinen in den
neuen Hub-Pillen.
- Section-Headings „Abrechnung" und „Statistik" — Tests
assertieren genau diese Strings.
- Strings im Header („Alpha GmbH", „Firma öffnen",
`route('me.press-kits.show', …)`).
- FluxUI-Form-Komponenten (`flux:input`, `flux:select`,
`flux:textarea`, `flux:checkbox`, `flux:field`,
`flux:error`, `flux:table*`) — nur Wrapper-Markup
verändert.
- **Verifikation**:
- `php artisan view:clear` ✓
- `npm run build:portal` ✓ — 418.11 kB CSS / 44.38 kB JS
(keine Größenänderung gegenüber 4E).
- `php artisan test --compact tests/Feature/{
CustomerPortalTest, CustomerCompanyContextTest,
PanelConsolidationTest}.php` →
**29 passed, 131 assertions**.
- Volle Suite: **230 passed, 3 skipped, 1 pre-existing
fail** (`ApiDocumentationTest` — fehlende
`docs/api/v1.yml`, war auch vor 4G/4E/4D rot).
- `vendor/bin/pint --dirty --format agent` → `passed`.
- **Resultat**:
- Mein-Bereich des Users ist visuell **vollständig** auf
Hub-Sprache.
- Sidebar-Nav (presse-kits, invoices, tokens, bookings)
läuft jetzt durchgängig im selben Vokabular wie Dashboard
+ Press-Releases.
- Detail-Cockpit `press-kits/show` ist das visuell
aufwendigste Customer-Page und stimmt jetzt mit Admin-
Detail-Show überein (Pillen-Header, KPI-Reihe, Panels,
Quick-Nav, Tabellen).
- **Nächste mögliche Päckchen**:
- **4F** Restliche Admin-Bereiche (contacts, categories,
presets, footer-codes, slow-requests, users).
- **press-release-images-manager** Komponente (kleiner
Cleanup aus 4C-Resten).
- **Phase 5** Dark-Mode-Konsolidierung.
---
## 2026-05-20 · Phase 4E · Profile & Settings
- **Anlass**: User „okay weiter" nach 4D. Fünftes Päckchen aus
Phase 4: alle Settings-Pages (Admin + Customer) auf Hub-Stil.
- **Plan-Dokument**: `11-PHASE-4E-PROFILE-SETTINGS.md`.
- **Zentraler Trick — Wrapper umgebaut**:
- **`resources/views/partials/settings-heading.blade.php`**:
Komplett neu als Hub-Page-Header (Pille „Admin Backend",
Eyebrow „Mein Konto · Einstellungen", H1 „Settings",
Subtitle).
- **`resources/views/components/settings/layout.blade.php`**:
Komplett neu als 2-Spalten-Grid mit Sidebar-Nav-`.panel`
(„Mein Konto"-Eyebrow + FluxUI-Navlist drin) und
Content-`.panel` mit `.panel-head` für Page-Heading +
Subheading im Body. Heading/Subheading-Slots der einzelnen
Settings-Pages werden so automatisch im Hub-Look gerendert.
- **Effekt**: `settings/appearance.blade.php` musste
**gar nicht** angefasst werden — übernimmt den Hub-Look
via Wrapper. Die anderen beiden brauchen nur
Save-Bar-Polish.
- **Was umgebaut wurde**:
- **`settings/profile.blade.php`**: Verification-Hinweis von
`<flux:text>`-Link auf Hub-Warn-Box (gelber Linker Strip,
Icon, Hub-Link für „re-send the verification email").
Save-Bar mit Border-Top + Token-`Saved.`-Pill.
Delete-Button-Section visuell durch Border-Top abgetrennt.
- **`settings/password.blade.php`**: Save-Bar gleicher Polish.
- **`settings/delete-user-form.blade.php`**: Das `mt-10`-Card
durch Hub-Danger-Box mit `border-l-[3px]
border-l-[color:var(--color-err)]`, „Danger Zone"-Eyebrow,
H3 + Subtitle + Trash-Button. Modal-Markup komplett
unverändert (Confirm-Password-Modal kommt aus FluxUI-Std.).
- **`customer/profile.blade.php`**: Page-Header („User
Backend"-Pille, „Mein Bereich · Profil"-Eyebrow,
„Mein Profil"-H1). Form in 3 Panels + Aktions-Panel:
Konto (Name/E-Mail/Sprache) · Profil (Anrede,
Vor-/Nachname, Telefon, Backlink, Checkboxen) ·
Rechnungsadresse (mit Warn-Hub-Box, wenn unvollständig).
Zugeordnete-Firmen als eigenes `.panel` mit Hub-Badges
(`ok` für Eigentümer, `hub` für Portal/Rolle).
- **`customer/security.blade.php`**: Page-Header. 4-spaltige
KPI-Reihe mit `.panel` + uppercase-Eyebrow + großer Wert +
Hub-Badge (E-Mail bestätigt? · 2FA aktiv? · Letzter Login +
IP · Sessions-Count). 2-Spalten-Grid für Passwort + E-Mail
in `.panel` mit `.panel-head`. 2FA-`.panel` mit
ok-Badge im Header wenn aktiv, Recovery-Codes mit
Hub-Bg-Boxes. Sessions-`.panel` mit Eintrags-Counter,
Empty-State als Hub-Icon-Box. **Alle Test-Strings
erhalten**: „Konto-Sicherheit", „Letzter Login",
„Aktive Sessions", „Passwort ändern", „E-Mail-Adresse
ändern", „Zwei-Faktor-Authentifizierung",
„Rechnungsadresse".
- **Tests**:
- Smoke: `Settings|CustomerProfileSecurity|
CustomerCompanyContext` → 33 passed (146 assertions).
- Volle Suite: 230 passed / 3 skipped /
1 pre-existing `ApiDocumentationTest`-Fail.
- **Build / Pint**: `npm run build:portal` ✓ (418 kB CSS),
`pint --dirty` ✓, keine Linter-Errors.
- **Bewusst NICHT angefasst**:
- Volt-Logik in allen Dateien.
- Confirm-User-Deletion-Modal-Markup
(`settings/delete-user-form.blade.php`).
- Fortify-2FA-Logik (Enable / Disable / Recovery-Codes-
Regenerate / QR-Generation).
- `<x-action-message>` Component-Wrapper — nur Slot-Inhalt.
- **Nächster Schritt** — Vorschlag:
- **4G** Customer-Bereiche (invoices, tokens, bookings,
company-switcher, me/press-kits/*) — Tests fordern
Strings, aber alle gut greifbar.
- **4F** Restliche Admin-Bereiche (contacts, categories,
presets, footer-codes, slow-requests, users) — größeres
Päckchen, sollte weiter unterteilt werden.
---
## 2026-05-20 · Phase 4D · Companies (admin)
- **Anlass**: User „okay weiter" nach 4C. Viertes Päckchen aus
Phase 4: alle vier Admin-Companies-Pages auf Hub-Stil.
- **Plan-Dokument**: `10-PHASE-4D-COMPANIES.md`.
- **Was umgebaut wurde**:
- **`admin/companies/index.blade.php`**: Hub-Page-Header
(„Admin Backend"-Pille, Eyebrow „Stammdaten · Firmen",
H1 „Firmen", Subtitle, CTA „Neue Firma" rechts) →
3 `<x-portal.stat-card>` (Gesamt/Aktiv/Inaktiv) →
Filter-`.panel` mit Combobox-Selects unverändert in der
Logik, nur Hülle getauscht → Tabelle in `.panel
overflow-hidden` mit `.panel-head` „Alle Firmen" +
Eintrags-Counter. Tabellen-Status/Portal/Count-Badges
auf Hub-Klassen (`badge ok|err|hub` + Dot) gesetzt.
Empty-State als Hub-Icon-Box.
- **`admin/companies/show.blade.php`**: Header mit
Status-, Portal- und ID-Pille; Logo-Box neben H1. KPI-Reihe
(3 stat-cards). Tabs „Überblick" / „Kontakte" als schlankes
Bottom-Border-Pattern (kein FluxUI-Tabs-Group nötig). Beide
Tab-Inhalte komplett in `.panel`-Sektionen mit `dl`-Layouts
bzw. Kontakt-Karten. Existing-Contact-Combobox bleibt
FluxUI; Wrapper auf Hub-`bg-elev`. Flash-Boxen
(success/error/info) auf Token-Pillen.
- **`admin/companies/edit.blade.php`**: Page-Header
(„ID"-Pille), 5 Form-Panels (Basisinformationen, Adresse,
Rechtliche Daten, Logo & Status, Aktionen). Required-Marker
auf `text-[color:var(--color-err)]`. Logo-Vorschau-Bild
nutzt Hub-Token-Border. „Logo wird beim Speichern entfernt"
auf Hub-Warn-Box (statt `flux:callout`).
**Delete-Confirm-Modal komplett unverändert.**
- **`admin/companies/create.blade.php`**: gleiches Schema
wie Edit, ohne Status-Pille und ohne Delete-Button. Forms
in 5 Panels strukturiert.
- **Tests**:
- Companies-Smoke: `UserManagement|PortalAssetManifest`
→ 25 passed (227 assertions).
- Volle Suite: 230 passed / 3 skipped /
1 vorbestehender Fail (`ApiDocumentationTest` —
fehlende Datei `docs/api/v1.yml`, nicht durch Phase 4D
verursacht).
- **Build / Pint**: `npm run build:portal` ✓ (418 kB CSS,
44 kB JS), `vendor/bin/pint --dirty --format agent` ✓.
- **Bewusst NICHT angefasst**:
- Volt-Logik in allen vier Dateien.
- `deleteCompany`-Methode und ihr Confirm-Modal-Markup
(Test `UserManagementTest::admin can delete company`
prüft Redirect-Verhalten, nicht UI).
- `<flux:select variant="combobox">` (Kontakt-/User-Lookup)
und alle anderen `flux:field`/`flux:input`-Bausteine —
Token-Bridging trägt.
- Test-relevante Strings: „Firmen", „Portal", „Alle Portale",
„Presseecho", „Businessportal24", „/admin/companies/…".
- **Nächster Schritt (Phase 4E oder 4F)**:
- **4E** = Profile/Settings (`settings.*`, `me.profile`,
`me.security`) — eher klein, viele kleine Panels.
- **4F** = Restliche Admin-Bereiche (contacts/, categories/,
presets/, footer-codes/, slow-requests, …) — Päckchen-Größe.
---
## 2026-05-19 · Phase 4C · Press-Releases Forms (create / edit)
- **Anlass**: User-Freigabe „ja" nach 4B. Drittes Päckchen aus