Files
carei.pagedev.pl/.paul/phases/07-hero-search-form/07-01-PLAN.md
Jacek Pyziak 92a58cb2e2 feat(07-hero-search-form): Mini formularz rezerwacji w hero z pre-fill do modala
Phase 7 complete:
- Nowy widget Elementor "Carei Search Form" do osadzenia w hero
- Pola: segment, daty od/do, lokalizacja, checkbox zwrotu
- Po kliknięciu przycisku otwiera modal z pre-wypełnionymi danymi
- Design zgodny z Figmą (tło #EDEDF3, przycisk czerwony, tytuł fioletowy)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 13:50:22 +02:00

12 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
07-hero-search-form 01 execute 1
wp-content/plugins/carei-reservation/includes/class-search-widget.php
wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
wp-content/plugins/carei-reservation/carei-reservation.php
false
## Goal Nowy widget Elementor "Carei Search Form" — kompaktowy mini formularz rezerwacji do osadzenia w sekcji hero. Po wypełnieniu i kliknięciu przycisku otwiera istniejący popup formularza rezerwacji z automatycznie uzupełnionymi danymi (segment, daty, lokalizacja).

Purpose

Użytkownik widzi formularz już na hero — nie musi szukać przycisku rezerwacji. Skraca ścieżkę konwersji i daje natychmiastowe CTA.

Output

  • Nowy plik: class-search-widget.php (widget Elementor)
  • Rozszerzony CSS: style mini formularza
  • Rozszerzony JS: logika prefill + otwarcie modala z danymi z mini formularza
  • Rejestracja widgetu w carei-reservation.php
## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md

Source Files

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

<acceptance_criteria>

AC-1: Widget renderuje mini formularz

Given strona z osadzonym widgetem "Carei Search Form" w Elementorze
When strona się ładuje
Then widoczny jest kompaktowy formularz z polami: segment (select), daty od/do, miejsce odbioru (select), checkbox "Zwrot w tej samej lokalizacji", przycisk "Złóż zapytanie o rezerwację"

AC-2: Selecty ładują dane z API

Given mini formularz jest widoczny na stronie
When strona się załadowała
Then select segmentu zawiera segmenty z API (segments-branches-map)
And select lokalizacji filtruje się po wybranym segmencie

AC-3: Przycisk otwiera modal z pre-wypełnionymi danymi

Given użytkownik wypełnił mini formularz (segment, daty, lokalizacja)
When kliknie "Złóż zapytanie o rezerwację"
Then otwiera się istniejący modal rezerwacji
And pola segment, data od, data do, miejsce odbioru są automatycznie wypełnione wartościami z mini formularza
And checkbox zwrotu jest zsynchronizowany
And extras/pricelist ładują się automatycznie (jak po ręcznym wypełnieniu)

AC-4: Design zgodny z Figmą

Given mini formularz jest renderowany
When wyświetla się na desktop
Then tło #EDEDF3, zaokrąglone rogi 14px, border #2F2482/10%
And pola mają białe tło, zaokrąglone rogi
And przycisk jest czerwony (#FF0000) z białym tekstem, pełna szerokość
And font Albert Sans, tytuł bold fioletowy (#2F2482)

</acceptance_criteria>

Task 1: Widget Elementor + HTML mini formularza wp-content/plugins/carei-reservation/includes/class-search-widget.php, wp-content/plugins/carei-reservation/carei-reservation.php 1. Utworzyć `class-search-widget.php` z klasą `Carei_Search_Widget extends \Elementor\Widget_Base`: - name: `carei-search-form` - title: `Carei Search Form` - icon: `eicon-search` - categories: `['general']` - style/script depends: te same co główny widget (carei-reservation-css, carei-reservation-js) - Brak kontrolek Elementor (formularz jest statyczny)
2. Metoda `render()` generuje HTML:
   - Container `div.carei-search-form` z tłem
   - Tytuł: `<h2 class="carei-search-form__title">Wypełnij formularz rezerwacji<span>.</span></h2>`
   - Select segmentu: `<select id="carei-search-segment">` z placeholder "Wybierz segment" i ikoną strzałki
   - Wiersz z dwoma polami daty: `<input type="datetime-local" id="carei-search-date-from">` i `id="carei-search-date-to"` z ikonkami kalendarza i labelami "Od kiedy?" / "Do kiedy?"
   - Select lokalizacji: `<select id="carei-search-pickup">` z ikoną pinu i placeholder "Miejsce odbioru"
   - Checkbox: `<input type="checkbox" id="carei-search-same-return" checked>` z label "Zwrot w tej samej lokalizacji"
   - Przycisk: `<button type="button" class="carei-search-form__submit" id="carei-search-submit">` z tekstem "Złóż zapytanie o rezerwację"

3. Zarejestrować widget w `carei-reservation.php`:
   - Dodać `require_once` w callbacku `elementor/widgets/register`
   - `$widgets_manager->register( new Carei_Search_Widget() );`

Avoid: Duplikowanie modala — mini formularz NIE zawiera modala. Modal jest renderowany przez istniejący widget Carei Reservation, który musi być obecny na tej samej stronie.
Widget "Carei Search Form" widoczny w panelu Elementor, po osadzeniu renderuje HTML mini formularza AC-1 satisfied: Mini formularz renderuje się z wszystkimi polami Task 2: JavaScript — ładowanie danych + prefill + otwarcie modala wp-content/plugins/carei-reservation/assets/js/carei-reservation.js 1. W sekcji inicjalizacji (DOMContentLoaded) dodać wykrywanie mini formularza: ``` var searchForm = document.querySelector('.carei-search-form'); ``` Jeśli istnieje, zainicjalizować `initSearchForm()`.
2. Funkcja `initSearchForm()`:
   - Pobrać referencje do elementów: `carei-search-segment`, `carei-search-date-from`, `carei-search-date-to`, `carei-search-pickup`, `carei-search-same-return`
   - Załadować dane API (segments-branches-map) — REUŻYĆ istniejącą logikę `loadInitialData`, ale populować selecty mini formularza
   - Podpiąć event na zmianę segmentu → filtrowanie lokalizacji (jak w głównym formularzu)
   - Podpiąć event na `#carei-search-submit` click:
     a) Zebrać wartości z mini formularza
     b) Znaleźć overlay modala: `document.querySelector('[data-carei-modal]')`
     c) Wywołać `openModal()` (istniejąca funkcja)
     d) Po otwarciu modala (setTimeout ~100ms po openModal) ustawić wartości w głównym formularzu:
        - `segmentSelect.value = searchSegment` + dispatch 'change' event
        - `dateFrom.value = searchDateFrom` + dispatch 'change'
        - `dateTo.value = searchDateTo` + dispatch 'change'
        - `pickupSelect` — poczekać aż lokalizacje się załadują po change segmentu, potem ustawić wartość
        - `sameReturnCheck.checked = searchSameReturn`
     e) Triggerować `loadExtras()` jeśli wszystkie wymagane pola wypełnione

3. Problem z timingiem: po ustawieniu segmentu, lokalizacje ładują się asynchronicznie. Rozwiązanie:
   - Dodać callback/promise lub event `carei:branches-loaded` który dispatch-uje się po załadowaniu lokalizacji
   - W prefill poczekać na ten event, potem ustawić pickupSelect.value

4. Osobna inicjalizacja dat w mini formularzu — labelki "Od kiedy?"/"Do kiedy?" zachowują się jak placeholdery (widoczne gdy puste).

Avoid: 
- Nie duplikować fetchowania API — jeśli dane już załadowane (dataLoaded=true), reużyć cache
- Nie łamać istniejącej logiki modala — openModal() musi działać normalnie gdy wywoływana z przycisku `data-carei-open-modal`
Po wypełnieniu mini formularza i kliknięciu przycisku: modal się otwiera, pola segment/daty/lokalizacja są wypełnione, extras się ładują AC-2, AC-3 satisfied: Selecty ładują dane, przycisk otwiera modal z pre-fill Task 3: CSS — stylowanie mini formularza zgodne z Figmą wp-content/plugins/carei-reservation/assets/css/carei-reservation.css Dodać style dla `.carei-search-form` na końcu pliku CSS:
1. Container `.carei-search-form`:
   - background: #EDEDF3
   - border-radius: 14px
   - border: 1px solid rgba(47, 36, 130, 0.1)
   - padding: ~24px 28px
   - max-width: 422px (z Figmy: width 422px)
   - box-shadow: subtletny drop shadow

2. Tytuł `.carei-search-form__title`:
   - font-family: 'Albert Sans', sans-serif
   - font-weight: 700
   - color: #2F2482
   - text-align: center
   - span (kropka): color: #FF0000

3. Pola formularza `.carei-search-form__field`:
   - background: #fff
   - border-radius: 8px
   - border: 1px solid #E0E0E0
   - padding: 12px 16px
   - font-size: 14px
   - Selecty: appearance: none + custom arrow icon
   - Daty: dwa pola obok siebie (flex row, gap)

4. Checkbox `.carei-search-form__checkbox`:
   - Styl jak w głównym formularzu (custom checkbox box z SVG checkmark)
   - Kolor checked: #2F2482

5. Przycisk `.carei-search-form__submit`:
   - background: #FF0000
   - color: #fff
   - border-radius: 8px
   - width: 100%
   - padding: 14px
   - font-weight: 600
   - ikona strzałki przed tekstem
   - hover: lekkie przyciemnienie

6. Responsive:
   - Na mobile (< 768px): max-width: 100%, padding zmniejszony
   - Pola dat: mogą być w kolumnie na bardzo wąskich ekranach (< 400px)

Avoid: Nie modyfikować istniejących styli modala/formularza — dodać TYLKO nowe reguły z prefiksem `.carei-search-form`
Mini formularz wygląda zgodnie z designem z Figmy: tło szare, pola białe, przycisk czerwony, tytuł fioletowy AC-4 satisfied: Design zgodny z Figmą Mini formularz rezerwacji w hero z pre-fill do modala 1. Otwórz stronę w Elementorze, osadź widget "Carei Search Form" w sekcji hero 2. Na tej samej stronie musi być osadzony widget "Carei Reservation" (renderuje modal) 3. Podgląd strony: - Mini formularz widoczny z polami segment, daty, lokalizacja, checkbox - Wybierz segment → lokalizacje się filtrują - Wypełnij daty i lokalizację - Kliknij "Złóż zapytanie o rezerwację" - Modal się otwiera z wypełnionymi danymi - Extras ładują się automatycznie 4. Sprawdź design: tło szare, pola białe, przycisk czerwony 5. Sprawdź mobile: formularz responsywny Type "approved" to continue, or describe issues to fix

DO NOT CHANGE

  • includes/class-elementor-widget.php — HTML modala pozostaje bez zmian
  • includes/class-softra-api.php — logika API bez zmian
  • includes/class-rest-proxy.php — endpointy REST bez zmian
  • includes/class-admin-panel.php — panel admina bez zmian

SCOPE LIMITS

  • Mini formularz NIE ma własnego modala — korzysta z modala renderowanego przez istniejący widget
  • Brak walidacji w mini formularzu — walidacja jest w głównym formularzu
  • Brak pól danych osobowych w mini formularzu — tylko dane wynajmu
  • Nie dodawać nowych zależności npm/composer
Before declaring plan complete: - [ ] Widget "Carei Search Form" widoczny w panelu Elementor - [ ] Mini formularz renderuje się na stronie z prawidłowym designem - [ ] Selecty segmentu i lokalizacji ładują dane z API - [ ] Kliknięcie przycisku otwiera modal z pre-wypełnionymi danymi - [ ] Istniejący przycisk `data-carei-open-modal` nadal działa normalnie - [ ] Responsive: formularz poprawny na mobile - [ ] Brak błędów JS w konsoli

<success_criteria>

  • Widget osadzony w Elementorze renderuje mini formularz
  • Dane z mini formularza poprawnie przenoszone do modala
  • Design zgodny z Figmą
  • Istniejąca funkcjonalność modala nienaruszona </success_criteria>
After completion, create `.paul/phases/07-hero-search-form/07-01-SUMMARY.md`