presseportale/docs/user-admin/Umsetzung Pressemitteilung Bearbeitung Titelbild Veroeffentlichung.md
Kevin Adametz 8d8d957884 Doku: Status-Sync 11./12.06., Decision-Update Preisstruktur und Phase-9-Plan
- Decision-Update Preisstruktur & Veroeffentlichungs-Flow aufgenommen
  (Launch-Tarife, Slot-Verbrauch bei Veroeffentlichung, Submit-Gate,
  Launch-Credits) inkl. Klarstellung 12.06.: Gelb geht direkt live,
  keine manuelle Pruef-Queue, nur Rot wird abgelehnt
- Alle Status-Dokumente auf den Code-Stand gezogen: README-Index,
  STATUS-ABGLEICH (KI-Pipeline, Bilder/Lizenzen, Pricing), Checkliste
  (KI- und Titelbild-Bloecke, Launch-To-dos), Admin-User,
  user-zusammenhaenge (Datenmodell-Delta), Entwicklungsplan KI-Pruefung
  (Phase 0 abgehakt, Decision-Abgleich)
- Ueberschriebene Tarif-Abschnitte in Konzept-Update 1/2 und
  Relaunch-Konzept mit Superseded-/IST-Hinweisen markiert
- Neues Plan-Dokument PHASE-9-FLOW-UND-TARIFE-PLAN.md (9A-9J)
- Phase-8-Roadmap-Doku (20-PHASE-8-USER-PANEL.md) + PROGRESS-Eintraege

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 09:20:22 +00:00

277 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Umsetzung Pressemitteilung bearbeiten: Titelbild, Rechte, Veröffentlichung
Stand: 11.06.2026
Diese Notiz dokumentiert die zuletzt umgesetzten Anpassungen an der Bearbeitung von Pressemitteilungen im User Panel und an den parallel genutzten Admin-Formularen.
## Betroffener Bereich
- Customer Create/Edit: `resources/views/livewire/customer/press-releases/create.blade.php`
- Customer Edit: `resources/views/livewire/customer/press-releases/edit.blade.php`
- Admin Create/Edit: `resources/views/livewire/admin/press-releases/create.blade.php`, `resources/views/livewire/admin/press-releases/edit.blade.php`
- Show/Index (Customer + Admin) für die Termin-Anzeige: `resources/views/livewire/customer/press-releases/{show,index}.blade.php`, `resources/views/livewire/admin/press-releases/{show,index}.blade.php`
- Model (Zeitzonen-Konstante + Accessoren): `app/Models/PressRelease.php`
- Titelbild-Manager: `resources/views/livewire/components/press-release-images-manager.blade.php`
- Platzhalter-Auswahl: `resources/views/livewire/components/press-release-placeholder-picker.blade.php`
- Platzhalter-Dateien: `public/images/press-release-placeholders`
- Layout-CSS: `resources/css/shared/hub-components.css`
## Titelbild-Platzhalter
Die Platzhalter für Pressemitteilungs-Titelbilder wurden erweitert.
- Die Varianten werden über `App\Enums\PressReleasePlaceholder` verwaltet.
- Die SVG-Dateien liegen lokal unter `public/images/press-release-placeholders`.
- Der Picker lädt die lokalen Varianten in `resources/views/livewire/components/press-release-placeholder-picker.blade.php`.
- Das Modal wurde für mehr Varianten verbreitert und mit einer scrollbaren Grid-Darstellung versehen.
Ziel: Wenn noch kein eigenes Titelbild vorhanden ist, kann ein optisch passender Platzhalter gewählt werden.
## Titelbild-Upload
Der Upload wurde auf ein einzelnes Titelbild begrenzt.
- Es kann vorerst nur ein Titelbild pro Pressemitteilung hochgeladen werden.
- Wenn ein Titelbild vorhanden ist, wird die Platzhalter-Card ausgeblendet.
- Das Upload-Formular wird ebenfalls ausgeblendet, solange ein Titelbild existiert.
- Das vorhandene Titelbild wird in einer eigenen Bild-Card angezeigt.
- In der Bild-Card werden Titel, Größe und Bildnachweis/Copyright angezeigt.
- Das Titelbild kann gelöscht werden; danach erscheinen Platzhalter und Upload-Formular wieder.
Das Upload-Formular ist einklappbar:
- Im Ausgangszustand erscheint nur der Hinweis, dass ein Titelbild fehlt.
- Über „Eigenes Titelbild hochladen" wird das Formular geöffnet.
- Über „Abbrechen" wird das Formular wieder geschlossen und zurückgesetzt.
## Bildverarbeitung und Speicherverhalten
Die Bildverarbeitung wurde auf die Titelbild-Nutzung optimiert.
- Erlaubte Formate: JPG, PNG, WebP.
- Maximale Dateigröße: 16 MB.
- Nicht previewfähige Dateien wie TIFF lösen keine Livewire-Preview-Exception mehr aus; sie werden über die Validierung abgefangen.
- Für Pressemitteilungsbilder wird eine Cover-Variante erzeugt: 1280 x 580 px.
- Der kanonische Bildpfad zeigt auf die Cover-Variante.
- Das Original wird nach der Variantenerzeugung gelöscht, um Speicherplatz zu sparen.
- Breite und Höhe in der Oberfläche beziehen sich auf die gespeicherte Cover-Version, nicht auf das Original.
Relevante Datei: `app/Services/Image/ImageService.php`.
## Lizenz- und Rechteformular
Das Formular wurde an die Vorgaben aus `docs/user-admin/Lizenztyp Bildupload.md` angepasst.
Erfasste Felder:
- Titel / Alt-Text über das bestehende `title`-Feld.
- Öffentlicher Bildnachweis über das bestehende `copyright`-Feld.
- Urheber / Fotograf / Rechteinhaber über `author`.
- Lizenztyp über `license_type`.
- Lizenzdetails über `license_detail`.
- Lizenz-URL über `license_url`.
- Quelle / Fundstelle über `source_url`.
- Personenrechte über `people_rights_status`.
- Marken, Kunstwerke, geschützte Werke oder private Orte über `property_rights_status`.
- Interne Notizen über `rights_notes`.
- Rechtebestätigung über `rights_confirmed_at`.
Lizenztypen:
- Eigene Aufnahme
- Creative-Commons-Lizenz
- Agentur-/Stockbild-Lizenz
- Vom Urheber / Fotografen freigegeben
- Presse-/PR-Bild mit Nutzungsfreigabe
- Gemeinfrei / Public Domain / CC0
- Sonstige Lizenz / Sondervereinbarung
Wichtige Regeln:
- „Bitte wählen" ist der Ausgangszustand.
- „Unsicher" wurde aus den Auswahlmöglichkeiten entfernt.
- Am Ende muss der Uploadende die Verantwortung für die Rechte bestätigen.
- Creative-Commons-Lizenzen erfassen zusätzlich die konkrete CC-Variante.
- CC-, Stock-/Agentur- und Presse-/PR-Lizenzen verlangen eine Lizenz- oder Nachweis-URL.
- „Sonstige Lizenz / Sondervereinbarung" verlangt einen Pflicht-Freitext.
- Risikohinweise werden bei eingeschränkten oder unklaren Lizenzfällen angezeigt.
Relevante Dateien:
- `app/Enums/ImageLicenseType.php`
- `app/Models/PressReleaseImage.php`
- `database/migrations/2026_06_10_154249_add_rights_detail_fields_to_press_release_images_table.php`
- `resources/views/livewire/components/press-release-images-manager.blade.php`
## Veröffentlichung
Die Veröffentlichungs-Box wurde vereinfacht.
Sichtbar sind nur noch:
- Sofort nach Freigabe
- Geplanter Termin
Embargo / Sperrfrist wurde in den Formularen aus der Oberfläche entfernt, weil es aktuell noch keine sinnvolle Anwendung im User-Flow gibt.
Technisches Verhalten:
- `scheduled_at` bleibt erhalten und wird weiterhin gespeichert.
- `embargo_at` wird in den betroffenen Formularen nicht mehr gesetzt und beim Speichern auf `null` geführt.
- Für den geplanten Termin wird `flux:date-picker` für das Datum verwendet.
- Für die Uhrzeit wird `flux:time-picker` verwendet.
- Intern werden Datum und Uhrzeit wieder zu `scheduledAt` kombiniert.
- Der geplante Termin muss mindestens 5 Minuten in der Zukunft liegen.
- Bei zu frühem Termin wird direkt ein Fehler gesetzt; beim Speichern greift die Validierung ebenfalls.
Betroffene Properties:
- `scheduledDate`
- `scheduledTime`
- `scheduledAt`
## Zeitzonen-Handling für geplante Veröffentlichung
Stand: 11.06.2026 (nachgezogen)
Die Anwendung läuft serverseitig in UTC (`config/app.php``timezone = 'UTC'`).
Geplante Termine werden aber von Redaktion und Kunden in **deutscher Zeit**
gedacht. Vorher wurde die im Formular eingegebene Uhrzeit naiv als UTC
interpretiert, wodurch die Veröffentlichung um den Berlin-Offset (im Sommer
+2 h) verschoben stattfand. Das ist behoben.
Grundprinzip:
- Eingabe und Anzeige erfolgen in **Europe/Berlin**.
- Gespeichert wird weiterhin **UTC**.
- Wichtig: Laravel konvertiert beim Speichern **nicht** automatisch nach UTC.
Deshalb wird der eingegebene Wert beim Parsen explizit als Berlin
interpretiert und mit `->utc()` umgewandelt; beim Laden wird umgekehrt von
UTC nach Berlin gewandelt.
Zentrale Stelle:
- `App\Models\PressRelease::DISPLAY_TIMEZONE` (`'Europe/Berlin'`) ist die
Single Source of Truth.
- `PressRelease::scheduledAtLocal()` und `PressRelease::embargoAtLocal()`
liefern die Termine in der Anzeige-Zeitzone für alle Views.
Verhalten in den Formularen (Customer **und** Admin, Create **und** Edit):
- Helper `scheduledAtUtc()`: parst die naiven Eingabefelder als Berlin und
gibt den UTC-Zeitpunkt für die Speicherung zurück.
- Die „mind. 5 Minuten in der Zukunft"-Prüfung läuft jetzt über eine
zeitzonenbewusste Closure-Regel statt über die naive `after:`-Regel.
- Beim Bearbeiten (`mount`) wird `scheduled_at` von UTC nach Berlin gewandelt,
bevor Datum/Uhrzeit in die Eingabefelder gefüllt werden.
Anzeige (lokalisiert auf Berlin):
- Customer-Show/-Index und Admin-Show/-Index: geplanter Termin und Embargo
werden über `scheduledAtLocal()` / `embargoAtLocal()` ausgegeben.
Bewusst (noch) nicht umgestellt:
- `published_at`, `created_at` und die Status-Log-Zeitstempel werden weiterhin
in UTC angezeigt. Eine vollständige Anzeige-Lokalisierung dieser Felder ist
als Folgeschritt vorgesehen.
## Aufräumung: Scheduling-Logik und Queries
Im Zuge der Zeitzonen-Umstellung wurden zwei Altlasten in allen vier
PM-Formularen bereinigt:
- **Doppelte Termin-Synchronisierung entfernt:** Die Termin-Logik lief vorher
sowohl im generischen `updated()`-Hook als auch in den spezifischen
`updated{PublishMode,ScheduledDate,ScheduledTime}`-Hooks also doppelt.
`updated()` enthält jetzt nur noch die generische Re-Validierung bereits
fehlerhafter Felder; die Synchronisierung liegt ausschließlich in den
spezifischen Hooks.
- **Redundante Queries reduziert:** Im Customer-Edit wird die geladene
Pressemitteilung pro Request memoisiert (`mount()`, `with()` und `save()`
greifen sonst jeweils mit einer eigenen Query auf dieselbe PM zu).
## Responsive Layout
Das Layout der Pressemitteilungsformulare wurde entkoppelt von der globalen Sidebar-Logik.
Die globale Flux-Sidebar bleibt im stabilen Standardzustand:
- `flux:sidebar sticky stashable`
- Header- und Toggle-Sichtbarkeit weiter über `lg:hidden`
Das eigentliche Formularlayout wird über eigene Klassen gesteuert:
- `.pr-editor-layout`
- `.pr-editor-side`
Regel in `resources/css/shared/hub-components.css`:
```css
@media (min-width: 1180px) {
.pr-editor-layout {
grid-template-columns: minmax(0, 1fr) 360px;
}
.pr-editor-side {
position: sticky;
top: 1rem;
}
}
```
Verhalten:
- Unter 1180 px steht die rechte Formularbox unterhalb des Hauptinhalts.
- Ab 1180 px steht die rechte Formularbox wieder rechts.
- Die rechte Box wird ab 1180 px sticky.
- Die globale linke Navigation bleibt davon unberührt.
## Button-Varianten
Sekundäre `variant="ghost"`-Buttons in Blade-Views wurden breit auf `variant="filled"` umgestellt, weil die Ghost-Buttons optisch zu wenig als Buttons erkennbar waren.
Umfang:
- Alle Blade-Views unter `resources/views` wurden auf verbleibende `variant="ghost"` geprüft.
- Markdown-Dokumentation wurde dabei nicht als UI geändert.
## Tests und Verifikation
Ergänzte bzw. angepasste Tests:
- `tests/Feature/PressReleasePlaceholderTest.php`
- `tests/Feature/PressReleaseImageLicenseTest.php`
- `tests/Feature/CustomerPressReleaseSchedulingFormTest.php`
- `tests/Feature/Admin/AdminPressReleaseSchedulingTest.php`
Für die Zeitzonen-Umstellung zusätzlich angepasst (Assertions auf
Berlin-Werte umgestellt):
- `tests/Feature/PressReleaseShowPhase8aTest.php`
- `tests/Feature/Admin/AdminPressReleaseShowTest.php`
Zuletzt erfolgreich ausgeführte Checks:
- `php artisan test --compact tests/Feature/CustomerPressReleaseSchedulingFormTest.php tests/Feature/Admin/AdminPressReleaseSchedulingTest.php tests/Feature/Admin/AdminPressReleaseShowTest.php tests/Feature/PressReleaseShowPhase8aTest.php tests/Feature/PressReleaseIndexPhase8bTest.php`
- `vendor/bin/pint --dirty --format agent`
- Volle Suite: 400 passed (die zwei roten Tests `PressReleaseImageApiTest` und
`CustomerPressReleaseCreatePhase7Test` sind vorbestehende, unabhängige WIP-
Failures per Stash-Test verifiziert, dass sie auch ohne diese Änderungen
scheitern).
Vorher zusätzlich grün gelaufen:
- `php artisan test --compact tests/Feature/PressReleasePlaceholderTest.php tests/Feature/PressReleaseImageLicenseTest.php tests/Feature/CustomerPressReleaseEditPhase7Test.php`
- Phase-8-nahe Show-/Index-/Attachment-/Admin-Tests.
## Bewusst noch nicht umgesetzt
- Optionaler Upload von Lizenznachweisen oder Freigabe-Dokumenten.
- Reaktivierung des separaten Anhang-Managers.
- Manuelle redaktionelle Prüf-Workflows für riskante Lizenzfälle.
- Vollständige Medienbibliothek statt einzelnes Titelbild.
- Frontend-Ausgabe des Bildnachweises außerhalb der Bearbeitungsoberfläche, sofern noch nicht separat angebunden.
- Anzeige-Lokalisierung von `published_at`, `created_at` und Status-Log-Zeitstempeln (aktuell weiterhin UTC).
- Klärung/Anpassung der Auto-Publish-Policy: geplante PMs (Status `review` + fälliger `scheduled_at`) werden vom Scheduler-Command automatisch veröffentlicht ohne separate redaktionelle Freigabe. Wird in einem eigenen Schritt geprüft.