# Phase 8 · User-Panel-Konsolidierung & PM-Lifecycle Stand: 2026-05-29 · **abgeschlossen** Plan-Doc: [`docs/PHASE-8-USER-PANEL-PLAN.md`](../../../docs/PHASE-8-USER-PANEL-PLAN.md) Abgleich: [`docs/STATUS-ABGLEICH-USER-PANEL.md`](../../../docs/STATUS-ABGLEICH-USER-PANEL.md) Folge-Initiative nach Phase 7 (PM-Form-Refactor). Ziel: das User-Panel produktionsreif abrunden — Show-Page-Lücken, Firmen-Liste auf Mockup-Niveau, durchgängige PM-Titelbilder, rechtssichere Bild-Lizenzen und ein bewusster Veröffentlichungs-Flow mit Kontingent-Vorbereitung. ## Päckchen-Übersicht | ID | Thema | Status | |---|---|---| | 8A | Show-Page-Lücken (subtitle, scheduling, embargo, boilerplate_override) — Customer + Admin | ✅ | | 8B | Listen-Indikatoren für Scheduling/Embargo | ✅ | | 8C | Pressekontakt-Warn-Box in der Form-Sidebar | ✅ | | 8D | Doku-Sync (`docs/user-admin/*`, `STATUS-ABGLEICH`) | ✅ | | 8E | Firmen-Liste auf Mockup-Niveau (Counter-Strip, Saved-Views, Filter-Chips, Toggle, Rollen-Legende) | ✅ | | 8F | SVG-Titelbild-Platzhalter-Set + Anzeige-Komponente + Picker-Modal | ✅ | | 8G | Titelbild-Schema (`placeholder_variant`) + Cover-Resolver | ✅ | | 8H | Bild-Upload mit Lizenz-Pflichtfeldern | ✅ | | 8I | Veröffentlichungs-Modal (Rechtshinweis + Kontingent) | ✅ | | 8J | Quota-Stub im Datenmodell + monatlicher Reset-Command | ✅ | | 8K | Tests, Pint, Build, Doku-Abschluss | ✅ | ## Wichtigste Code-Artefakte (8F–8J, neu in dieser Phase) **Enums** - `app/Enums/PressReleasePlaceholder.php` — 9 SVG-Varianten (Default, Seed-deterministisch, Labels, Asset-Pfad). - `app/Enums/ImageLicenseType.php` — 5 Lizenztypen, `requiresLicenseUrl()`. **Assets / Komponenten** - `public/images/press-release-placeholders/01..09-*.svg` (1600×900, 3 Muster × 3 Hub-Farben). - `resources/views/components/portal/press-release-placeholder.blade.php` — rendert Bild/Platzhalter mit optionalem Titel-Overlay. - `resources/views/livewire/components/press-release-placeholder-picker.blade.php` — FluxUI-Modal mit 3×3-Grid, dispatcht `placeholder-selected`. **Services** - `app/Services/PressRelease/PressReleaseCoverImage.php` — `coverUrl()`, `coverIsPlaceholder()`, `placeholder()`. Bevorzugt `is_preview`-Bild, fällt sonst auf den SVG-Platzhalter zurück. **Schema (additive, nullable/Default-Migrationen)** - `press_releases.placeholder_variant` (string 32, nullable). - `press_release_images`: `author`, `license_type`, `license_url`, `persons_consent` (default false), `rights_confirmed_at`. - `users`: `press_release_quota` (default 3), `press_release_quota_used_this_month` (default 0). **Models** - `PressRelease`: Cast + `creating`-Hook setzt deterministisch eine Platzhalter-Variante, wenn keine gesetzt ist. - `PressReleaseImage`: Lizenz-Felder + `license_type`-Enum-Cast. - `User`: `pressReleaseQuotaRemaining()`. **Service-Hook & Command** - `PressReleaseService::submitForReview()` zählt `press_release_quota_used_this_month` des Autors hoch (Stub). - `app/Console/Commands/ResetMonthlyPressReleaseQuota.php` + Scheduler-Eintrag (`monthlyOn(1, '00:05')`) in `routes/console.php`. **Views** - Customer-Show + Admin-Show: Hero-Titelbild via Cover-Resolver. - Customer Create/Edit: Platzhalter-Vorschau + Picker-Einbindung (`#[On('placeholder-selected')]`). - Customer-Show: Veröffentlichungs-Modal (`confirm-submit-review`) mit Rechts-Platzhalter, Kontingent-Badge und 3 Bestätigungs-Checkboxen (Submit-Button via Alpine disabled bis alle gesetzt). - Image-Manager: Lizenz-Felder + Anzeige in der Bild-Kachel. ## Tests (neu) - `tests/Feature/PressReleasePlaceholderTest.php` (8) — Enum, Assets, Picker, Cover-Resolver (Platzhalter + echtes Bild). - `tests/Feature/PressReleaseImageLicenseTest.php` (3) — Pflichtfelder, CC-ohne-URL, vollständiger Upload + `rights_confirmed_at`. - `tests/Feature/PressReleaseQuotaTest.php` (3) — Remaining-Berechnung, Increment bei Submit, monatlicher Reset. - `tests/Feature/PressReleasePublishModalPhase8iTest.php` (2) — Modal-Inhalt (Rechtshinweis + Kontingent), Submit-Flow. Gesamt-Suite nach Phase 8: **375 passed, 4 skipped**. Pint clean, `npm run build:portal` clean. ## Bewusste Abweichungen / offene Folge-Themen - **8H — Upload-Control**: `flux:input type=file` statt `flux:file-upload` (Pro-Dropzone mit aufwändigem Slot-Aufbau). Funktion identisch, kein Risiko für den Upload-Flow. Dropzone-Optik ggf. separat nachziehen. - **8I — Rechtstext** ist ein **Platzhalter** und vor Go-Live anwaltlich zu prüfen. - **8J — Quota** ist ein Stub. Die Schnittstelle `User::pressReleaseQuotaRemaining()` bleibt stabil; das echte Tarif-/Credit-Modul löst Spalten + Decrement-Logik später ab. - Offen (Phase 2/3): Stock-/KI-Bildquellen, Wasserzeichen-Check, Magic-Link-Flow für Pressekontakte, Statistik-/Abrechnungs-Tabs, Anhänge-Reaktivierung (Security-Audit).