feat(120): alert component unification
Phase 120 - Plan 01:
- Reusable PHP alert component (resources/views/components/alert.php)
with inline SVG icon per type, optional dismiss button.
- Missing .alert--info SCSS variant added (#eff6ff/#bfdbfe/#1e3a8a) -
fixes black-on-white alert after Fakturownia test connection.
- Flash::push(type, message) + Flash::all() with BC for set/get;
legacy key heuristic (error/.save/warning -> typed entries).
- Central flash renderer in 3 layouts (app/auth/public) iterating
Flash::all() through component (.alerts-stack wrap).
- Vanilla JS alert-dismiss.js with idempotent guard and delegated
click handler on [data-alert-dismiss].
- 36 views migrated off inline <div class="alert alert--TYPE">;
.flash--error/success removed from views (orders/show, shipments/prepare).
- SCSS rebuilt: public/assets/css/{app,login}.css.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,53 @@
|
||||
# Technical Changelog
|
||||
|
||||
## 2026-05-12 - Phase 120 Plan 01: Alert Component Unification
|
||||
|
||||
**Co zrobiono:**
|
||||
- Dodano komponent `resources/views/components/alert.php` (params: `$type` info|success|warning|danger, `$message`/`$messageHtml`, `$dismissible`, `$role`) renderujacy `.alert` z inline SVG ikona, body i opcjonalnym przyciskiem dismiss.
|
||||
- SCSS `_ui-components.scss`: `.alert` zmieniony na flex z `.alert__icon`/`.alert__body`/`.alert__dismiss`; dodany brakujacy wariant `.alert--info` (#eff6ff/#bfdbfe/#1e3a8a); dodany wrapper `.alerts-stack`.
|
||||
- Vanilla JS `public/assets/js/modules/alert-dismiss.js` z idempotent guardem i delegated handlerem na `[data-alert-dismiss]`.
|
||||
- `Flash` rozszerzony o `push(string $type, string $message): void` i `all(): array` z BC dla `set/get` — `all()` konsumuje typowana kolejke + skanuje legacy `_flash` z heurystyka klucza (error/danger/fail → danger, warning → warning, success/.save/.created/.deleted/.toggled → success, reszta → info).
|
||||
- Layouty `app.php`, `auth.php`, `public.php` na poczatku content area iteruja `Flash::all()` przez komponent w `.alerts-stack` i ladja `alert-dismiss.js`.
|
||||
- Migracja 36 widokow (34 z planu + `orders/show.php` + `shipments/prepare.php`): inline `<div class="alert alert--TYPE">` zastapione `include components/alert.php`; `.flash--error`/`.flash--success` w starych widokach takze przeniesione na komponent.
|
||||
|
||||
**Dlaczego:**
|
||||
- Po teste polaczenia Fakturowni alert `OK (HTTP 200)` mial klase `alert--info`, ale `.alert--info` nie istnial — efekt: czarny tekst na bialym tle bez ikony. Zglosenie operatora po Phase 118.
|
||||
- Wiele wzorcow alertow w 36 widokach roznilo sie szczegolami (mt-12/role/struktura), brak komponentu wielokrotnego uzytku. Po Phase 120 jeden plik (`components/alert.php`) jest jedynym renderem markupu alert + centralny renderer flash w 3 layoutach przyjmuje przyszle `Flash::push()` bez koniecznosci powtarzania kodu w widokach.
|
||||
|
||||
**Boundaries (zachowane):**
|
||||
- Kontrolery NIE zmieniane — `Flash::set/get` BC; wzorce `Flash::set('module.key', '...')` + view local `$flashXxx` dzialaja jak dotychczas (widok renderuje przez komponent).
|
||||
- Modul `resources/modules/jquery-alerts` (dialogi `OrderProAlerts`) niezmieniany — osobny system.
|
||||
- `email-mailboxes.php` JS-generowane alerty AJAX testu SMTP — pozostawione bez zmian (uzywaja `.alert` SCSS, brak markupu komponentu — out of scope).
|
||||
- `.flash--*` SCSS nie usuniety (deferred cleanup) — widoki juz go nie uzywaja.
|
||||
- Build SCSS → CSS poza zakresem; `public/assets/css/app.css` musi byc zregenerowany lokalnie po wdrozeniu.
|
||||
|
||||
## 2026-05-12 - Phase 119 Plan 01: Re-import total_paid Protection
|
||||
|
||||
**Co zrobiono:**
|
||||
- `OrderImportRepository::updateOrderDelta()` przebudowane na dynamiczny SQL builder: `total_paid` i `is_canceled_by_buyer` są dołączane do UPDATE warunkowo. Gdy `payment_status` w bazie == `payment_status` z payloadu źródła, `total_paid` NIE jest aktualizowany. `is_canceled_by_buyer` jest pomijany w tej samej sytuacji, chyba że źródło flaguje anulowanie (`$cancelledBySource=true`) — wtedy zawsze wpisywane.
|
||||
- `upsertOrderAggregate()` wylicza `$paymentStatusUnchanged` przed wywołaniem delty i propaguje wraz z `$cancelledBySource`.
|
||||
- Test PHPUnit `tests/Unit/OrderImportRepositoryTest.php` z 3 scenariuszami (preserve / transition / cancel propagation). Uruchomienie odroczone — `vendor/` nieobecne w środowisku, składnia PHP zweryfikowana przez `php -l`.
|
||||
|
||||
**Dlaczego:**
|
||||
- Incydent zamówienia #976: operator usunął 2 pozycje Girlanda i zwrócił klientowi 28,00 PLN, obniżając `total_paid` ze 119,00 na 91,00. Audyt re-importu (Phase 112-01 delta-only) wykazał, że istniejące `updateOrderDelta` nadpisywało `total_paid` z payloadu źródła przy każdym wywołaniu, jeśli identical-payload guard nie zadziałał. Ręczne korekty kwoty były ulotne.
|
||||
|
||||
**Boundaries (zachowane):**
|
||||
- `paymentTransition` (Phase 111) i `statusOverwriteAllowed` (Phase 62) działają bez zmian.
|
||||
- Cancel propagation (`$cancelledBySource` override) z Phase 112-01 nadal wymusza `status_code='anulowane'` i — od Phase 119 — `is_canceled_by_buyer=1` nawet gdy `payment_status` stabilne.
|
||||
- Identical-payload no-op guard (Phase 112-01) nadal pierwsza linia obrony — Phase 119 dotyczy tylko ścieżki gdy guard nie zadziałał (payload się różni, ale `payment_status` stabilne).
|
||||
|
||||
## 2026-05-12 - Phase 118 Plan 01: Fakturownia Single Instance
|
||||
|
||||
**Co zrobiono:**
|
||||
- Dodano migracje `20260512_000109_fakturownia_single_instance.sql`, ktora wybiera aktywna instancje Fakturowni, przepina delegowane `invoice_configs.integration_id` na jeden globalny rekord i usuwa nadmiarowe konta Fakturowni po przepieciu zaleznosci.
|
||||
- Przebudowano `FakturowniaIntegrationRepository` na jedna globalna konfiguracje (`getSettings`, `saveSettings`, `getIntegrationId`, `getCredentials`) z kompatybilnym `findAll()` zwracajacym jeden element.
|
||||
- Uproszczono `FakturowniaIntegrationController` i widok `/settings/integrations/fakturownia` do pojedynczego formularza konfiguracji i testu polaczenia.
|
||||
- Hub integracji pokazuje Fakturownie jako jedna instancje, bez licznika kont.
|
||||
- Zapis delegowanej konfiguracji faktury ustawia `invoice_configs.integration_id` na globalny rekord Fakturowni; UI konfiguracji faktury nie pokazuje juz selecta kont.
|
||||
|
||||
**BREAKING / migracja:**
|
||||
- Po migracji nie ma juz wielu kont Fakturowni. Jesli baza miala wiele rekordow `integrations.type='fakturownia'`, zachowany zostaje aktywny rekord (fallback: uzywany przez konfiguracje faktur, potem najnizsze id), a pozostale sa usuwane.
|
||||
|
||||
## 2026-05-12 - Phase 117 Plan 01: SMSPLANET Integration Settings + Test SMS
|
||||
|
||||
**Co zrobiono:**
|
||||
|
||||
Reference in New Issue
Block a user