Files
carei.pagedev.pl/.paul/phases/04-polish-testing/04-01-PLAN.md
2026-03-25 17:45:13 +01:00

12 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
04-polish-testing 01 execute 1
wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
wp-content/plugins/carei-reservation/includes/class-elementor-widget.php
false
## Goal Polish formularza rezerwacji: obsługa edge cases (wygasły token, brak dostępności, timeouty), animacje przejść form↔summary↔success, poprawki a11y (ARIA, focus management, keyboard nav), naprawa bugów CSS.

Purpose

Formularz działa end-to-end (Phase 3), ale brak obsługi błędów brzegowych, brak animacji, a11y nie jest wdrożone. Phase 4 doprowadza formularz do jakości produkcyjnej.

Output

Zmodyfikowane: JS (error handling + animacje + a11y), CSS (transitions + fix bugs), PHP widget (ARIA attrs).

## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md

Prior Work

@.paul/phases/03-form-submit-booking/03-01-SUMMARY.md

  • Phase 3: pełny booking flow działa (customer → pricing → makebooking → confirm → success)
  • API discoveries: boolean true/false, drivers[] required, penalty items filtered

Source Files

@wp-content/plugins/carei-reservation/assets/js/carei-reservation.js @wp-content/plugins/carei-reservation/assets/css/carei-reservation.css @wp-content/plugins/carei-reservation/includes/class-elementor-widget.php

<acceptance_criteria>

AC-1: Obsługa wygasłego tokenu JWT

Given formularz jest otwarty i token JWT serwera wygasł (>1h)
When użytkownik wysyła formularz lub zmienia segment/extras
Then system automatycznie odświeża token i ponawia request (retry 1x)
  And użytkownik nie widzi błędu tokenu — flow kontynuuje normalnie

AC-2: Obsługa braku dostępności pojazdu

Given użytkownik wypełnił formularz i jest na ekranie podsumowania
When API makebooking zwraca rejectReason CAR_NOT_FOUND
Then wyświetla się czytelny komunikat "Brak dostępnego pojazdu w wybranym terminie. Zmień daty lub segment."
  And przycisk "Wróć do formularza" jest aktywny
  And użytkownik może wrócić i zmienić dane

AC-3: Obsługa timeoutów i błędów sieciowych

Given dowolny request API trwa >15s lub sieć jest niedostępna
When fetch rzuca timeout lub network error
Then wyświetla się komunikat "Wystąpił problem z połączeniem. Spróbuj ponownie."
  And przycisk submit/confirm wraca do stanu aktywnego
  And formularz nie jest zablokowany

AC-4: Animacje przejść między krokami

Given użytkownik jest na formularzu
When przechodzi do podsumowania (submit) lub do success (confirm)
Then przejście jest animowane (fade out → fade in, ~300ms)
  And przy powrocie z podsumowania do formularza również jest animacja

AC-5: Accessibility — ARIA i focus management

Given użytkownik otwiera modal
When modal się otwiera
Then focus przenosi się na pierwszy interaktywny element modalu
  And modal ma role="dialog" i aria-modal="true"
  And focus jest trapowany w modalu (Tab nie wychodzi poza modal)
  And po zamknięciu modalu focus wraca na przycisk trigger
  And przejście form→summary→success przenosi focus na odpowiedni heading

AC-6: Fix CSS — orphaned styles w media query

Given plik CSS ma orphaned styles poza media query (linie ~560-570)
When CSS jest naprawiony
Then style .carei-form__row--address i .carei-summary__actions są wewnątrz @media (max-width: 768px)
  And nie ma podwójnego zamknięcia } na końcu media query

</acceptance_criteria>

Task 1: Edge cases — token retry, timeout, lepsze error messages wp-content/plugins/carei-reservation/assets/js/carei-reservation.js 1. **Token retry:** Wrap apiGet/apiPost — jeśli response HTTP 401 lub 403, wywołaj retry 1x (token odświeża się automatycznie po stronie PHP proxy). Dodaj flagę `isRetry` żeby nie zapętlić.
2. **Timeout:** Dodaj AbortController z timeout 15s do fetch w apiGet/apiPost. Na timeout rzuć Error z komunikatem "Przekroczono czas oczekiwania. Spróbuj ponownie."

3. **Network error:** W handleResponse/catch, rozróżnij TypeError (network) od Error (API). Na TypeError pokaż: "Brak połączenia z serwerem. Sprawdź internet i spróbuj ponownie."

4. **Rozszerz translateRejectReason:** Dodaj więcej kodów z API:
   - CUSTOMER_ALREADY_EXISTS → "Klient o tych danych już istnieje w systemie"
   - INVALID_PESEL → "Nieprawidłowy numer PESEL"
   - PRICE_LIST_EXPIRED → "Cennik wygasł. Odśwież formularz."

5. **Submit button recovery:** Upewnij się, że KAŻDY catch w createCustomerAndShowSummary i handleSummaryConfirm przywraca przyciski do stanu aktywnego.

Avoid: Nie zmieniaj endpointów API ani logiki proxy PHP. Retry tylko na 401/403, nie na inne kody.
- Symuluj offline: w DevTools Network → Offline → submit → czytelny komunikat, przycisk aktywny - Symuluj slow: Network → Slow 3G → submit → po 15s timeout message - Sprawdź że po błędzie można ponownie wysłać formularz AC-1, AC-2, AC-3 satisfied: token retry, timeout handling, network errors, rozszerzone komunikaty Task 2: Animacje przejść + fix CSS bug wp-content/plugins/carei-reservation/assets/css/carei-reservation.css, wp-content/plugins/carei-reservation/assets/js/carei-reservation.js 1. **CSS transitions:** Dodaj klasy animacji: ```css .carei-step-enter { opacity: 0; transform: translateY(10px); } .carei-step-active { opacity: 1; transform: translateY(0); transition: opacity 0.3s ease, transform 0.3s ease; } .carei-step-exit { opacity: 0; transform: translateY(-10px); transition: opacity 0.2s ease, transform 0.2s ease; } ```
2. **JS transitions:** W showSummaryOverlay(), handleSummaryBack(), showSuccessView():
   - Dodaj klasę `carei-step-exit` do wychodzącego elementu
   - Po 200ms (transitionend lub setTimeout): hide wychodzący, show wchodzący z `carei-step-enter`
   - Po 1 frame (requestAnimationFrame): zamień `carei-step-enter` na `carei-step-active`

3. **Modal open animation:** Dodaj fade-in na overlay (.carei-modal-overlay) i scale na .carei-modal:
   ```css
   .carei-modal-overlay { opacity: 0; transition: opacity 0.3s ease; }
   .carei-modal-overlay.is-open { opacity: 1; }
   .carei-modal { transform: scale(0.95); transition: transform 0.3s ease; }
   .carei-modal-overlay.is-open .carei-modal { transform: scale(1); }
   ```
   Zmień display:none/flex na visibility+opacity pattern (display:flex zawsze, visibility:hidden gdy nie is-open).

4. **Fix CSS bug:** Linie ~558-570 — orphaned styles po zamknięciu media query 768px. Przenieś `.carei-form__row--address`, `.carei-summary__actions`, `.carei-summary__btn` do wnętrza `@media (max-width: 768px)` i usuń dodatkowy `}`.

Avoid: Nie dodawaj żadnych bibliotek animacji. Czyste CSS transitions + JS class toggle.
- Otwórz modal: smooth fade-in + scale - Submit formularz: form fade out → summary fade in - "Wróć": summary fade out → form fade in - "Potwierdź": summary fade out → success fade in - Sprawdź w DevTools że nie ma CSS parse errors AC-4 satisfied: animacje przejść. AC-6 satisfied: CSS bug naprawiony. Task 3: Accessibility — ARIA, focus trap, focus management wp-content/plugins/carei-reservation/includes/class-elementor-widget.php, wp-content/plugins/carei-reservation/assets/js/carei-reservation.js 1. **PHP widget — ARIA attrs:** - Modal overlay div: dodaj `role="dialog"` `aria-modal="true"` `aria-labelledby="carei-modal-title"` - Close button: dodaj `aria-label="Zamknij formularz"` - Form sections: dodaj `role="group"` z `aria-label` na sekcjach (dane rezerwacji, dane osobowe, opcje) - Submit button: dodaj `aria-busy="false"` (JS zmieni na true podczas loading) - Summary confirm: dodaj `aria-busy="false"`
2. **JS — Focus management:**
   - openModal(): po otwarciu, focus na pierwszy select (segmentSelect) lub na modal-title
   - closeModal(): zapisz `lastFocusedElement` przed open, przywróć focus po close
   - showSummaryOverlay(): focus na .carei-summary__title
   - showSuccessView(): focus na .carei-success__title
   - handleSummaryBack(): focus na segmentSelect

3. **JS — Focus trap:**
   - W openModal(), dodaj keydown listener na modal:
   - Zbierz wszystkie focusable elements w modalu
   - Na Tab z ostatniego → focus na pierwszy
   - Na Shift+Tab z pierwszego → focus na ostatni
   - Usuń trap w closeModal()

4. **JS — aria-busy:**
   - setSubmitState('loading'): dodaj aria-busy="true" na submit button
   - setSubmitState('ready'): dodaj aria-busy="false"
   - Analogicznie dla summaryConfirm

5. **Announcements:** Dodaj aria-live="polite" region (sr-only) do modalu. Announce:
   - "Ładowanie podsumowania..." przy submit
   - "Rezerwacja potwierdzona" przy success
   - Błędy API

Avoid: Nie dodawaj aria-label do elementów które mają visible text. Nie rób z formularza role="form" (natywny <form> wystarczy).
- Tab przez formularz: focus nie wychodzi poza modal - Submit → focus na heading podsumowania - Confirm → focus na heading success - Close modal → focus wraca na trigger button - Screen reader: ogłasza "Ładowanie...", "Rezerwacja potwierdzona", błędy AC-5 satisfied: ARIA attrs, focus trap, focus management, aria-live announcements Edge cases, animacje przejść, accessibility — pełny polish formularza 1. Otwórz https://carei.pagedev.pl 2. Kliknij "Złóż zapytanie o rezerwację" — modal fade-in smooth 3. Tab przez formularz — focus nie wychodzi poza modal 4. Wypełnij formularz i wyślij — form animuje się do summary 5. Kliknij "Wróć do formularza" — animacja powrotu 6. Wyślij ponownie → Potwierdź → success z animacją 7. Zamknij modal → focus wraca na przycisk trigger 8. Test offline: DevTools → Network → Offline → submit → komunikat błędu 9. Test mobile: responsive 375px — form działa, animacje smooth Type "approved" to continue, or describe issues to fix

DO NOT CHANGE

  • wp-content/plugins/carei-reservation/includes/class-softra-api.php (API proxy stable)
  • wp-content/plugins/carei-reservation/includes/class-rest-proxy.php (REST endpoints stable)
  • .env (credentials)
  • Logika API endpoints (segments-branches-map, pricelist, customer, booking)

SCOPE LIMITS

  • Nie dodawaj nowych endpointów API
  • Nie zmieniaj flow rezerwacji (customer → pricing → booking → confirm)
  • Nie dodawaj bibliotek zewnętrznych
  • Nie implementuj e2e test framework — weryfikacja manualna na produkcji
  • Nie dodawaj ubezpieczenia ani wyjazdu zagranicznego (backlog)
Before declaring plan complete: - [ ] Formularz działa end-to-end bez regresji - [ ] Token retry: 401 → retry → success - [ ] Timeout 15s: komunikat, przycisk aktywny - [ ] Network error: komunikat, przycisk aktywny - [ ] CAR_NOT_FOUND: czytelny komunikat PL - [ ] Animacje: modal open, form→summary, summary→form, summary→success - [ ] Focus: modal open → focus w modalu, close → focus na trigger - [ ] Focus trap: Tab nie wychodzi poza modal - [ ] ARIA: role=dialog, aria-modal, aria-busy, aria-live - [ ] CSS: brak orphaned styles, media queries poprawne - [ ] Mobile 375px: responsive OK

<success_criteria>

  • All 6 acceptance criteria met
  • All verification checks pass
  • No regressions in booking flow
  • Human verification approved on carei.pagedev.pl </success_criteria>
After completion, create `.paul/phases/04-polish-testing/04-01-SUMMARY.md`