- Aktueller-Tarif-Card erscheint erst mit vorhandener Buchung; die Kontingent-Kachel zeigt nur noch echte Zahlen (kein irreführendes "Unbegrenzt" vor dem Launch-Schalter) - Tarif-Cards plakativer: Icon je Tarif, größerer Preis, Trennlinie vor den Leistungen, mehr Abstand zum größeren Buchen-Button - "Prüfung und Veröffentlichung inklusive" statt "KI-Prüfung" - "Aktive Buchungen"-Panel entfernt (redundant zum Tarif-Panel); Verlauf als eigene, durch Trennlinie abgegrenzte Sektion - Tests angepasst; Suite 519 passed / 4 skipped Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
92 KiB
Fortschritts-Log — Hub × FluxUI
Tagebuch der Umsetzung. Neue Einträge oben anfügen. Format pro Eintrag: Datum · Phase · Was wurde gemacht · Wer · Notizen
2026-06-12 · Phase 9F · Tarif-Seite + Checkout-UI ✅
- Was: „Buchungen & Add-ons" vom Credit-Konzept-Mock auf echte Daten
umgestellt: 4-Tier-Raster aus
plans(Alpine Monat/Jahr-Toggle, „2 Monate gratis"), Checkout-Buttons auf die 9E-Routen, Einzel-PM als separater No-Abo-Block, Aktueller-Tarif-Panel (Abo / Bestandstarif unbegrenzt / offene Einzelkäufe / leer) mit Kontingent-Kachel, „Abo verwalten" → Stripe Billing Portal (neue Routeme.checkout.billing-portal), aktive Buchungen + Verlauf real. Credit-Pakete/Marktplatz/Platzierungen entfernt (→ 9I bzw. Phase 2). Stripe Tax im Dashboard aktiviert („SaaS – business use", exklusiv). Feinschliff nach Review (Kevin): Aktueller-Tarif-Card nur bei vorhandener Buchung (kein irreführendes „Unbegrenzt" vor dem Launch; Kontingent-Kachel nur als echte Zahl), Tarif-Cards plakativer (Icon je Tarif, größerer Preis, Trennlinie, mehr Abstand zum Button), „Prüfung und Veröffentlichung inklusive" ohne „KI", „Aktive Buchungen"-Panel entfernt (Info steht im Tarif-Panel), Verlauf als eigene, klar abgegrenzte Sektion. - Dateien:
resources/views/livewire/customer/bookings.blade.php(Neufassung),app/Http/Controllers/CheckoutController.php+app/Services/Billing/StripeCheckoutService.php(Billing Portal),routes/customer.php. - Build/Test: Suite 519 passed / 4 skipped, Pint clean; 9 neue Tests
in
BookingsPageTest,PanelConsolidationTestauf neue Seite angepasst. - Offene Fragen: Stripe Tax + Produkt-Sync vor Relaunch im Live-Mode wiederholen.
- Nächster Schritt: 9G Tageslimit (
plans.daily_limitbeim Veröffentlichen), dann 9H Einzel-PM-Abo-Brücke, 9I Launch-Credits.
2026-06-12 · Phase 9E · Stripe-Anbindung komplett ✅
- Was: Produkt-Sync nach Stripe (Tarife + Einzel-PM, Netto-Preise,
Test-Mode), Webhook-Verarbeitung (STR-Spiegelung + Einmalkauf-Erfüllung;
Endpoint
pressekonto.com/stripe/webhookregistriert, Secret gesetzt), Checkout-Flows als Backend (me.checkout.subscription,me.checkout.single-pm; Stripe Tax viaCashier::calculateTaxes()), Slot-Logik vom Stub auf Plan-Kontingent umgestellt: Abo → Tarif-Quote, danach Einmalkauf-Verbrauch (consumed + PM-Verknüpfung), Grandfathered = unbegrenzt (Entscheidung 12.06.2026, Bestandsschutz); Stub-Spalteusers.press_release_quotaentfernt. - Dateien:
app/Http/Controllers/CheckoutController.php,app/Services/Billing/StripeCheckoutService.php,app/Listeners/ProcessStripeWebhook.php,app/Console/Commands/SyncStripePlans.php,app/Models/User.php,app/Services/PressRelease/PressReleaseService.php,routes/customer.php,config/billing.php, Buchungs-Seite (Rückmeldung), Submit-Modal/Views (Kontingent-Anzeige). - Build/Test: Suite 510 passed / 4 skipped, Pint clean; Stripe-Sync
live gegen Test-Mode gelaufen (Einzel-PM:
STRIPE_PRICE_SINGLE_PMin .env). - Offene Fragen: Stripe Tax im Dashboard aktivieren (Ursprungsadresse), sonst schlägt der Checkout fehl; Live-Mode-Sync vor Relaunch.
- Nächster Schritt: 9F Tarif-Seite/Buchungs-UI an die Checkout-Routen anbinden (Mock ablösen), danach 9G Tageslimit.
2026-06-12 · Phase 9D · Tarif-Datenmodell, Rechnungskreise & USt ✅
Zentrale Doku: docs/user-admin/Billing-und-Rechnungskreise.md.
Plan: docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md (9D ✅, 9E in Arbeit).
Tarif-Datenmodell
- Laravel Cashier ^16.5 (freigegeben),
Userist Billable, Cashier-Migrationen published + ausgeführt. plans(4 Tiers, Netto-Preise, Kontingente, Tageslimits, Seeder),single_purchases(Einzel-PM, Extra-PM, Boost, PDF-Nachweis).hasActiveBooking()prüft hybrid: Cashier-Abo ∨ bezahlter Einmalkauf ∨ aktive Legacy-Vereinbarung.
Hybride Rechnungskreise (Entscheidung 12.06.)
InvoiceNumberGenerator: atomare fortlaufende Nummern, STR- (Stripe) / MAN- (manuell); Alt-Archivlegacy_invoicesbleibt unverändert.- MAN-Fälligkeitslauf
billing:generate-manual-invoices(täglich 04:30): Periodenende → Rechnung mit Adress-Snapshot → Periode weiter.
Legacy-Migration (P6.6, Runbook entsperrt)
legacy:grandfather-subscriptions: aktive jährliche Vereinbarungen aus dem Rechnungsarchiv (22 im Test-Snapshot, 4 sofort fällig) alsgrandfatherednachuser_payment_options— Replay-fähig für den Lauf kurz vor Relaunch.
USt (Einwand 12.06.: alle neuen Preise netto; Legacy war brutto)
VatResolver: DE immer Steuer, EU nur mit USt-ID befreit (Reverse Charge + Pflichthinweisinvoices.tax_note), Drittland befreit.vat_idan Rechnungsadresse + Rechnungs-Snapshot; Netto-Ableitung der Legacy-Beträge (199 € brutto → 167,23 € netto + 31,77 € USt — Brutto bleibt für DE-Bestandskunden identisch).- Offen: VIES-Validierung, PDF-Layout, Steuerberater-Abnahme.
Verifikation: Suite 490 passed / 4 skipped (39 neue Billing-Tests über 4 Commits). Pint clean. Dry-Runs gegen Echtdaten validiert.
2026-06-12 · Phase 9 · Veröffentlichungs-Flow Block 1 (9A–9C) ✅
Plan-Doc: docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md. Grundlage:
docs/Decision-Update Preisstruktur & Veröffentlichungs-Flow.md
(+ Entscheidung 12.06.: Gelb geht direkt live).
Vorab Block 0: Repo aufgeräumt (3 Artefakt-Dateien im Root entfernt), der unkommittierte Stand vom 29.05.–11.06. in drei Commits gesichert (Vite/Multi-Domain-Infra, User-Panel/KI-Pipeline, Doku-Sync).
9A — Gelb-Routing Direkt-Live
routeByClassification(): Gelb durchläuft denselben Auto-Publish-Pfad wie Grün (autoPublishApproved()); nur Rot wird abgelehnt.- Scheduler publiziert fällige gelbe + grüne PMs; unklassifizierte bleiben als Fallback in der manuellen Queue.
9B — Slot-Verbrauch bei Veröffentlichung
- Increment aus
submitForReview()entfernt;publish()undchangeStatusFromAdmin()zählen idempotent beim erstenpublished-Übergang (Prüfung über Status-Logs). Rot kostet nichts. - Submit-Guard: Einreichen erfordert freien Slot
(
QuotaExceededException, API 422).
9C — Submit-Gate + Funnel-Fix
User::hasActiveBooking()-Stub hinterconfig/billing.php(enforce_booking, Default aus) — Tarif-Modul ersetzt nur den Rumpf.- Einreichungs-Modal zeigt ohne Buchung einen Buchungs-Hinweis mit
CTA zur Buchungs-Seite; Server-Guard (
BookingRequiredException), API antwortet 402. - Befund + Fix: Customer-Create legte PMs bei „Zur Prüfung senden"
direkt mit Status
reviewan — vorbei an Blacklist, Quota, KI und Status-Log. Jetzt: immer Draft anlegen, dannsubmitForReview().
Verifikation: Suite 451 passed / 4 skipped (9 neue Tests: Quota-Semantik, Gelb-Routing, Gate via Service/API/Modal). Pint clean.
Nächster Schritt: Review-Stopp, dann Block 2 (9D–9J: Tarif-Datenmodell, Stripe/Cashier — Dependency-Freigabe nötig, Tarif-UI, Tageslimit, Einzel-PM, Launch-Credits).
2026-05-29 · Phase 8 · User-Panel-Konsolidierung abgeschlossen (8F–8K) ✅
Abschluss von Phase 8. Die erste Hälfte (8A–8E: Show-Page-Lücken, Listen-Indikatoren, Pressekontakt-Warnung, Firmen-Liste auf Mockup-Niveau) war bereits im Commit „Optimierung der User und Admin Panels" enthalten, aber undokumentiert. Heute der zweite Block plus Doku-Sync.
Roadmap-Doc: 20-PHASE-8-USER-PANEL.md. Plan: docs/PHASE-8-USER-PANEL-PLAN.md.
8D — Doku-Sync: docs/user-admin/checkliste-user-backend.md,
docs/STATUS-ABGLEICH-USER-PANEL.md und Admin-User.md auf den
echten IST-Stand gezogen (8A–8E waren als „offen" markiert, sind
aber umgesetzt).
8F — SVG-Titelbild-Platzhalter
- 9 Varianten (3 Muster × 3 Hub-Farben) in
public/images/press-release-placeholders/. App\Enums\PressReleasePlaceholder(Default, Seed-deterministisch).<x-portal.press-release-placeholder>+ Picker-Modal (components.press-release-placeholder-picker, dispatchtplaceholder-selected).
8G — Titelbild-Schema + Cover-Resolver
- Migration
placeholder_variantaufpress_releases(nullable). - Model-
creating-Hook setzt deterministisch eine Variante. App\Services\PressRelease\PressReleaseCoverImage(coverUrl/coverIsPlaceholder).- Hero-Bild in Customer-/Admin-Show; Vorschau + Picker in Create/Edit.
8H — Bild-Upload mit Lizenz-Pflichtfeldern
- Migration:
author,license_type,license_url,persons_consent,rights_confirmed_ataufpress_release_images. App\Enums\ImageLicenseType(CC/kommerziell erzwingen Lizenz-URL).- Image-Manager: Urheber (Pflicht), Lizenztyp (Pflicht), Lizenz-URL (bedingt), Personen-Einwilligung, Rechte-Bestätigung (Pflicht).
- Abweichung: Upload-Control bleibt
flux:input type=filestattflux:file-upload(Stabilität). Lizenzerfassung vollständig.
8J — Quota-Stub (vor 8I, damit Modal darauf aufsetzt)
- Migration:
users.press_release_quota(3),..._used_this_month(0). User::pressReleaseQuotaRemaining(), Decrement inPressReleaseService::submitForReview().- Command
press-releases:reset-monthly-quota+ Scheduler (monthlyOn(1, '00:05')).
8I — Veröffentlichungs-Modal (Customer-Show)
- „Zur Prüfung einreichen" öffnet jetzt ein FluxUI-Modal statt
wire:confirm: Rechtshinweis (Platzhalter, anwaltlich zu prüfen), Kontingent-Badge, 3 Bestätigungs-Checkboxen (Submit via Alpine disabled bis alle gesetzt) → ruft das bestehendesubmitForReview().
8K — Abschluss
- Neue Tests:
PressReleasePlaceholderTest(8),PressReleaseImageLicenseTest(3),PressReleaseQuotaTest(3),PressReleasePublishModalPhase8iTest(2). - Suite: 375 passed, 4 skipped. Pint clean.
npm run build:portalclean.
2026-05-29 · Wartung · Test-Regression-Fix + Phase-7-Doku nachgezogen
Review der Gesamt-Umsetzung. Zwei Befunde behoben:
Fix — ProfileUpdateTest > profile page is displayed
Seit dem Customer-Portal-Umbau ist /settings/profile ein
Redirect auf /admin/me/profile (route me.profile), die
Profil-Pflege liegt jetzt in der Volt-Komponente
customer.profile. Der Starter-Kit-Test machte aber weiterhin
GET /settings/profile→assertOk() und lief deshalb auf 302
statt 200 (undokumentierte Regression aus dem Commit
„Optimierung der User und Admin Panels", 2026-05-22).
Test umgestellt auf assertRedirect('/admin/me/profile'). Das
Rendern der Zielseite ist bereits durch
CustomerProfileSecurityTest (Volt-Komponententest) abgedeckt,
also keine Doppelung. Die übrigen 4 Tests der Datei nutzen
weiterhin Volt::test('settings.profile') / delete-user-form
(Komponenten existieren und sind funktional).
Doku-Sync
Phase 7 war im Code vollständig umgesetzt (siehe Eintrag unten),
aber im Log nicht erfasst und in den Status-Tabellen
widersprüchlich (19-PHASE-7 „✅", 03-WEITERE-PHASEN „🟡 in
Planung", README noch auf Stand Phase 2). Nachgezogen:
- Phase-7-Eintrag in diesem Log ergänzt.
README.mdStatus-Tabelle auf Phase 0–7 aktualisiert.03-WEITERE-PHASEN.mdPhase 7 von „🟡 In Planung" auf „✅ abgeschlossen" + Gesamt-Status-Tabelle ergänzt.
Validierung:
php artisan test --compact→ 359 passed, 3 skipped, 1 failed (weiterhin nur der pre-existingApiDocumentationTest, fehlendedocs/api/v1.yml)vendor/bin/pint tests/Feature/Settings/ProfileUpdateTest.php→ fixed (EOF-Blankline)npm run build:portal→ grün (436.51 KB CSS / 58.95 KB gzip)
2026-05-22 · Phase 7 · Press-Release-Form-Refactor ✅ (retroaktiv dokumentiert)
Großes Modul-Refactor außerhalb der ursprünglichen hub-flux- Roadmap (0–6). Vorlage:
dev/frontend/tailwind_v3/User Neue Mitteilung presseportale.html. Plan-Doc:19-PHASE-7-PRESS-RELEASE-FORM.md. Dieser Eintrag wurde am 2026-05-29 nachgetragen — die Arbeit selbst entstand am 21./22.05. (Commit „Optimierung der User und Admin Panels").
7A — Migrations + Models
add_phase7_fields_to_press_releases(subtitle, boilerplate_override, scheduled_at, embargo_at — alle nullable)create_press_release_attachments_table(analog press_release_images, mit sort_order, soft-deletes)add_boilerplate_to_companies(companies.boilerplate)- Models + Factory + Relationen + Casts.
7B — Editor + Sanitizer
composer require mews/purifier ^3.4(approved)App\Services\PressRelease\PressReleaseHtmlSanitizer(Allowlist p/br/h2/h3/strong/em/u/ul/ol/li/blockquote/a)<flux:textarea>→<flux:editor>mit reduzierter Toolbar.- Test:
PressReleaseHtmlSanitizerTest.
7C/7D — Customer Create + Edit Form (UI)
- 2-Spalter mit sticky Settings-Sidebar (Status & Absenden, Portal read-only-Badge, Pressekontakt-Single-Select, Themen-Tags, Veröffentlichung, SEO).
- Linke Spalte: Firma-Selector, Titel/Untertitel mit
Counter-Pillen (
.pr-meter),flux:editor, Medien, Anhänge, Boilerplate-Box mit Override-Toggle. - Hub-Form-Bausteine in
hub-components.cssergänzt (.pr-form-label,.pr-meter,.pr-bald-badge,.pr-ai-hint,.pr-check-row,.pr-boiler,.pr-tag-chip,.pr-pub-opt…). - Live-Re-Validation (
updated()re-validiert Felder mit bestehendem Error) + Sammel-Toast bei Validierungsfehler. - Neues JS-Asset
portal-form-hooks(Build). - Tests:
CustomerPressReleaseCreatePhase7Test(8),CustomerPressReleaseEditPhase7Test(9).
7E — Anhänge-Manager
App\Services\PressRelease\PressReleaseAttachmentStorage- Komponente
livewire/components/press-release-attachments-manager.blade.php(upload/remove/reorder, PDF/DOCX/XLSX/PPTX, Tile-Layout).
7F — Scheduling + Embargo
- UI: Radio „Geplanter Termin" +
datetime-local, Embargo-Switch + Date-Picker. - Validation: scheduled_at min. 5 Min Zukunft, embargo_at Zukunft (nur wenn Toggle aktiv).
PressReleaseService::publish()→resolvePublishedAt()(published_at > scheduled_at > embargo_at-Verschiebung > now).- Command
press-releases:publish-scheduled(App\Console\Commands\PublishScheduledPressReleases,--dry-run,--limit=N) + Scheduler-Eintrag inroutes/console.php(everyFiveMinutes,withoutOverlapping,runInBackground). - Tests:
PressReleaseSchedulingTest(11),CustomerPressReleaseSchedulingFormTest(5).
Effekt auf die Suite: von dokumentierten ~231 auf ~360 Tests gewachsen. Admin-Create/Edit ziehen das Layout vorerst NUR optisch mit; Scheduling/Embargo-UI bleibt Customer-seitig (laut Plan-Doc Out-of-Scope für Admin in Phase 7).
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ünvendor/bin/pint --dirty --format agent→ passed- Tests: 230/231 (nur der bekannte pre-existing
ApiDocumentationTest)
Roadmap-Update:
03-WEITERE-PHASEN.mdPhase 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-Hovervar(--color-bg)ist dunkler als die Sidebar — wirkte als „Eindrücken" statt Hervorheben) :active,:focusexplizit aufvar(--color-hub-soft)mitoutline: none→ verhindert Browser-Default-Tap-Flash-webkit-tap-highlight-color: transparentfür mobile Browser:focus-visiblemit 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:
- JS-Bridge in
partials/head.blade.php+partials/admin-head.blade.php: wrapptwindow.Flux.applyAppearance, spiegelt den effektiv applizierten Modus (beisystemaus DOM-Klasse abgelesen →dark/light) in einflux_appearance-Cookie. Schreibt auch beim initialen Page-Load. - Server-Side Render:
<html>-Tag incomponents/layouts/app/sidebar.blade.phpundlayouts/admin-master.blade.phpsetztclass="dark"direkt, basierend auf dem Cookie:@class(['dark' => request()->cookie('flux_appearance') === 'dark']) - Bonus: hardcoded
class="dark"ausadmin-master.blade.phpraus (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.phpZ. 137:--color-ink-deepToken war nie definiert → durch--color-panel-dark-2ersetzt (konstant dunkel in beiden Modi)customer/security.blade.php2FA-QR: erklärender Kommentar fürbg-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.csshat 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 undcolor-scheme: darkportal.csshat@custom-variant dark (&:where(.dark, .dark *))- Dark-Mode-Shadow-Overrides für Primary-Buttons
hub-components.cssist 100 % token-basiertpanel-darknutzt--color-panel-dark*(konstant)@fluxAppearancein beiden Head-Partials integriert- Switcher in Sidebar (Desktop + Mobile) +
settings/appearance.blade.php
Was im Rahmen von Phase 5 gefixt wurde:
-
customer/tokens.blade.phpZ. 137 — Token-Anzeige nutzte ein nicht existentes--color-ink-deep. Damit war der Code-Block bisher transparent (im Dark Mode wäre--color-inkhell → weißer Text unlesbar). Umgestellt auf--color-panel-dark-2(konstant dunkel, weißer Text in beiden Modi korrekt). -
customer/security.blade.phpZ. 270 — 2FA-QR-Code inbg-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 incustomer/dashboard.blade.phpsind impanel-darkBlock (konstant dunkel) oder auf--color-accent(Bernstein in beiden Modi) — passt admin/dashboard.blade.phpQuick-Action Hover (group-hover:bg-hub group-hover:text-white) — Hub-Bg ist in beiden Modi dunkel genug für weißen Textcustomer/press-kits/show.blade.phpLogo-Bgbg-white— bewusst, weil Firmen-Logos einen weißen Bg brauchen- Sidebar-
dark:bg-zinc-*Helper aus dem Starter-Kit — Zinc-Skala ist inportal.cssauf warmes Buchpapier gemapped, läuft
Außerhalb Phase 5:
shared-styles.csshat.dark .card,.dark .slider-*,.dark .highlight-*,.dark .section-*— diese sind für den Web-Bereich (Hub-Frontend, presseecho, businessportal24).portal.cssimportiertshared-styles.cssnicht — 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.mdPhase 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.mdPhase 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.mdmit 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.htmlist 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-darkBrand-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:
recentSelect umportal+published_aterweitert recent-Liste:- Portal-Pills (
pe/bp) neben dem Badge (Both → beide Pills) - Sub-Zeile mit
PM-{id} · Firma · Datum published_atals Primärdatum für veröffentlichte PMs- Badge-Mapping erweitert (
mutedfür archived/draft statthub)
- Portal-Pills (
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
mutedfü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
- Row-Tinting
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.phpresources/views/admin/dashboard.blade.phpdev/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()umrejected+archivedCounter erweitert (zwei zusätzlicheselectRawim gleichen Statement, weiter überAdminPerformanceCache)- 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.triggerfür die bestehenden, test-kritischen Modals - Titel mit Sub-Zeile (PM-ID + Firma + Sprache, klickbar)
- Portal-Pills (presseecho/businessportal24, bei
Portal::Bothbeide nebeneinander) - Kategorie (truncate)
- Datum mit Status-Kontext-Sub („veröffentlicht · HH:MM",
„eingereicht · HH:MM", …) und
published_atals Primärdatum wenn vorhanden - Hits monospace
- Aktionen-Spalte rechts reduziert auf view + edit (Status-Actions wandern in die Status-Zelle)
- Status + Inline-Action (Freigeben/Ablehnen für Review,
Archivieren für Published) — Inline-Actions sind
- 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(), alleclearXFilter(),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 ... @endphpumgewandelt.
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— fehlendedocs/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.phpdev/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(mitis-ok,is-warn,is-err,is-muted) +.sep.view-tabs+.view-tab(mitis-active,cnt-Pille).filter-chip(mitis-active,caret).active-chip(mitx-Remove-Button).portal-pill(mitpe+bpDot-Varianten, nutzt--color-bridge-presseecho/--color-bridge-businessportal).inline-action(mitwarn+errVarianten).is-row-warn+.is-row-err(Row-Tinting viacolor-mixaus Status-Soft-Token gegen Card-Background).empty-stage+.empty-ico(mitwarm+errVarianten).empty-title+.empty-sub
.badge.muted(neue Variante nebenok,warn,err,hub)
Volt-Komponente erweitert (customer/press-releases/index.blade.php)
- Aggregierte
statusCounts(assoc) pergroupBy('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 setztstatusFilterviasetView() - 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
submitForReviewmitwire: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
- Status-Spalte mit Hub-Badge + Inline-Action „Zur Prüfung →"
für Drafts (ruft
- 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-warmmit 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 inpress_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:79rot, 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:portalclean - 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 inarticle.panel, Required-Marker auftext-[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 alsarticle.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 inarticle.panel.admin/contacts/edit.blade.php(352 Z.): Page-Header mit ID + Portal-Badge, Forms inarticle.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 inarticle.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 inarticle.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 inarticle.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 alsarticle.panelmit 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 inarticle.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) bleibenflux: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:
ApiDocumentationTestweiterhin 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.phpmit ID-Ankern (Quick-Nav-Targets) — diese bleibenflux:card, da Footnote-Logik daran hängt und das File 1.224 Z. groß ist. - Modal in
users.blade.phpund 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 undroute('me.press-kits.show', …)bleiben — alles, was derCustomerCompanyContextTestassertiert, 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 dotfür bezahlt,warn dotfü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(stattflux: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-headmit 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-headmit Bearbeiten- Button. Inline-Form alsbg-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-headmit Counter. Inline-Form analog Stammdaten. Kontakt-Items alsbg-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.
- Header: Pillen-Reihe (User-Backend, Mein
Bereich · Firma, Aktiv/Inaktiv, Portal, Rolle, ggf.
Footer-Code-aus) + Logo-Box (oder Hub-Icon-Box) + H1
-
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— fehlendedocs/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/showist 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-.panelmit.panel-headfür Page-Heading + Subheading im Body. Heading/Subheading-Slots der einzelnen Settings-Pages werden so automatisch im Hub-Look gerendert.- Effekt:
settings/appearance.blade.phpmusste 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: Dasmt-10-Card durch Hub-Danger-Box mitborder-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.panelmit Hub-Badges (okfür Eigentümer,hubfü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.panelmit.panel-head. 2FA-.panelmit ok-Badge im Header wenn aktiv, Recovery-Codes mit Hub-Bg-Boxes. Sessions-.panelmit 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.
- Smoke:
-
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-.panelmit Combobox-Selects unverändert in der Logik, nur Hülle getauscht → Tabelle in.panel overflow-hiddenmit.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 mitdl-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 auftext-[color:var(--color-err)]. Logo-Vorschau-Bild nutzt Hub-Token-Border. „Logo wird beim Speichern entfernt" auf Hub-Warn-Box (stattflux: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 Dateidocs/api/v1.yml, nicht durch Phase 4D verursacht).
- Companies-Smoke:
-
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 (TestUserManagementTest::admin can delete companyprüft Redirect-Verhalten, nicht UI).<flux:select variant="combobox">(Kontakt-/User-Lookup) und alle anderenflux: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.
- 4E = Profile/Settings (
2026-05-19 · Phase 4C · Press-Releases Forms (create / edit)
-
Anlass: User-Freigabe „ja" nach 4B. Drittes Päckchen aus Phase 4 — Forms (create + edit) für Admin und Customer.
-
Plan-Dokument:
09-PHASE-4C-PRESS-RELEASES-FORMS.md. -
Was umgebaut wurde (alle 4 Forms):
- Page-Header wie auf Listen und Detail: Hub-Badge
(„Admin Backend" / „User Backend") + Eyebrow + großes H1 +
Subtitle. Bei Edit zusätzlich Status-Pille im Header-Meta
(
@class([])-Syntax mitok|warn|err|hub) und „ID"-Pill. Aktions-Buttons rechts (Zurück). - Form-Sektionen als
.panelmit.panel-headundsection-eyebrow: „Inhalt", „SEO & Links", „Metadaten", „Status-Aktionen" (Admin-Edit), „Aktionen". Innenraum immerp-5 space-y-4. - Form-Felder bleiben FluxUI (
<flux:field>,<flux:label>,<flux:input>,<flux:textarea>,<flux:select>inkl. Combobox-Variant,<flux:checkbox>,<flux:error>) — das Token-Bridging aus Phase 1 zieht. - Required-Marker von
text-red-500auf Token-Farbe (text-[color:var(--color-err)]) umgestellt. - Save-/Submit-Buttons in eigenem
.panelmit Header „Aktionen" statt „nackten" Buttons in der Sidebar. - Flash-Boxen (Success/Error) auf Hub-Token-Pillen.
- Page-Header wie auf Listen und Detail: Hub-Badge
(„Admin Backend" / „User Backend") + Eyebrow + großes H1 +
Subtitle. Bei Edit zusätzlich Status-Pille im Header-Meta
(
-
Admin-Edit-spezifisch: 5 Sidebar-Panels (Status-Aktionen + Metadaten + Aktionen + Modals). „Status-Aktionen"-Panel zeigt rechts im Header die aktuelle Status-Pille — visuelle Doppelung mit dem Page-Header-Status, aber im Kontext der Sidebar sinnvoll als Vergleichs-Anker für die „Neuer Status"-Auswahl.
-
Was explizit NICHT angefasst wurde:
- Volt-Logik (alle
save/publish/reject/backToDraft/archive/changeStatus/deletePressRelease/mount/with/selectedCompany-Methoden) — Layout-only. - Confirm-Modals der Admin-Edit-Page
(
confirm-status-change,confirm-delete-press-release) — Tests inAdminPressReleaseActionsTestassertieren Wortlaute. - Wortlaute: „Neuer Status", „Status wechseln", „Status wirklich wechseln?", „Pressemitteilung löschen?", „Status wurde auf" — alle erhalten.
<livewire:components.press-release-images-manager>— eigene Komponente, kommt im jeweiligen eigenen Päckchen dran.
- Volt-Logik (alle
-
Build/Test:
npm run build:portal→ ok (portal-D0cNdOWP.css418.42 kB).- Linter clean (alle 4 Dateien).
php artisan test --compact --filter='PressRelease|CustomerCompanyContext|CustomerProfileSecurity|PanelConsolidation'→ 72 passed (310 assertions).- Volle Suite: 230 passed, 3 skipped, 1 pre-existing failure
(
ApiDocumentationTest). - Pint
--dirty --format agent→ passed.
-
Offene Fragen: Keine.
-
Nächster Schritt: Phase 4 für Press-Releases ist mit 4A/4B/4C komplett abgeschlossen. Nächstes Päckchen je nach Sichtbarkeit: 4D = Companies (
admin.companies.*) ODER 4E = Settings / Profile (me.profile,me.security).
2026-05-19 · Phase 4B · Press-Releases Detail/Show-Pages
-
Anlass: User-Freigabe „weiter" nach 4A. Zweites Päckchen aus Phase 4 — Detail/Show-Pages für Admin und Customer.
-
Plan-Dokument:
08-PHASE-4B-PRESS-RELEASES-DETAIL.md. -
Was umgebaut wurde (beide Show-Pages):
- Page-Header mit Hub-Badge + Eyebrow + Status-Pill + Sprache + Portal (Admin nur), darunter großer H1 mit dem PM-Titel und Subtitle mit Firma/Kategorie/Autor bzw. Datum. Aktions-Buttons rechts (Bearbeiten/Vorschau-Link/Zurück).
- Status-Workflow-Aktionsbar als
.panelmit.panel-headund passend gefärbtem Badge je nach Status (warn=Review, ok=Published, err=Rejected, hub=Draft). - Content-Hauptbereich (PM-Text) als
.panelmit eigenem Header „Inhalt" +prosedarunter. Keywords/Backlink darunter als Footer mit Hub-Rule. - Sidebar / Side-Cards (Admin) als kompakte
.panelmitpanel-head„Details" und „Bilder" + Hub-Badges. - Status-Verlauf-Timeline als
.panelmit Hub-Badge je Log-Eintrag (.badge.ok|warn|err|hub) statt FluxUI-color-Props. - Status-Badges in Header und Timelines komplett auf
<span class="badge …">mit@class([])-Syntax.
-
Customer-Show-spezifisch:
- Rejection-Hinweis als roter
.panelmit linker Akzent-Border (border-left-width:3px) und Icon-Box — statt<flux:callout color="red">. - Review-Pending-Hinweis als warner
.panelmit Akzent-Border und Clock-Icon-Box — statt<flux:callout color="yellow">. - Share-Link-Erfolgsblock als ok-
.panelmit Gültigkeits-Badge im Header und readonly-Input im Body. - Contacts-Liste als Hub-Items (
bg-bg-elev+border-bg-rule), Empty-State mit gestrichelter Border. - Status-Tile-Grid (Aktuell/Erstellt/Veröffentlicht/Aufrufe) als 4-er-Grid mit kleinen Hub-Tiles statt zinc-Hintergründen.
- Rejection-Hinweis als roter
-
Admin-Show-spezifisch:
- Modals (Publish/Reject/Archive) komplett unverändert —
Tests in
AdminPressReleaseActionsTestassertieren Wortlaute.
- Modals (Publish/Reject/Archive) komplett unverändert —
Tests in
-
Was explizit NICHT angefasst wurde:
- Volt-Logik (publish/reject/archive/submitForReview/ generateShareLink/with-Method) — Layout-only.
- Wortlaute „Erneut einreichen", „Werbliche Sprache wurde
markiert." aus
PressReleaseWorkflowTest. - Bestehende Modals und ihre Wortlaute.
-
Mini-Stolperer (sofort gefixt):
- Erst zwei nicht-existente Tokens (
--color-rule,--color-panel-soft) verwendet. Korrigiert zu--color-bg-ruleund--color-bg-elev(16 + 5 Vorkommen). Wäre im Browser stumm gefailed (Tailwind hätte die Klassen einfach nicht ausgegeben).
- Erst zwei nicht-existente Tokens (
-
Build/Test:
npm run build:portal→ ok (portal-Bq4pkLWt.css418.36 kB).- Linter clean.
php artisan test --compact --filter='PressReleaseWorkflow|AdminPressReleaseActions'→ 16 passed (52 assertions).- Volle Suite: 230 passed, 3 skipped, 1 pre-existing failure
(
ApiDocumentationTest, schon vor 4A bekannt). - Pint
--dirty --format agent→ passed.
-
Offene Fragen: Keine.
-
Nächster Schritt: Päckchen 4C = Press-Releases Forms (
create.blade.php+edit.blade.php, Admin + Customer). Forms sind tendenziell aufwendiger (mehr FluxUI-Felder, ggf. zusätzliche Logik wie Image-Uploads).
2026-05-19 · Phase 4A · Press-Releases Listen-Pages
-
Anlass: User-Freigabe „weiter" nach Phase 3 (Admin-Dashboard). Phase 4 ist laut Roadmap „der Marathon" über Listen-/Detail-Pages (~3–5 Tage iterativ). Wegen Umfang in Päckchen geteilt — A = Listen, B = Detail/Show, C = Forms, D = Companies, E = Settings, F = Rest.
-
Plan-Dokument:
07-PHASE-4A-PRESS-RELEASES-LISTEN.md(knapp, Scope hart auf zweiindex.blade.php-Files begrenzt, mit explizitem „NICHT in diesem Päckchen"-Block). -
Scope dieses Päckchens:
resources/views/livewire/admin/press-releases/index.blade.phpresources/views/livewire/customer/press-releases/index.blade.php
-
Was umgebaut wurde (beide Listen):
- Page-Header im Hub-Stil:
<header>mit1fr auto-Grid, Hub-Badge („Admin Backend" / „User Backend"), Eyebrow, großes H1, Subtitle, rechts der CTA-Primary-Button (FluxUI bleibt für den Button). - Filter-Bar als
.panel+.panel-headmitsection-eyebrow„Filter & Suche". FluxUI-Inputs (Search-Input, Selects, Combobox für User/Company/Contact-Lookup) bleiben unverändert — Hub hat kein eigenes Combobox-Pendant. - Tabelle als
.panelmit.panel-head„Alle Pressemitteilungen"- Eintrags-Counter rechts. FluxUI-
<flux:table>bleibt — das Zinc-→Hub-Mapping aus Phase 1 zieht hier perfekt.
- Eintrags-Counter rechts. FluxUI-
- Status-Badges:
<flux:badge color="green|yellow|red|zinc|blue">ersetzt durch<span class="badge ok|warn|err|hub">für visuelle Konsistenz mit dem Dashboard (@class([...])-Syntax). - Empty-State mit Icon-Box (
bg-[color:var(--color-hub-soft)], Hub-Border,flux:icon.newspaper) + Headline + Subtext. - Flash-Boxen auf Hub-Tokens (
--color-ok-soft,--color-err-soft,--color-gain-deep,--color-loss) stattbg-green-50etc.
- Page-Header im Hub-Stil:
-
Admin-spezifisch: Vier
<x-portal.stat-card>(Gesamt/Veröffentlicht/ In Prüfung/Entwürfe) als KPI-Reihe — identisches Layout wie Admin-Dashboard. -
Was explizit NICHT angefasst wurde:
- Confirm-Modals (Publish/Reject/Archive) — Tests in
AdminPressReleaseActionsTestassertieren die Wortlaute („Pressemitteilung veröffentlichen?" etc.) → unverändert. - Volt-Logik (Sort, Filter, alle Methods) — Layout-only.
- Confirm-Modals (Publish/Reject/Archive) — Tests in
-
Bonus-Fix:
customer/dashboard.blade.phpSubtitle bekommt einen „Übersicht für :company —"-Einschub, wenn$selectedCompanygesetzt ist. Korrigiert eine Phase-2-Regression beiCustomerCompanyContextTest > customer dashboard is filtered by …. -
Build/Test:
npm run build:portal→ ok (portal-DaL-tXm-.css418.75 kB).- Linter clean.
php artisan test --compact --filter='PressReleaseWorkflow|AdminPressReleaseActions|Dashboard|CustomerCompanyContext'→ 45 passed (163 assertions).- Volle Suite: 230 passed, 3 skipped, 1 failed.
Der einzelne Fail (
ApiDocumentationTest) ist pre-existing — viagit stashverifiziert, war auch vor diesem Päckchen rot (/docs/api/v1liefert nicht das erwartete YAML). - Pint
--dirty --format agent→ passed.
-
Offene Fragen: Keine.
-
Nächster Schritt: Päckchen 4B = Detail/Show-Pages (
admin/press-releases/show.blade.php+customer/press-releases/show.blade.php). Dort ist mit der „Werbliche Sprache wurde markiert."- und „Erneut einreichen"- Assertion ausPressReleaseWorkflowTestzu rechnen — Wortlaute bleiben unverändert.
2026-05-19 · Phase 3 · Admin-Dashboard im Hub-Vokabular
-
Anlass: User-Freigabe „weiter" nach Phase 5 (Dark Mode). Phase 3 laut Roadmap: Admin-Dashboard (
/dashboard) im selben Vokabular wie Customer-Dashboard. -
Plan-Dokument:
06-PHASE-3-ADMIN-DASHBOARD.md(knapper als Phase 2 — niedrig-risiko, keine neuen Konzepte, reine Vokabular-Migration auf die DRY-Schicht aus Phase 2). -
Ausgangslage:
admin/dashboard.blade.phpwar Controller-rendered (kein Volt), nutzte reines Tailwind mitzinc-*-Klassen, harten Farb-Pillen (bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 …) und keiner FluxUI-Komponente. Visuell aus der Zeit gefallen. -
admin/dashboard.blade.phpkomplett umgeschrieben:- Page-Header: Hub-Badge „Admin Backend" + Eyebrow + großes H1
- Subtitle mit
auth()->user()->name. Rechts: ok-Pille „Alle Systeme operational".
- Subtitle mit
- KPI-Reihe (5 Stat-Cards via
<x-portal.stat-card>):- Pressemitteilungen →
primarymit Trend-Slot „X pub · Y prüf · Z entwurf" (Wortlaut für Test-Assertions bewusst beibehalten). - In Prüfung →
warnals eigene KPI (war vorher nur in der PM-Card versteckt — jetzt klickbar direkt in den Filter). - Firmen / Kontakte / Benutzer →
mutedmit kurzen Sublines. - Alle Cards sind klickbar (link-wrapped) → CRM-/Content-Übersichten.
- Pressemitteilungen →
- 2-Spalten-Grid (
2fr 1fr):- Links: Panel „Letzte Pressemitteilungen" mit Hub-Liste +
.badge.ok|warn|err|hub-Pillen (statt Tailwind-Farben). - Rechts: Panel „Zur Prüfung" mit warn-Pille (Count) oder ok-Pille „leer". „+ N weitere"-Link im Footer.
- Links: Panel „Letzte Pressemitteilungen" mit Hub-Liste +
- Newsletter + Quick-Actions (
1fr 2fr, NEU):- Links:
panel-warmNewsletter-Block mit Mono-Zahl- Subline + Sync-Link.
- Rechts: Quick-Action-Grid mit 4 Icon-Buttons (Pressemitteilungen, Firmen, Rechnungen, Voreinstellungen) — Icon-Tile wechselt auf Hover ins gefüllte Hub-Blau.
- Links:
- Footer: subtle Link-Reihe (Benutzer / Rollen / Performance).
- Page-Header: Hub-Badge „Admin Backend" + Eyebrow + großes H1
-
Was bewusst NICHT geändert:
- Controller-Logik, Datenform, Cache-Strategie (
AdminPerformanceCache). - Newsletter-Count bleibt, wandert nur in eigenen Block.
- Controller-Logik, Datenform, Cache-Strategie (
-
Build/Verifikation:
npm run build:portal→portal: 417.81 kB(Δ -0.7 kB, weil viele Zinc-Tailwind-Klassen weggefallen sind).php artisan test --filter='DashboardTest|AuthenticationTest|RegistrationTest|CustomerPortalTest'→ 18/18 passed, 70 Assertions.DashboardTestmit seinen Wortlaut-Assertions (3,1 pub,1 prüf,1 entwurf,Review Dashboard PM) bleibt grün ohne Anpassung.vendor/bin/pint --dirty→passed.- Linter: 0 Errors.
-
Lessons learned:
- Vokabular-Migrations ohne Logik-Eingriff brauchen ~15 Minuten dank
DRY-Schicht aus Phase 2 — der Wert der
shared/hub-components.css<x-portal.stat-card>-Investition zahlt sich ab Phase 3 deutlich aus.
- Der
<x-portal.stat-card>ist auch ohne:value-Number-Format flexibel (number_format()direkt im Aufruf eingebettet). - Test-Assertions können bei Layout-Refactors überraschend stabil bleiben, wenn man die Original-Strings im neuen Layout an sinnvollen Stellen behält (hier: im Trend-Slot der KPI-Card).
- Vokabular-Migrations ohne Logik-Eingriff brauchen ~15 Minuten dank
DRY-Schicht aus Phase 2 — der Wert der
2026-05-19 · Phase 5 · Dark Mode + Switcher im User-Menü
-
Anlass: User-Feedback nach Phase 2: „Switch in den Dark Mode funktioniert nicht. Zusätzlich hätte ich gerne einen Switcher hell/dunkel direkt im User-Menü." → Phase 5 vorgezogen vor Phase 3/4, weil der Switcher der natürliche UX-Einstiegspunkt für Dark Mode ist und der Notfall-Hack aus Phase 1 (
portal.css: .dark { --color-accent: var(--color-hub) }) endlich verschwinden soll. -
Plan-Dokument:
05-PHASE-5-DARK-MODE.mdmit Token-Mapping-Tabelle, drei wichtigen Token-Konstanten-Tricks (--color-accent-warm,--color-panel-dark,--color-panel-dark-2) und Switcher-Snippet. -
design-tokens.css— Dark-Block aktiviert:- Vollständiger
.dark { … }-Block mit Werten ausUser Dashboard presseportale Dark.html. - Surfaces: bg/elev/card/rule schalten auf
#0e1218-Familie. - Hub-Blau wird heller im Dark Mode (
#5a78c2statt#1a2540) — notwendig für Lesbarkeit auf dunklem Bg. - Bernstein-Akzent ebenfalls heller (
#d9a560). - Status-Farben (
ok/warn/err) auf dunkle, gesättigte Variante. - Schatten-Tokens neutral-schwarz statt hub-blau-warm.
color-scheme: dark;als Hint für native Form-Controls.
- Vollständiger
-
3 neue Token-Konstanten (gleicher Wert in beiden Modi):
--color-accent-warm(#b07a3a) — für Stellen, die explizit Bernstein bleiben müssen (Hint-Card-Border-Left, Progress-Bar-Fill); löst die Kollision auf, dass--color-accentim Portal auf Hub-Blau gemapt ist und im Dark Mode noch heller würde.--color-panel-dark(#0f1729) und--color-panel-dark-2(#1a2540) — für.panel-darkund Brand-Bridge-Inner-Boxes. Ohne diese würde der dunkle Bridge-Container im Dark Mode plötzlich hellblau, weilvar(--color-hub)zum hellen Wert wird.
-
portal.css— Notfall-Hack aus Phase 1 entfernt:- Der
.dark { --color-accent: var(--color-hub); … }-Block ist überflüssig, weil das echte Dark-Token-Mapping indesign-tokens.css--color-hubautomatisch auf#5a78c2schaltet — und--color-accentdarüber pervar(--color-hub)-Verweis dynamisch mitkommt. - Primary-Button-Shadows zusätzlich für
.darküberschrieben: stattrgba(26, 37, 64, …)(warmer Hub-Blau-Alpha) jetztrgba(0, 0, 0, …)(neutral-schwarz), weil der hub-blaue Schatten auf dunklem Card-BG zu sichtbar wirkt.
- Der
-
hub-components.css— Dark-tauglich gemacht:.panel-darknutzt jetztvar(--color-panel-dark-2)undvar(--color-panel-dark)(vorhervar(--color-hub)undvar(--color-topbar-deep)) → bleibt im Dark Mode dunkel..hint-card border-leftund.hint-bar > spannutzenvar(--color-accent-warm)(konstant Bernstein) stattvar(--color-accent)(im Portal Hub-Blau-Mapping)..hint-card backgroundschaltet aufvar(--color-bg-card-warm)— ist im Light Mode#efeadc(warmes Buchpapier), im Dark Mode#1f1a12(warm-dunkles Bernstein-Substrat).- Restliche Klassen funktionieren automatisch, weil alle Werte über Tokens laufen — DRY-Architektur zahlt sich aus.
-
customer/dashboard.blade.php:- Brand-Bridge-Inner-Boxes auf
bg-[color:var(--color-panel-dark-2)]umgestellt (statt--color-hub-2, das im Dark Mode hell würde).
- Brand-Bridge-Inner-Boxes auf
-
Switcher im User-Menü (
sidebar.blade.php— Desktop + Mobile):- Vor dem Logout-Button: kleiner Block mit Eyebrow „Erscheinung" und
FluxUI-Segmented-Radio-Group mit Icons-only.
<flux:radio.group x-data variant="segmented" size="sm" x-model="$flux.appearance"> <flux:radio value="light" icon="sun" :title="__('Hell')" /> <flux:radio value="dark" icon="moon" :title="__('Dunkel')" /> <flux:radio value="system" icon="computer-desktop" :title="__('System')" /> </flux:radio.group> $flux.appearanceist FluxUIs Magic-Object — LocalStorage-persistent,@fluxAppearance-Script setztclass="dark"auf<html>.- In BEIDEN Dropdowns (Desktop in der Sidebar, Mobile im Header).
- Vor dem Logout-Button: kleiner Block mit Eyebrow „Erscheinung" und
FluxUI-Segmented-Radio-Group mit Icons-only.
-
Hub-Frontend bleibt Light-Only (Plan-Vorgabe):
auth/pressekonto.blade.phplädt KEIN@fluxAppearanceund KEINpartials/head. Damit wirdclass="dark"dort nie gesetzt — auch nicht, wenn LocalStoragedarkenthält. Kein Eingriff nötig.- Hub-Landing analog (eigene
<head>-Pipeline).
-
Build/Verifikation:
npm run build:portal→portal: 418.55 kB(Δ +1.5 kB für Dark-Tokens + Switcher).php artisan test --filter='DashboardTest|AuthenticationTest|RegistrationTest|CustomerPortalTest'→ 18/18 passed, 70 Assertions. Keine Regressions.vendor/bin/pint --dirty→passed.- Linter: 0 Errors.
-
Lessons learned:
- Tailwind v4's
@theme-Variables sind dynamisch zur Laufzeit —--color-accent: var(--color-hub)schaltet beim.dark-Switch automatisch mit, ohne dass man.dark { --color-accent: … }extra setzen muss. - Wenn ein Wert in beiden Modes IDENTISCH bleiben soll (
--color-panel-dark-2,--color-accent-warm), gehört er in den Light-Block und wird im.dark-Block bewusst NICHT überschrieben. Vererbung tut den Rest. - FluxUI's
flux:radio.group variant="segmented"mit Icons-only ist perfekt für Dropdown-Switcher;:title="…"liefert Tooltips ohne sichtbares Label.
- Tailwind v4's
-
Bonus: Der ursprüngliche Symptom-Fix aus Phase 1 (Multi-Alpine + Dark-Mode-Bug) ist jetzt strukturell aufgelöst:
- Alpine kommt ausschließlich aus
@fluxScripts. - Dark Mode ist echt umgesetzt, nicht maskiert.
- Alpine kommt ausschließlich aus
2026-05-19 · Phase 2 · Customer-Dashboard auf Mockup-Stil
-
Anlass: User-Freigabe „weiter“ nach Behebung des Dark-Mode/Alpine-Bugs. Phase 2 laut Plan: Customer-Dashboard (
/admin/me) anUser Dashboard presseportale.htmlangleichen. -
Vorab-Doku:
04-PHASE-2-CUSTOMER-DASHBOARD.mdmit Mockup-Diff-Tabelle, CSS-Strategie, Component-Skizzen, Akzeptanzkriterien. -
CSS-Architektur — DRY-Schritt:
- Neue Datei
resources/css/shared/hub-components.cssals Single Source of Truth für Hub-Layout-Bausteine:.panel(warm/dark/head),.stat-card(+ Variantenis-primary|ok|warn|muted,.stat-strip,.stat-label,.stat-num,.stat-meta,.stat-trend),.hint-card(+.hint-ico,.hint-bar,.hint-action),.badge(+.warn|ok|hub|err|dot),.bridge-row/.dot-pe/.dot-bp, portable.eyebrowund.section-eyebrow(für Portal — Web-Build überschreibt idempotent). - Importiert in beiden Builds:
resources/css/portal.css(nachflux.css)resources/css/web/shared-styles.css(nachdesign-tokens.css)
- Alle Werte nutzen
var(--color-*)-Tokens — keine Hex-Literale. - Fehlende Tokens nachgezogen in
shared/design-tokens.css:--color-bg-rule-2(hellere Progress-Track-Variante) und--color-gain-deep(dunkles Grün füris-ok-Stat-Num).
- Neue Datei
-
Neue Blade-Components in
resources/views/components/portal/:<x-portal.stat-card variant="…" label="…" :value="…">mit Slotsmeta(oben rechts) undtrend(unten).<x-portal.hint-card :icon :title :percent :href :action>mit Progress-Bar bei gesetztem$percentundwire:navigate-Link.
-
livewire/customer/dashboard.blade.phpkomplett neu:- Page-Header: Hub-Badge „User Backend“ + Eyebrow + großes H1
- Subtitle. Rechts entweder Aktive-Firma-Pille oder Warn-Pille „Keine Firma zugeordnet → zuordnen“.
- KPI-Reihe (4
stat-cards): Gesamt (primary, mit Δ-zu-Vormonat), Veröffentlicht (ok), In Prüfung (warn), Entwürfe (muted). - Zweispalten-Grid (
lg:grid-cols-[2fr_1fr]):- Links: Panel mit Pressemitteilungen-Liste oder Empty-State (Icon-Box mit Notification-Dot, Headline, Action-Button, Schritt-Karten 01/02/03, Footer-Tipp „4 Stunden“).
- Rechts: Panel „Datenqualität“ mit
<x-portal.hint-card>s oder Success-State („Alles im grünen Bereich“).
- Unteres Grid: Firmen-Panel (Liste oder dashed Empty-Slot
- Hinweis-Box) + Brand-Bridge-Dark-Panel (presseecho + businessportal24 mit Status, API-Status-Indikator, Tarif).
- Footer: Subtle-Link-Reihe (Sicherheit, API & Tokens, Profil).
- Page-Header: Hub-Badge „User Backend“ + Eyebrow + großes H1
-
Volt-
with()erweitert:stats.deltaMonth— Monatsvergleich via zweiterwhereBetween-Query.profileCompleteness(Heuristik auf 6 Profile-Kernfelder).billingCompleteness(5 Address-Pflichtfelder).bridgeStatus(vorerst hardcodedconnected— Phase 3+).qualityHints[]optional umpercent-Feld erweitert — wenn gesetzt, rendert Progress-Bar in der Hint-Card.
-
Edge-Case beim Bauen: Blade interpretierte
<flux:icon>im PHPDoc- Kommentar vonhint-card.blade.phpals echten Component-Tag und produzierteUndefined variable $component. Fix: Doc-Block entkontaminiert („flux:icon“ ohne Spitzklammern). -
Tests neu in
tests/Feature/Customer/DashboardTest.php(5 Cases):- Customer-Dashboard rendert Core-Sections ohne Fehler
- Empty-State mit 3-Schritt-Intro wird gezeigt
- PR-Liste + KPI-Zahlen rendern bei vorhandenen Daten
- Profile-Completeness-Hint mit Prozentwert erscheint bei Teildaten
- Vollständiges Profil + Billing → Hints werden ausgeblendet, „Alles im grünen Bereich“ wird gezeigt
- Ergebnis: 5/5 passed, 21 Assertions.
- Cross-Check: Verwandte Tests (
Dashboard|Authentication|Registration|CustomerPortal) → 18/18 grün, 70 Assertions. Keine Regressions.
-
Build/Verifikation:
npm run build:portal→portal: 417.02 kB(Δ +8 kB für neue Hub-Components-Klassen + Dashboard-Klassen). Web-Build unverändert.vendor/bin/pint --dirty→passed.
-
Was bewusst weggelassen:
- Sparklines auf den Stat-Cards (kommen mit echten Trend-Daten in Phase 4).
- Topbar-Anpassung (eigene Phase, später).
<x-portal.bridge-card>-Extraktion (Brand-Bridge bleibt inline, bis sie an mehr Stellen gebraucht wird).
-
Lessons learned:
- PHPDoc in Blade-Components darf KEINE
<flux:*>-Tags enthalten — der Blade-Pre-Compiler scannt das gesamte File vor dem PHP-Parsing. shared/hub-components.cssist der richtige Hebel für Phase 3 (Admin-Dashboard) und Phase 4 (Listen/Detail) — Components-CSS muss nicht mehr pro Phase neu definiert werden.
- PHPDoc in Blade-Components darf KEINE
2026-05-19 · Phase 1 Refinement · Dark-Mode-Bug + Multi-Alpine
-
Anlass: User-Review nach Kontrast-Refinement: zwei konkrete Befunde aus der Browser-Konsole.
[Warning] Detected multiple instances of Alpine running (me, line 114)- Button-Default-Farbe ist
rgb(109, 138, 211)(helles Blau), nicht das gewünschte Hub-Blaurgb(26, 37, 64). Computed Style zeigt:.bg-[var(--color-accent)] { background-color: var(--color-accent); }→var(--color-accent)löst zu#6d8ad3auf.
-
Diagnose Bug 1 (Alpine):
partials/head.blade.phplädtresources/js/app.jsüber@vite.app.jsruftAlpine.start()auf.- Am Ende des
<body>injiziert@fluxScripts(sidebar.blade.php Zeile nahe</body>) eine eigene Alpine-Instanz (FluxUI bringt Alpine selbst mit). - Ergebnis: zwei
window.Alpine-Objekte, Bindings teils tot, Warning. - Auf der Login-Seite hatten wir das bereits gefixt (app.js dort rausgenommen), aber im Portal-Layout war der Fix noch offen.
-
Diagnose Bug 2 (Button-Farbe):
- Der Wert
rgb(109, 138, 211)=#6d8ad3ist exakt der Dark-Mode-Fallback, den ich inportal.cssunter.dark { --color-accent: #6d8ad3 }definiert hatte. - FluxUI's
@fluxAppearance-Helper schreibtclass="dark"auf<html>, sobald der User den Appearance-Switcher mal auf "dark" gestellt hatte (gespeichert inlocalStorage). - Damit überschreibt der Dark-Block den Light-Mode-Akzent
var(--color-hub)(#1A2540) — Buttons sehen plötzlich blassblau aus. - Dark Mode ist laut Plan erst Phase 5, war aber durch den Fallback-Block bereits halb aktiv.
- Der Wert
-
Fixes:
resources/views/partials/head.blade.php:resources/js/app.jsaus dem@vite-Aufruf entfernt. Alpine kommt im Portal ausschließlich über@fluxScripts. (Hub-Landing nutztpartials/headnicht — eigene<head>-Pipeline.)resources/css/portal.css: Der.dark { --color-accent: ... }- Block setzt jetzt bewusst alle Akzent-Tokens aufvar(--color-hub)(also den Light-Mode-Wert). Damit bleibt das Hub-Blau auch bei eingeschaltetemclass="dark"konsistent. Kommentar dokumentiert, dass Phase 5 diesen Block durch das echte Dark-Token-Mapping ausshared/design-tokens.cssersetzt.
-
Build/Verifikation:
npm run build:portal→portal: 408.97 kB(Δ +0.02 kB).php artisan test --compact --filter='AuthenticationTest|RegistrationTest'→ 6 passed, 19 assertions, 1.93s.vendor/bin/pint --dirty --format agent→passed.
-
User-Action zur Verifikation:
- Im Portal Hard-Reload (Cmd/Strg+Shift+R) — die alte
app.jshängt sonst im HTTP-Cache. - Konsole sollte keine Multi-Alpine-Warning mehr werfen.
- Primary-Buttons sind im Default-State sattes Hub-Blau (
#1A2540), Hover noch dunkler (#243152).
- Im Portal Hard-Reload (Cmd/Strg+Shift+R) — die alte
2026-05-19 · Phase 1 Refinement · Kontraste & Button-Hover
- Anlass: User-Review nach Phase 1: „Buttons als Primary auf
rgb(26, 37, 64)einsetzen, die andere Farbe ist deutlich zu hell. Es fehlen noch deutliche Kontraste." - Diagnose:
- FluxUI-Primary-Buttons sind eigentlich schon auf
var(--color-accent)=var(--color-hub)=#1A2540=rgb(26, 37, 64)gesetzt (im Build verifiziert). Sollte stimmen. - ABER: Der FluxUI-Default-Hover ist
hover:bg-[color-mix(in_oklab,_var(--color-accent),_transparent_10%)]— auf hellem Buchpapier wirkt das hell-blau statt der gewünschten Hub-Konventionhover:bg-hub-2(dunkler als Default). - Außerdem zu wenig Schatten/Border-Kontrast für klare Button-Kanten.
- FluxUI-Primary-Buttons sind eigentlich schon auf
- Erkenntnis: Frühere
[data-flux-button][data-variant="primary"]- Overrides griffen nie, weil FluxUI keindata-variant-Attribut rendert. Variant-Styling kommt komplett über Tailwind-Klassen (z.B.bg-[var(--color-accent)]). Neue Selektor-Strategie nutzt jetzt diese Klassen direkt (mit escapeten Brackets). - Fixes in
portal.css:- Primary-Button-Hover auf
var(--color-hub-2)(#243152) statt FluxUI's color-mix-Hellung. Selektor:[data-flux-button].hover\:bg-\[color-mix\(in_oklab\,_var\(--color-accent\)\,_transparent_10\%\)\]:hover - Primary-Button-Shadow: kräftigeres Inset-Highlight + warmer
Drop-Shadow in Hub-Blau-Alpha für klare Kanten auf Buchpapier.
Border zusätzlich auf
var(--color-hub-2)für definierten Rand. - Hover-State: noch stärkerer Shadow + Drop für Tiefenwirkung.
- Input-Focus auf Hub-Blau-Ring (statt blassem Default-Akzent), mit Buchpapier-Offset für saubere Trennung.
- Alter (defunkter)
[data-flux-button][data-variant="primary"]- Block entfernt, weil Selektor nicht existiert.
- Primary-Button-Hover auf
- Build/Verifikation:
npm run build:portal→portal: 408.95 kB(von 409.03 kB, -0.08 kB).- Im finalen CSS verifiziert:
- Hub-2-Hover-Override:
[data-flux-button].hover\:bg-…:hover{background-color:var(--color-hub-2)!important} - Shadow-Override:
[data-flux-button].bg-\[var\(--color-accent\)\]{border-color:var(--color-hub-2);box-shadow:inset 0 1px #ffffff2e,0 1px 2px #1a254040,…} - Input-Focus-Ring auf Hub-Blau.
- Hub-2-Hover-Override:
vendor/bin/pint --dirty→ passed.
- Wirkung:
- Primary-Button Default:
#1A2540(Hub-Blau), klarer warmer Schatten, definierter Rand → fühlt sich „solid" an wie auf der Hub-Landing. - Primary-Button Hover:
#243152(Hub-2, dunkler statt heller) — Hub-Konvention, signalisiert Interaktion ohne den Eindruck einer schwächeren Farbe zu erzeugen. - Inputs zeigen jetzt einen erkennbaren Hub-Blau-Ring beim Fokus statt eines blassen Bernstein-Schimmers.
- Primary-Button Default:
- Hinweis an User: Hard-Reload (Cmd+Shift+R) ist nötig — das
CSS-Bundle hat einen neuen Hash (
portal-kuU-opFv.css). - Verfeinerungen noch offen für Phase 2 / Iteration:
- Subtle/Filled/Ghost-Buttons (
<flux:button variant="filled">) sind weiterhin transparent-zinc → bei Bedarf in Phase 2 angleichen. - Sidebar-Active-Item hat schon Hub-Soft + 2 px-Strip; ggf. den Strip noch sichtbarer machen wenn weiter zu unauffällig.
- Subtle/Filled/Ghost-Buttons (
2026-05-19 · Phase 1 abgeschlossen · Portal-Shell auf Hub-Design
- Was: Portal-Shell (Sidebar, Topbar, Layout-Container, Customer-Banner)
visuell ans Hub-Design angeglichen. FluxUI bleibt komplett erhalten —
Anpassung erfolgt über CSS-Token-Bridging und
[data-flux-*]-Overrides. Brand-Mark ersetzt das Starter-Kit-Logo. Light Mode ist Default; Dark Mode für Phase 5 vorbereitet (heller Hub-Blau). - Dateien (geändert):
resources/css/portal.css— komplett refactored:--font-sans: "Inter Tight"stattInstrument Sans--color-accent: var(--color-hub)(#1A2540) statt#3ea3dc--color-zinc-50..950auf Hub-Buchpapier-Familie gemappt (Zinc-100 = #F6F4EF, Zinc-700 = #1A1F1C, Zinc-900 = Hub-Blau)- Hub-Stil-Overrides:
[data-flux-sidebar],[data-flux-navlist],[data-flux-navlist-item]mit Active-Strip links,[data-flux-button]Primary/Filled auf Hub-Blau,[data-flux-card]Buchpapier - Dark-Mode-Block bleibt vorerst minimal (nur Accent), Vollumstellung in Phase 5
resources/views/partials/head.blade.php— Bunny-Font aufinter-tight + jetbrains-mono + source-serif-4(für Brand-Mark)resources/views/components/layouts/app/sidebar.blade.php:class="dark"aus<html>entfernt<body>jetztbg-bg text-ink antialiased(Hub-Buchpapier)<x-app-logo>ersetzt durch<x-web.brand-mark brand="pressekonto" :serif="false" />+ Eyebrow "Publisher · Hub" — sowohl im Desktop- Brand-Block als auch im Mobile-Header- Testmodus-Block (Impersonation) komplett im Hub-Stil: dunkles Hub-Blau-Panel mit Bernstein-Eyebrow „Testmodus aktiv", weiße CTA „Zurück zum Admin" (statt Amber-Warnfarbe wie zuvor)
- Resources-Block (Tailwind/HeroIcons/Flux/Repository) entfernt — gehört nicht ins Live-Portal
resources/views/components/layouts/app.blade.php:- Customer-Banner („User Backend") visuell auf Hub-Stil: Hub-Soft- Hintergrund + Hub-Soft-2-Border, Hub-Blau-Pille mit Dot, Eyebrow „Firmenkontext" in Sperrschrift, Heading in Hub-Ink
- Dateien (Test-Anpassungen, weil rollen-basierter Redirect aus Login-Fix
weitere Tests berührt hat):
tests/Feature/Auth/AuthenticationTest.php— Test-User aufsuperAdmin()umgestellt (sonstcanAccessAdmin() === false→ Redirect auf/statt/dashboard)tests/Feature/Auth/RegistrationTest.php—terms_acceptedim Formular gesetzt + Redirect-Erwartung auf/angepasst (frisch registrierte User haben keine Rolle → Fallback/)
- Build/Test:
npm run build:portal→portal: 409.03 kB(vorher 408.89 kB, +0.14 kB). Unter dem 10 %-Akzeptanzkriterium (≤ 450 kB).- CSS-Inspektion bestätigt Phase-1-Tokens:
--color-accent: var(--color-hub)und.dark { --color-accent: #6d8ad3 }im:root--color-zinc-700: #1a1f1c(Hub-Ink statt Zinc-Grau)--font-sans: "Inter Tight"ohne Instrument-Sans-Vorlauf- Hub-Overrides im Output:
[data-flux-sidebar]{background:var(...)},[data-flux-navlist-item][aria-current=page]{background:var( --color-hub-soft);...}
- Auth-Test-Suite: 0 zusätzliche Regressionen verifiziert (8 fail / 15 passed vor & nach Phase 1; verbleibende Failures sind pre-existing Domain-Mismatch- und CSRF-Issues im Test-Setup).
- Smoke-Test:
/dashboard,/admin/me,/settings/profile,/admin/companies,/admin/press-releasesantworten alle HTTP 302 →/login(erwartetes Verhalten ohne Auth-Session via curl). vendor/bin/pint --dirty→ passed.
- Bewusst NICHT in Phase 1:
- Topbar mit Breadcrumb + Bridge-Row + Search + „Neue Mitteilung"-CTA aus dem Mockup → ist für Phase 2 (Customer-Dashboard) sinnvoller, weil die Topbar dort Page-Kontext (Breadcrumb-Titel) braucht. Aktuell nutzen wir FluxUI's Default-Layout ohne dedizierte Topbar.
- Konto-Switcher als Sidebar-Header (Avatar + Name + Firma als Dropdown-Trigger oben statt unten) → das User-Menü unten bleibt vorerst FluxUI-Standard. Iterativ in Phase 2.
- Dashboard-Inhalte (Stat-Cards, Hint-Cards) → Phase 2 & 3.
- Listen-Pages → Phase 4 (automatisch durch Token-Bridge schon „okay").
- Beobachtungen:
- FluxUI-Navlist-Item-Selektor:
[aria-current="page"]greift. Falls künftige FluxUI-Versionen[data-current="true"]statt[aria-current="page"]setzen, deckt der Override beides ab. - Vendor-Pfad in
partials/head.blade.phpbewusst nicht geändert — Vite-Setup mitbuild/portalbleibt wie gehabt.
- FluxUI-Navlist-Item-Selektor:
- Nächster Schritt: Review-Stopp. Bei Freigabe → entweder Phase 2 (Customer-Dashboard-Stat-Cards & Hint-Cards) oder Topbar- Iteration. Entscheidung bei dir/Frank nach Anschauen.
2026-05-19 · Login-Funktionsfix · Doppelte Alpine-Instanz
- Was: Nach Phase 0 trat ein funktionaler Bug auf: Login-Form ging nicht durch, Browser-Logs zeigten „Detected multiple instances of Alpine running" und „Livewire: published assets out of date".
- Ursache: Das Hub-Auth-Layout (
pressekonto.blade.php) lud sowohlresources/js/app.js(dasAlpine.start()aufruft) als auch@livewireScripts(das Alpine intern mitbringt). Zwei Alpine-Instanzen →wire:submit,x-data,wire:modelbrachen. - Fixes:
app.jsaus@vite([…])im Auth-Layout entfernt — Alpine kommt nun nur noch über Livewire.php artisan livewire:publish --assets→livewire.jsvon 450 kB auf 552 kB aktualisiert (Versions-Mismatch behoben).- Login/Register-Redirect auf rollen-basierte Logik umgestellt
(Admin →
/dashboard, Customer →/admin/me, sonst/) undnavigate: trueentfernt — SPA-Navigation kann den Wechsel zwischen Web-Build (Hub-Auth) und Portal-Build (FluxUI-Dashboard) nicht handhaben.
- Dateien:
resources/views/components/layouts/auth/pressekonto.blade.phpresources/views/livewire/auth/login.blade.phpresources/views/livewire/auth/register.blade.php
- Verifikation: Login funktioniert (User bestätigt), Redirect zum Dashboard läuft, keine Browser-Warnings mehr.
2026-05-19 · Phase 0 abgeschlossen · Token-Unifizierung
- Was: Single Source of Truth für Design-Tokens etabliert. Web- und
Portal-Build importieren beide
resources/css/shared/design-tokens.css. Visuelle Unverändertheit verifiziert — FluxUI-Defaults gewinnen im Portal weiterhin (Instrument Sans, Zinc,#3ea3dc), wird in Phase 1 abgelöst. - Dateien:
resources/css/shared/design-tokens.cssneu — alle Hub-Tokens plus Status-Reihe (--color-warn,--color-warn-soft,--color-err,--color-err-soft,--color-ok-soft), Bridge-Dots (--color-bridge-presseecho,--color-bridge-businessportal), Radii (--radius-xs/sm/md/lg) und Schatten (--shadow-soft,--shadow-auth). Dark-Mode-Block als auskommentierter Vorgriff.resources/css/web/shared-styles.css— Token-Import nachtailwindcssergänzt. Wirkt damit für alle Web-Themes (pressekonto, presseecho, businessportal24).resources/css/web/theme-pressekonto.css— kompletter@theme {}- Block entfernt (lebt jetzt in der Token-Datei). HSL-Legacy-Variablen und@layer components { … }blieben unverändert.resources/css/portal.css— Token-Datei importiert, FluxUI-Setup mit Zinc + Instrument Sans bleibt vorerst dominant. Phase 1 löst es ab.
- Build/Test:
npm run build:web→theme-pressekonto: 193 kB(vorher 189 kB, +4 kB für neu gebridgde Status-Tokens),theme-presseecho: 189 kB,theme-businessportal24: 189 kB.npm run build:portal→portal: 408 kB(vorher 397 kB, +12 kB für die zusätzlich verfügbaren Hub-Tokens als CSS-Vars im:root). Wird in Phase 1 wieder egalisiert, wenn das Zinc-Setup wegfällt.- Smoke-Test:
pressekonto.test/,/login,/register,/dashboard(302→login),presseecho.test/,businessportal24.test/— alle HTTP 200/302 wie erwartet. - CSS-Inspektion:
--color-hub: #1a2540und--color-warn: #a87a1fsind intheme-pressekonto-*.cssenthalten. Im Portal-Build bleibt--font-sans: "Instrument Sans"— bestätigt visuelle Unverändertheit. vendor/bin/pint --dirty→ passed.
- Offene Fragen / Beobachtungen:
- Weil Tailwind v4 alle in
@theme {}definierten Tokens als CSS- Variablen im:rootausgibt (auch ohne Utility-Verwendung), wird der Portal-CSS-Wuchs in Phase 1 nicht komplett zurückgehen — die Hub-Tokens bleiben als Variablen verfügbar. Der Nettoeffekt nach Phase 1 sollte ähnlich bleiben (+/- 5–10 kB). - Dark-Mode-Block in
design-tokens.cssist auskommentiert vorbereitet, aber bewusst noch nicht aktiv (Phase 5).
- Weil Tailwind v4 alle in
- Nächster Schritt: Review-Stopp. Bei Freigabe →
Phase 1 starten: Portal-Shell (Sidebar, Topbar, Layout-Container)
auf Hub-Style mappen, Zinc-Palette ablösen, FluxUI-Overrides via
[data-flux-*]-Selektoren inportal.css. Details:02-PHASE-1-PORTAL-SHELL.md.
2026-05-19 · Setup
- Was: Architektur-Entscheidung getroffen → Plan B (Tokens teilen,
Komponenten getrennt lassen). Dokumentation in
dev/frontend/hub-flux/angelegt:README.md— Übersicht & Entscheidung01-PHASE-0-TOKENS.md— Detail-Plan für Tokens-Vereinheitlichung02-PHASE-1-PORTAL-SHELL.md— Detail-Plan für Portal-Shell-Refresh03-WEITERE-PHASEN.md— Outline Phase 2–6PROGRESS.md— dieses Log
- Bestätigt:
- Hub-Blau als Primärer Akzent im Portal (klarer Kontrast zum hellen Buchpapier-Hintergrund)
- Bernstein als Sekundärer Akzent (Notifications, Datenqualität, Akzent-Ribbons)
- Brand bleibt pressekonto (auch im Portal-Sidebar via
<x-web.brand-mark>) - Reihenfolge: erst Phase 0 + 1, dann Review
- Nächster Schritt: Phase 0 umsetzen
→
resources/css/shared/design-tokens.csserstellen,theme-pressekonto.cssrefactoren,portal.cssminimal vorbereiten.
Vorlauf (zur Erinnerung, was schon steht)
- Hub-Landing (
web/pressekonto.blade.php) — fertig, lebt im Web-Build mittheme-pressekonto.css - Hub-Auth (Login, Register, Forgot, Reset, Verify, Confirm) — fertig
im Hub-Design, neues Layout
auth/pressekonto.blade.phpim Web-Build - Register-AGB-Checkbox mit Server-Side-Validierung ergänzt
- Portal-Backend mit FluxUI funktional vorhanden (Admin-Dashboard,
Customer-Dashboard, 77 Blade-Dateien mit FluxUI), aber visuell noch
Starter-Kit-Look (Zinc +
#3ea3dc+ Instrument Sans)
Template für neue Einträge
## YYYY-MM-DD · Phase N · Kurztitel
- **Was**: [Was wurde konkret gemacht?]
- **Dateien**: [Pfade]
- **Build/Test**: [Wie verifiziert?]
- **Offene Fragen**: [Falls etwas unklar geblieben ist]
- **Nächster Schritt**: [Was als Nächstes ansteht]