--- phase: 120-alert-component-unification plan: 01 subsystem: ui tags: [alerts, flash, components, scss, php-view, accessibility, dismissable] requires: - phase: 113-fakturownia-foundation provides: Flash usage pattern, fakturownia.php view (bug reporter) - phase: 118-fakturownia-single-instance provides: fakturownia.php single-form view that exposed missing .alert--info provides: - Reusable view component for alerts (`resources/views/components/alert.php`) - .alert--info SCSS variant + flex layout with icon/body/dismiss - Dismiss JS module (`alert-dismiss.js`) with delegated click handler - Flash::push(type, message) + Flash::all() with legacy heuristic - Central flash renderer in 3 layouts (app/auth/public) - 36 views migrated off inline alert markup affects: [future settings views, future Flash::push usage, login UX, any new admin views] tech-stack: added: [] patterns: - Component include with extracted locals (`$type`, `$message`, `$dismissible`, `$messageHtml`) - Central renderer in layout consuming queued + legacy flash entries - Idempotent vanilla JS modules guarded via window flags key-files: created: - resources/views/components/alert.php - public/assets/js/modules/alert-dismiss.js modified: - resources/scss/shared/_ui-components.scss - public/assets/css/app.css (rebuilt) - public/assets/css/login.css (rebuilt) - src/Core/Support/Flash.php - resources/views/layouts/app.php - resources/views/layouts/auth.php - resources/views/layouts/public.php key-decisions: - "Component-based view include over template engine partial - no DI needed, BC z `extract` pattern" - "Flash::set/get pozostawione BC; kontrolery NIE dotykane - migracja widokow wystarczyla" - "Heurystyka klucza legacy (`.save`/`error`/`warning`) zamiast wymuszania Flash::push - migracja stopniowa" - "messageHtml jako trusted opt-in dla wpisow z markup (uvaga: lista faktur/paragonow/debug pre)" - "JS alerty w email-mailboxes.php pozostawione na klasach SCSS - markup komponentu poza zakresem" patterns-established: - "Alert markup: ``" - "Trusted HTML w alert: ob_start() ... $messageHtml = ob_get_clean(); include ...; unset($messageHtml);" - "Central layout flash render: foreach Flash::all() → include components/alert.php (wrap .alerts-stack)" duration: ~50min started: 2026-05-12T15:00:00Z completed: 2026-05-12T15:40:00Z --- # Phase 120 Plan 01: Alert Component Unification **Reusable PHP alert component z `.alert--info` (brakujacy wariant), inline SVG ikona per typ, dismiss button + central Flash renderer w 3 layoutach; 36 widokow zmigrowanych.** ## Performance | Metric | Value | |--------|-------| | Duration | ~50 minut | | Started | 2026-05-12T15:00:00Z | | Completed | 2026-05-12T15:40:00Z | | Tasks | 3 z 3 ukonczone | | Files modified | 42 (component + JS + SCSS + 3 layouty + Flash + 36 widokow + 2 CSS rebuilds) | ## Acceptance Criteria Results | Criterion | Status | Notes | |-----------|--------|-------| | AC-1: Komponent alert + brakujacy wariant info | Pass | `.alert--info` (#eff6ff/#bfdbfe/#1e3a8a) w `app.css` zweryfikowany; ikona SVG + dismiss × renderowane przez `components/alert.php`. Test polaczenia fakturownia → niebieski alert z ikona "i" i ×. | | AC-2: Centralny renderer flash w layoutach | Pass | `Flash::all()` w `app.php`, `auth.php`, `public.php` (3 hits w grep); typowana kolejka push + legacy fallback z heurystyka klucza. | | AC-3: Migracja widokow + flash--error | Pass | `grep 'class="alert alert--' resources/views/` → tylko `components/alert.php`; `grep 'flash--' resources/views/` → 0. 36 widokow przeszlo `php -l`. | ## Accomplishments - Component-based alert markup dostepny w jednym pliku — `resources/views/components/alert.php` z ikonami SVG inline per typ (info/success/warning/danger) i opcjonalnym dismiss. - Brakujacy `.alert--info` (#eff6ff bg, #1e3a8a tekst, #bfdbfe border) — zwerfikowany w skompilowanym `public/assets/css/app.css` (63 560 B, rebuilt via `npx sass`). - `Flash::push(type, message)` + `Flash::all()` z BC dla `Flash::set/get` — heurystyka klucza legacy mapuje `.save/.created/.deleted/.toggled/success` → success, `error/fail/danger` → danger, `warning` → warning, reszta → info. - Central flash renderer w 3 layoutach (`app.php`, `auth.php`, `public.php`) — przyszle `Flash::push()` zadziala bez ifow w widokach. - 36 widokow zmigrowanych off inline `
` (34 z planu + odkryte `orders/show.php` i `shipments/prepare.php` ze starym wzorcem `.flash--error/success`). - Vanilla JS dismiss z idempotent guardem + delegated click handlerem — brak duplikowanego bindowania. ## Task Commits Brak atomowych commits per task — caly plan zostanie wyemitowany jako single commit w transition phase (zgodnie z konwencja projektu, faza 119/118 dziedzicza ten wzorzec). | Task | Commit | Type | Description | |------|--------|------|-------------| | Task 1: Komponent + SCSS + JS + layouty | (transition) | feat | Alert component, SCSS info/icon/dismiss, JS, central layout render | | Task 2: Flash push/all + BC | (transition) | feat | Flash::push/all + legacy heuristic | | Task 3: Migracja 36 widokow | (transition) | refactor | Inline alert/flash markup → component include | ## Files Created/Modified | File | Change | Purpose | |------|--------|---------| | `resources/views/components/alert.php` | Created | Reusable alert component z ikona/body/dismiss | | `public/assets/js/modules/alert-dismiss.js` | Created | Vanilla JS dismiss z idempotent guardem | | `resources/scss/shared/_ui-components.scss` | Modified | `.alert` flex + `__icon`/`__body`/`__dismiss`, `.alert--info`, `.alerts-stack` | | `public/assets/css/app.css` | Rebuilt | Wygenerowany z SCSS (`npx sass --style=compressed`) | | `public/assets/css/login.css` | Rebuilt | Wygenerowany z SCSS | | `src/Core/Support/Flash.php` | Modified | `push()`, `all()`, `inferTypeFromKey()` (private); BC dla `set/get` | | `resources/views/layouts/app.php` | Modified | Central flash render + `alert-dismiss.js` script tag | | `resources/views/layouts/auth.php` | Modified | Central flash render + `alert-dismiss.js` script tag | | `resources/views/layouts/public.php` | Modified | Central flash render + `alert-dismiss.js` script tag | | `resources/views/settings/fakturownia.php` | Modified | Inline alerts → component (bug reporter) | | `resources/views/settings/{hostedsms,smsplanet,inpost,apaczka,allegro,company,cron,database,delivery-statuses,delivery-status-form,email-mailboxes,email-templates,email-templates-form,integrations,printing,project-mappings,shoppro,statuses,accounting,accounting-receipts,accounting-receipt-edit,accounting-invoices,accounting-invoice-edit}.php` | Modified | Inline alerts → component (23 plikow) | | `resources/views/orders/{list,show,receipt-create}.php` | Modified | Inline alerts + `.flash--*` → component (3 pliki) | | `resources/views/shipments/prepare.php` | Modified | 4× `.flash--error` → component | | `resources/views/accounting/invoice_form.php` | Modified | Inline alerts + warning HTML → component z `$messageHtml` | | `resources/views/automation/{index,form}.php` | Modified | Inline alerts → component | | `resources/views/users/index.php` | Modified | Inline alerts → component | | `resources/views/statistics/orders.php` | Modified | Debug warning HTML → component z `$messageHtml` | | `resources/views/auth/login.php` | Modified | `.alert--danger login-alert` → component (`flash--error` flow) | | `.paul/codebase/architecture.md` | Modified | Sekcja "Phase 120 — Alert Component Unification" | | `.paul/codebase/tech_changelog.md` | Modified | Wpis dla Phase 120 | ## Decisions Made | Decision | Rationale | Impact | |----------|-----------|--------| | Component przez `include` z extracted locals zamiast template helper | Zero infrastruktury, BC z istniejacym wzorcem `` w widokach | Latwa migracja, brak nowych zaleznosci | | Kontrolery NIE zmieniane (BC `Flash::set/get`) | Plan boundary: DO NOT CHANGE controllers. Migracja widokow wystarcza, central renderer obsluguje przyszle `Flash::push()` | Zachowany dotychczasowy flow flash z pre-fetchem w kontrolerze | | `messageHtml` jako trusted opt-in (4 widoki: invoice_form, receipt-create, printing, statistics/orders) | `