Umbenennung presseportale → pressekonto in Domains, Themes und Dokumentation. Design-Tokens, Portal-Shell, Customer-Dashboard, Auth- und Admin-PM-Views. Artisan-Befehl migrate:legacy-media mit Tests und Hub-Flux-Entwicklungsdocs. Co-authored-by: Cursor <cursoragent@cursor.com>
40 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-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]