diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..9d8fa1e
Binary files /dev/null and b/.DS_Store differ
diff --git a/.paul/PROJECT.md b/.paul/PROJECT.md
index 4b7ef46..7906521 100644
--- a/.paul/PROJECT.md
+++ b/.paul/PROJECT.md
@@ -44,7 +44,6 @@ Plugin Elementor do rezerwacji samochodu na stronie carei.pagedev.pl, zintegrowa
## Out of Scope (backlog)
- Ubezpieczenie (pakiet Soft/Premium) — czeka na API Softra
-- Wyjazd zagraniczny (lista krajów + ceny) — czeka na API Softra
- Eksport CSV/PDF rezerwacji
- Email notyfikacje
diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md
index 18aa4d5..32d17bd 100644
--- a/.paul/ROADMAP.md
+++ b/.paul/ROADMAP.md
@@ -19,6 +19,18 @@ Edge cases (token retry, timeout, network errors), animacje przejść form↔sum
### Phase 5: Admin Panel — Historia Formularzy ✅ Complete
CPT `carei_reservation` z automatycznym zapisem po booking, lista z kolumnami i filtrem statusu, meta box szczegółów, system statusów nowe/przeczytane/zrealizowane, auto-mark-read.
+---
+
+## Milestone v0.2: Wyjazd Zagraniczny
+
+**Goal:** Wydzielenie pozycji "WYJAZD ZA GRANICĘ" z opcji dodatkowych do dedykowanej sekcji z wyszukiwarką krajów (zgodnie z Figmą).
+
+**Status:** In progress
+
+### Phase 6: Wyjazd zagraniczny — sekcja + wyszukiwarka krajów 🔄 Planning
+Sekcja "Wyjazd zagraniczny" z checkboxem toggle, wyszukiwarką krajów z flagami/cenami, dodawanie/usuwanie krajów, integracja z API submit. Design z Figmy (node 32-397, 122:1054, 122:1091, 123:1195).
+
+---
+
### Backlog (do realizacji gdy API będzie gotowe)
-- **Wyjazd zagraniczny:** Checkbox "Planuję trasę poza granicę Polski" + wyszukiwarka krajów z cenami. Wymaga endpointu listy krajów i cennika per kraj w API Softra.
- **Ubezpieczenie:** Sekcja "Pakiet ochrony Soft/Premium" jak na Figmie. Wymaga dedykowanych pozycji ubezpieczeniowych w API pricelist.
diff --git a/.paul/STATE.md b/.paul/STATE.md
index 4d65271..3a84a1a 100644
--- a/.paul/STATE.md
+++ b/.paul/STATE.md
@@ -2,35 +2,33 @@
## Current Position
-Milestone: v0.1 Formularz Rezerwacji MVP — COMPLETE
-Phase: 5 of 5 (Admin Panel — Historia Formularzy) — Complete
-Plan: 05-01 — Complete
-Status: Milestone v0.1 complete — all 5 phases finished
-Last activity: 2026-03-25 — Phase 5 unified, milestone complete
+Milestone: v0.2 Wyjazd Zagraniczny
+Phase: 6 of 6 (Wyjazd zagraniczny — sekcja + wyszukiwarka krajów) — Planning
+Plan: 06-01 created, awaiting approval
+Status: PLAN created, ready for APPLY
+Last activity: 2026-03-30 — Created .paul/phases/06-wyjazd-zagraniczny/06-01-PLAN.md
Progress:
-- Milestone: [██████████] 100% ✅
-- Phase 1: [██████████] 100% ✅
-- Phase 2: [██████████] 100% ✅
-- Phase 3: [██████████] 100% ✅
-- Phase 4: [██████████] 100% ✅
-- Phase 5: [██████████] 100% ✅
+- Milestone v0.1: [██████████] 100% ✅
+- Milestone v0.2: [░░░░░░░░░░] 0%
+- Phase 6: [░░░░░░░░░░] 0%
## Loop Position
Current loop state:
```
PLAN ──▶ APPLY ──▶ UNIFY
- ✓ ✓ ✓ [Loop complete — milestone v0.1 finished]
+ ✓ ○ ○ [Plan created, awaiting approval]
```
## Session Continuity
-Last session: 2026-03-25
-Stopped at: Milestone v0.1 complete — all phases unified
-Next action: /paul:complete-milestone or start next milestone
-Resume file: .paul/ROADMAP.md
+Last session: 2026-03-30
+Stopped at: Plan 06-01 created
+Next action: Review and approve plan, then run /paul:apply .paul/phases/06-wyjazd-zagraniczny/06-01-PLAN.md
+Resume file: .paul/phases/06-wyjazd-zagraniczny/06-01-PLAN.md
Resume context:
-- All 5 phases complete: skeleton, form UI, booking flow, polish, admin panel
-- Plugin fully functional: formularz → API Softra → admin panel
-- Backlog: ubezpieczenie + wyjazd zagraniczny (czeka na API)
+- v0.1 complete (5 phases)
+- v0.2 Phase 6: wyjazd zagraniczny — wydzielenie WYJAZD ZA GRANICĘ z extras do dedykowanej sekcji z wyszukiwarką krajów
+- Dane krajów z istniejącego pricelist API (additionalItems z nazwą WYJAZD ZA GRANIC...)
+- Design z Figmy: checkbox toggle + wyszukiwarka z flagami/cenami + karty krajów
diff --git a/.paul/phases/06-wyjazd-zagraniczny/06-01-PLAN.md b/.paul/phases/06-wyjazd-zagraniczny/06-01-PLAN.md
new file mode 100644
index 0000000..bf05ca7
--- /dev/null
+++ b/.paul/phases/06-wyjazd-zagraniczny/06-01-PLAN.md
@@ -0,0 +1,282 @@
+---
+phase: 06-wyjazd-zagraniczny
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - 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
+autonomous: false
+---
+
+
+## Goal
+Wydzielić pozycje "WYJAZD ZA GRANICĘ ..." z sekcji "Opcje dodatkowe" do osobnej sekcji "Wyjazd zagraniczny" z checkboxem "Planuję trasę poza granicę Polski" i interaktywną wyszukiwarką krajów zgodną z Figmą.
+
+## Purpose
+Użytkownik chcący zarezerwować samochód z wyjazdem za granicę powinien mieć dedykowaną, intuicyjną sekcję zamiast listy checkboxów zagubionych wśród opcji dodatkowych. Design Figmy przewiduje wyszukiwarkę krajów z flagami, cenami i możliwością dodawania/usuwania — lepsze UX niż surowe checkboxy.
+
+## Output
+- Sekcja "Wyjazd zagraniczny" z checkboxem toggle
+- Wyszukiwarka krajów z 3 stanami (default, active, z wybranymi)
+- Karty krajów z flagą, nazwą, ceną, przyciskiem +/×
+- Wybrane kraje trafiają do API jako extras przy submit
+
+
+
+## Project Context
+@.paul/PROJECT.md
+@.paul/ROADMAP.md
+@.paul/STATE.md
+
+## Prior Work
+@.paul/phases/02-form-ui/02-01-SUMMARY.md — struktura formularza (opcje dodatkowe, loadExtras)
+
+## Source Files
+@wp-content/plugins/carei-reservation/includes/class-elementor-widget.php — HTML formularza (linia 126-143: extras wrapper)
+@wp-content/plugins/carei-reservation/assets/js/carei-reservation.js — loadExtras() linia 315-346, buildExtraCard() linia 348-364, getSelectedExtrasForApi() linia 588-604
+@wp-content/plugins/carei-reservation/assets/css/carei-reservation.css — style extra-card (linia 390-429)
+
+## Design Reference
+@docs/figma-formularz/README.md — sekcja "Wyjazd zagraniczny" (linia 113-117) + wyszukiwarka krajów (linia 146-177)
+@docs/figma-formularz/input-wyszukiwarka-krajow.jsx — stany wyszukiwarki, karty krajów, kolory
+@docs/figma-formularz/screenshot-popup-desktop.png
+@docs/figma-formularz/screenshot-input-kraje-stany.png
+
+
+
+No SPECIAL-FLOWS.md — skills section omitted.
+
+
+
+
+## AC-1: Pozycje WYJAZD ZA GRANICĘ nie pojawiają się w Opcjach dodatkowych
+```gherkin
+Given formularz z załadowanym cennikiem z API
+When pricelist zawiera pozycje zaczynające się od "WYJAZD ZA GRANIC"
+Then te pozycje NIE wyświetlają się w sekcji "Opcje dodatkowe"
+And wyświetlają się TYLKO w sekcji "Wyjazd zagraniczny"
+```
+
+## AC-2: Sekcja "Wyjazd zagraniczny" z checkboxem toggle
+```gherkin
+Given formularz z załadowanymi extras
+When użytkownik widzi sekcję "Wyjazd zagraniczny"
+Then widoczny jest checkbox "Planuję trasę poza granicę Polski"
+And wyszukiwarka krajów jest UKRYTA dopóki checkbox nie jest zaznaczony
+When użytkownik zaznacza checkbox
+Then wyszukiwarka krajów pojawia się z animacją
+When użytkownik odznacza checkbox
+Then wyszukiwarka znika i wybrane kraje się czyszczą
+```
+
+## AC-3: Wyszukiwarka krajów — wyszukiwanie i dodawanie
+```gherkin
+Given checkbox "Planuję trasę..." jest zaznaczony
+When użytkownik widzi domyślny stan wyszukiwarki
+Then widzi ikonę "+" i tekst "Wyszukaj i dodaj kraj na trasie"
+When użytkownik klika pole i wpisuje tekst (np. "Nie")
+Then pod polem pojawiają się karty krajów pasujących do frazy
+And każda karta ma: flagę (emoji/obraz), nazwę kraju, cenę "od X do Y zł", przycisk "+"
+When użytkownik klika "+" na karcie kraju
+Then kraj zostaje dodany do listy wybranych (karta zmienia styl na selected, "+" → "×")
+```
+
+## AC-4: Wybrane kraje trafiają do API przy submit
+```gherkin
+Given użytkownik wybrał kraje w wyszukiwarce (np. Niemcy, Czechy)
+When formularz jest submitowany
+Then getSelectedExtrasForApi() zawiera pozycje z pricelist odpowiadające wybranym krajom
+And pricing summary i booking zawierają te pozycje
+```
+
+## AC-5: Design zgodny z Figmą
+```gherkin
+Given sekcja "Wyjazd zagraniczny" jest wyświetlona
+Then separator "Wyjazd zagraniczny" ma taki sam styl jak inne separatory
+And karty krajów mają: border-radius 8px, nazwę w #2F2482 Albert Sans SemiBold 15px, cenę w #505050
+And wybrany kraj ma tło rgba(47,36,130,0.05), border rgba(47,36,130,0.2)
+And pole wyszukiwarki ma 48px wysokości, border-radius 8px
+```
+
+
+
+
+
+
+ Task 1: HTML sekcji "Wyjazd zagraniczny" + filtrowanie w JS
+ wp-content/plugins/carei-reservation/includes/class-elementor-widget.php, wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
+
+ **PHP (class-elementor-widget.php):**
+ Dodać nową sekcję HTML PRZED sekcją "Opcje dodatkowe" (między linią 135 "Ubezpieczenie" a linią 136 "Opcje dodatkowe"):
+
+ ```
+
Wyjazd zagraniczny
+
+
+
+
+
+
+
+
+
+
+
+ ```
+
+ **JS (carei-reservation.js) — modyfikacja loadExtras():**
+ W pętli `items.forEach()` (linia 329-341) dodać trzecią kategorię:
+ - Jeśli `name` zaczyna się od "wyjazd za granic" → `abroadItems.push(item)` (NIE do extraItems)
+ - Parsować nazwę kraju z item.name (np. "WYJAZD ZA GRANICĘ - NIEMCY" → "Niemcy")
+ - Przechowywać `abroadItems` w zmiennej modułowej (dostępnej dla wyszukiwarki)
+
+ Po załadowaniu — NIE renderować abroadItems jako checkboxów. Zamiast tego, zachować dane w pamięci JS do użycia przez wyszukiwarkę.
+
+ Avoid: Nie usuwać istniejącej logiki insurance/extras — tylko dodać nową kategorię w `forEach`.
+
+
+ 1. Otworzyć formularz, wybrać segment i oddział
+ 2. Pozycje "WYJAZD ZA GRANICĘ ..." NIE pojawiają się w "Opcje dodatkowe"
+ 3. Widoczna sekcja "Wyjazd zagraniczny" z checkboxem
+
+ AC-1 satisfied: pozycje WYJAZD nie lądują w Opcjach dodatkowych. AC-2 partially: sekcja HTML istnieje.
+
+
+
+ Task 2: Wyszukiwarka krajów — interakcje JS + style CSS
+ wp-content/plugins/carei-reservation/assets/js/carei-reservation.js, wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
+
+ **JS — nowy blok "Abroad Country Search":**
+
+ 1. **Toggle checkbox:** Listener na `#carei-abroad-toggle`:
+ - checked → `#carei-abroad-search` display:block (slide down)
+ - unchecked → hide + wyczyść selected countries
+
+ 2. **Mapowanie krajów na flagi:** Obiekt `COUNTRY_FLAGS` z emoji flagami dla typowych krajów (Niemcy 🇩🇪, Czechy 🇨🇿, Norwegia 🇳🇴, etc.). Fallback: flaga 🏳️.
+
+ 3. **Wyszukiwanie:** Input event na `#carei-abroad-input`:
+ - Filtruj `abroadItems` po nazwie kraju (case-insensitive, includes)
+ - Renderuj karty wyników w `#carei-abroad-results` (2 kolumny CSS grid)
+ - Karta: flaga (emoji 24px) + nazwa kraju + cena "od X do Y zł" + przycisk "+"
+ - Już wybrane kraje w wynikach → styl selected (bg/border Figma) + przycisk "×"
+ - Puste pole = nie pokazuj wyników (stan default)
+
+ 4. **Dodawanie kraju ("+"):**
+ - Dodaj do `selectedCountries` Map (id → item)
+ - Przerenderuj wyniki (kraj zmienia się na selected)
+ - Przerenderuj `#carei-abroad-selected` — lista wybranych pod wyszukiwarką
+
+ 5. **Usuwanie kraju ("×"):**
+ - Usuń z `selectedCountries`
+ - Przerenderuj wyniki i selected
+
+ 6. **Integracja z getSelectedExtrasForApi():**
+ Zmodyfikować `getSelectedExtrasForApi()` (linia 588-604) — oprócz `extras[]` checkboxów, dołączyć kraje z `selectedCountries` Map w tym samym formacie:
+ ```js
+ selectedCountries.forEach(function(item) {
+ items.push({ id: item.id || item.code, name: item.name, ... });
+ });
+ ```
+
+ **CSS — nowe reguły `.carei-abroad`:**
+
+ Zgodne z Figmą (docs/figma-formularz):
+ - `.carei-abroad__input-wrap`: height 48px, border-radius 8px, border 1px #D0D0D0, flex, gap 8px, padding 0 16px, align-items center
+ - `.carei-abroad__input`: no border, flex 1, Albert Sans SemiBold 15px, color #2F2482, placeholder color #C7C7C7
+ - `.carei-abroad__plus-icon`: 16px, color #2F2482
+ - `.carei-abroad__results`: display grid, grid-template-columns 1fr 1fr, gap 8px, margin-top 8px
+ - `.carei-abroad__card`: height 56px, border-radius 8px, border 1px rgba(0,0,0,0.1), flex, align-items center, padding 0 12px, gap 8px
+ - `.carei-abroad__card--selected`: background rgba(47,36,130,0.05), border-color rgba(47,36,130,0.2)
+ - `.carei-abroad__flag`: width 24px, height 24px, border-radius 50%, font-size 20px, line-height 24px, text-align center
+ - `.carei-abroad__name`: Albert Sans SemiBold 15px, color #2F2482, flex 1
+ - `.carei-abroad__price`: text-align right, color #505050 (format: "od" 10px + wartość 14px + "do" 10px + wartość 14px + "zł")
+ - `.carei-abroad__action`: 16px button, cursor pointer, no bg/border
+ - `.carei-abroad__selected`: margin-top 8px, flex column, gap 8px
+
+ Mobile (max-width 600px):
+ - `.carei-abroad__results`: grid-template-columns 1fr (1 kolumna)
+
+ Avoid: Nie modyfikować istniejących stylów `.carei-form__extra-card`. Nowe klasy `.carei-abroad__*`.
+
+
+ 1. Zaznacz checkbox "Planuję trasę..." → wyszukiwarka się pojawia
+ 2. Wpisz "Niem" → pojawia się karta Niemcy z flagą, ceną, "+"
+ 3. Kliknij "+" → Niemcy zmienia styl na selected, pojawia się w liście wybranych z "×"
+ 4. Kliknij "×" → kraj usunięty
+ 5. Odznacz checkbox → wyszukiwarka znika, wybrane kraje się czyszczą
+ 6. Submit z wybranym krajem → pricing summary zawiera pozycję WYJAZD
+
+ AC-2, AC-3, AC-4, AC-5 satisfied: pełna interakcja wyszukiwarki, integracja z API, design Figma
+
+
+
+ Sekcja "Wyjazd zagraniczny" z wyszukiwarką krajów w popup rezerwacji
+
+ 1. Otwórz stronę z formularzem rezerwacji
+ 2. Wybierz segment i oddział (żeby załadować extras)
+ 3. Sprawdź: pozycje "WYJAZD ZA GRANICĘ ..." NIE widać w "Opcje dodatkowe"
+ 4. Sprawdź: widoczna sekcja "Wyjazd zagraniczny" z checkboxem
+ 5. Zaznacz "Planuję trasę poza granicę Polski" → wyszukiwarka się pojawia
+ 6. Wpisz fragment nazwy kraju → karty z flagami i cenami
+ 7. Dodaj kraj (+) → karta się podświetla, pojawia się w liście wybranych
+ 8. Usuń kraj (×) → znika z wybranych
+ 9. Odznacz checkbox → wszystko się czyści
+ 10. Zaznacz, dodaj kraje, submit → w summary widać pozycje WYJAZD
+ 11. Sprawdź responsywność na mobile (1 kolumna kart)
+ 12. Porównaj wygląd z Figmą (kolory, fonty, spacing)
+
+ Type "approved" to continue, or describe issues to fix
+
+
+
+
+
+
+## DO NOT CHANGE
+- wp-content/plugins/carei-reservation/includes/class-softra-api.php (API client — nie wymaga zmian)
+- wp-content/plugins/carei-reservation/includes/class-rest-proxy.php (REST proxy — nie wymaga zmian)
+- wp-content/plugins/carei-reservation/includes/class-admin-panel.php (Admin panel — osobna funkcjonalność)
+- Istniejąca logika ubezpieczeń (filtrowanie ubezp/ochrony w loadExtras)
+- Istniejąca logika buildExtraCard() — nie modyfikować, nowe karty mają osobny builder
+- Istniejące style .carei-form__extra-card — nie modyfikować
+
+## SCOPE LIMITS
+- Nie dodawać prawdziwych obrazów flag (emoji wystarczą na MVP)
+- Nie tworzyć osobnego API endpoint do krajów — dane z istniejącego pricelist
+- Nie modyfikować logiki booking/confirm — tylko getSelectedExtrasForApi()
+- Nie dodawać walidacji "minimum 1 kraj wybrany" — checkbox sam w sobie jest opcjonalny
+- Summary overlay — wystarczy że kraje pojawią się jako standardowe pozycje extras
+
+
+
+
+Before declaring plan complete:
+- [ ] Pozycje "WYJAZD ZA GRANIC..." nie pojawiają się w "Opcje dodatkowe"
+- [ ] Sekcja "Wyjazd zagraniczny" wyświetla się z separatorem i checkboxem
+- [ ] Toggle checkbox pokazuje/ukrywa wyszukiwarkę
+- [ ] Wyszukiwanie filtruje kraje w real-time
+- [ ] Dodawanie/usuwanie krajów działa poprawnie
+- [ ] Wybrane kraje trafiają do getSelectedExtrasForApi()
+- [ ] Pricing summary zawiera pozycje WYJAZD dla wybranych krajów
+- [ ] Mobile: karty w 1 kolumnie
+- [ ] Brak błędów w konsoli JS
+
+
+
+- All tasks completed
+- All verification checks pass
+- No errors or warnings introduced
+- Design wizualnie zgodny z Figmą (kolory, spacing, typografia)
+- Istniejąca funkcjonalność (ubezpieczenie, opcje dodatkowe, booking flow) nienaruszona
+
+
+
diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json
index 1817d6f..9ba4c58 100644
--- a/.vscode/ftp-kr.sync.cache.json
+++ b/.vscode/ftp-kr.sync.cache.json
@@ -123,16 +123,22 @@
},
"handoffs": {
"archive": {
+ "HANDOFF-2026-03-25.md": {
+ "type": "-",
+ "size": 3911,
+ "lmtime": 1774394933000,
+ "modified": false
+ },
"HANDOFF-2026-03-25-phase3.md": {
"type": "-",
"size": 3672,
"lmtime": 1774440974369,
"modified": false
},
- "HANDOFF-2026-03-25.md": {
+ "HANDOFF-2026-03-25-phase5.md": {
"type": "-",
- "size": 3911,
- "lmtime": 1774394933000,
+ "size": 4436,
+ "lmtime": 1774453504000,
"modified": false
}
}
@@ -181,25 +187,31 @@
"size": 11298,
"lmtime": 1774447717369,
"modified": false
+ },
+ "05-01-SUMMARY.md": {
+ "type": "-",
+ "size": 4697,
+ "lmtime": 1774456664870,
+ "modified": false
}
}
},
"PROJECT.md": {
"type": "-",
- "size": 2025,
- "lmtime": 0,
+ "size": 3246,
+ "lmtime": 1774456701930,
"modified": false
},
"ROADMAP.md": {
"type": "-",
- "size": 1906,
- "lmtime": 1774447405669,
+ "size": 1862,
+ "lmtime": 1774456710745,
"modified": false
},
"STATE.md": {
"type": "-",
- "size": 1376,
- "lmtime": 1774453515616,
+ "size": 1212,
+ "lmtime": 1774456724909,
"modified": false
}
},
@@ -301,8 +313,8 @@
"includes": {
"class-admin-panel.php": {
"type": "-",
- "size": 18994,
- "lmtime": 1774448051188,
+ "size": 19203,
+ "lmtime": 1774456454972,
"modified": false
},
"class-elementor-widget.php": {
diff --git a/.vscode/sftp.json b/.vscode/sftp.json
new file mode 100644
index 0000000..3f86b62
--- /dev/null
+++ b/.vscode/sftp.json
@@ -0,0 +1,11 @@
+{
+ "name": "My Server",
+ "host": "localhost",
+ "protocol": "sftp",
+ "port": 22,
+ "username": "username",
+ "remotePath": "/",
+ "uploadOnSave": false,
+ "useTempFile": false,
+ "openSsh": false
+}
diff --git a/wp-admin/.DS_Store b/wp-admin/.DS_Store
new file mode 100644
index 0000000..676ccd7
Binary files /dev/null and b/wp-admin/.DS_Store differ
diff --git a/wp-content/.DS_Store b/wp-content/.DS_Store
new file mode 100644
index 0000000..611bffa
Binary files /dev/null and b/wp-content/.DS_Store differ
diff --git a/wp-content/languages/.DS_Store b/wp-content/languages/.DS_Store
new file mode 100644
index 0000000..8f047d7
Binary files /dev/null and b/wp-content/languages/.DS_Store differ
diff --git a/wp-content/plugins/.DS_Store b/wp-content/plugins/.DS_Store
new file mode 100644
index 0000000..b9b4f1c
Binary files /dev/null and b/wp-content/plugins/.DS_Store differ
diff --git a/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css b/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
index cad203c..ed4fac7 100644
--- a/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
+++ b/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
@@ -77,6 +77,7 @@
width: 100%;
max-height: 90vh;
overflow-y: auto;
+ overflow-x: hidden;
padding: 40px 48px;
position: relative;
font-family: var(--carei-font);
@@ -93,13 +94,13 @@
background: none;
border: none;
cursor: pointer;
- color: var(--carei-gray);
+ color: #B0B0B0;
line-height: 1;
padding: 4px;
transition: color 0.2s;
}
.carei-modal-close:hover {
- color: var(--carei-blue);
+ color: #808080;
}
.carei-modal-title {
font-family: var(--carei-font);
@@ -140,7 +141,7 @@
}
.carei-form__row {
display: grid;
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--carei-gap-inner);
}
.carei-form__row--top {
@@ -217,6 +218,137 @@
color: var(--carei-gray);
}
+/* Floating label for text inputs */
+.carei-form__float-wrap {
+ position: relative;
+ height: var(--carei-input-h);
+ background: var(--carei-white);
+ border: 1px solid transparent;
+ border-radius: var(--carei-radius);
+ transition: border-color 0.2s;
+}
+.carei-form__float-wrap:focus-within {
+ border-color: var(--carei-blue);
+}
+.carei-form__float-label {
+ position: absolute;
+ left: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ font-family: var(--carei-font);
+ font-weight: 400;
+ font-size: 15px;
+ color: var(--carei-gray);
+ pointer-events: none;
+ transition: top 0.15s, font-size 0.15s, transform 0.15s;
+ z-index: 1;
+}
+.carei-form__float-label--static {
+ position: static;
+ transform: none;
+ font-size: 11px;
+ padding: 6px 16px 0;
+ display: block;
+}
+.carei-form__input--float {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: none !important;
+ background: transparent !important;
+ padding: 0 16px !important;
+ z-index: 2;
+}
+.carei-form__input--float:not(:placeholder-shown) ~ .carei-form__float-label,
+.carei-form__input--float:focus ~ .carei-form__float-label {
+ top: 8px;
+ transform: none;
+ font-size: 10px;
+}
+.carei-form__input--float:not(:placeholder-shown),
+.carei-form__input--float:focus {
+ padding-top: 16px !important;
+ padding-bottom: 0 !important;
+}
+
+/* Date input with floating label */
+.carei-form__date-wrap {
+ position: relative;
+ height: var(--carei-input-h);
+ background: var(--carei-white);
+ border: 1px solid transparent;
+ border-radius: var(--carei-radius);
+ transition: border-color 0.2s;
+ cursor: pointer;
+}
+.carei-form__date-wrap:focus-within {
+ border-color: var(--carei-blue);
+}
+.carei-form__date-icon {
+ position: absolute;
+ left: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--carei-blue);
+ pointer-events: none;
+ z-index: 3;
+}
+.carei-form__date-label {
+ position: absolute;
+ left: 36px;
+ top: 50%;
+ transform: translateY(-50%);
+ font-family: var(--carei-font);
+ font-weight: 400;
+ font-size: 15px;
+ color: var(--carei-gray);
+ pointer-events: none;
+ transition: top 0.15s, font-size 0.15s, transform 0.15s;
+ z-index: 3;
+}
+.carei-form__date-wrap.has-value .carei-form__date-label {
+ top: 7px;
+ transform: none;
+ font-size: 10px;
+}
+.carei-form__input--date {
+ border: none !important;
+ background: transparent !important;
+ height: 100% !important;
+ width: 100%;
+ padding: 0 12px 0 36px !important;
+ font-size: 14px;
+ position: relative;
+ z-index: 2;
+}
+/* Pusty: ukryj natywny tekst i zablokuj interakcję z polami wewnętrznymi */
+.carei-form__input--date.is-empty {
+ color: transparent !important;
+ z-index: 1;
+}
+.carei-form__input--date.is-empty::-webkit-datetime-edit {
+ color: transparent;
+ -webkit-user-select: none;
+ user-select: none;
+}
+/* Wypełniony: przesuń wartość w dół pod label */
+.carei-form__date-wrap.has-value .carei-form__input--date {
+ padding-top: 14px !important;
+ padding-bottom: 0 !important;
+}
+/* Ukryj natywną ikonę kalendarza przeglądarki */
+.carei-form__input--date::-webkit-calendar-picker-indicator {
+ opacity: 0;
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+}
+
/* Select wrapper */
.carei-form__select-wrap {
position: relative;
@@ -263,16 +395,30 @@
═══════════════════════════════════════════ */
.carei-form__phone-wrap {
display: flex;
- align-items: center;
+ flex-direction: column;
background: var(--carei-white);
border-radius: var(--carei-radius);
border: 1px solid transparent;
transition: border-color 0.2s;
height: var(--carei-input-h);
+ padding: 4px 0 0;
}
.carei-form__phone-wrap:focus-within {
border-color: var(--carei-blue);
}
+.carei-form__phone-label {
+ font-family: var(--carei-font);
+ font-weight: 400;
+ font-size: 10px;
+ color: var(--carei-gray);
+ padding: 0 16px;
+ line-height: 1;
+}
+.carei-form__phone-row {
+ display: flex;
+ align-items: center;
+ flex: 1;
+}
.carei-form__phone-prefix {
display: flex;
align-items: center;
@@ -295,8 +441,10 @@
color: var(--carei-gray);
}
.carei-form__input--phone {
- border: none;
- background: transparent;
+ border: none !important;
+ background: transparent !important;
+ box-shadow: none !important;
+ outline: none !important;
height: 100%;
padding-left: 12px;
}
@@ -305,7 +453,7 @@
letter-spacing: 2px;
}
.carei-form__input--phone:focus {
- border: none;
+ border: none !important;
}
/* ═══════════════════════════════════════════
@@ -397,35 +545,205 @@
padding: 16px;
background: var(--carei-white);
transition: border-color 0.2s;
+ min-width: 0;
+ overflow: hidden;
}
.carei-form__extra-card:has(input:checked) {
border-color: var(--carei-blue);
}
.carei-form__checkbox-label--card {
- align-items: flex-start;
+ align-items: center;
}
.carei-form__extra-content {
display: flex;
- flex-direction: column;
- gap: 4px;
+ align-items: center;
+ gap: 8px;
flex: 1;
+ min-width: 0;
+ overflow: hidden;
}
.carei-form__extra-content strong {
- font-weight: 700;
- font-size: 14px;
+ font-weight: 600;
+ font-size: 15px;
color: var(--carei-blue);
+ word-break: break-word;
+ min-width: 0;
}
.carei-form__extra-desc {
- font-size: 12px;
- color: var(--carei-gray);
- font-weight: 400;
- line-height: 1.4;
+ display: none;
}
.carei-form__extra-price {
- font-weight: 700;
+ font-weight: 400;
+ font-size: 14px;
+ color: var(--carei-gray);
+ margin-left: auto;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+.carei-form__checkbox-label--abroad {
+ align-items: center;
+ font-weight: 600;
font-size: 15px;
- color: var(--carei-red);
- margin-top: 4px;
+}
+
+/* ═══════════════════════════════════════════
+ Abroad Country Search
+ ═══════════════════════════════════════════ */
+.carei-abroad {
+ margin-top: 16px;
+}
+.carei-abroad__input-wrap {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ height: 48px;
+ padding: 0 16px;
+ border: 1px solid var(--carei-border);
+ border-radius: var(--carei-radius);
+ background: var(--carei-white);
+ transition: border-color 0.2s;
+}
+.carei-abroad__input-wrap:focus-within {
+ border-color: var(--carei-blue);
+}
+.carei-abroad__plus-icon {
+ flex-shrink: 0;
+ color: var(--carei-blue);
+}
+.carei-abroad__input {
+ flex: 1;
+ border: none !important;
+ outline: none !important;
+ box-shadow: none !important;
+ background: transparent !important;
+ font-family: 'Albert Sans', sans-serif;
+ font-weight: 600;
+ font-size: 15px;
+ color: var(--carei-blue);
+ line-height: 48px;
+ padding: 0 !important;
+ margin: 0;
+ min-width: 0;
+}
+.carei-abroad__input::placeholder {
+ font-weight: 400;
+ color: #C7C7C7;
+}
+.carei-abroad__clear {
+ display: none;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+ color: #B0B0B0;
+ border-radius: 50%;
+ transition: color 0.15s;
+}
+.carei-abroad__clear:hover {
+ color: var(--carei-gray);
+}
+.carei-abroad__input-wrap.has-text .carei-abroad__clear {
+ display: flex;
+}
+.carei-abroad__results {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px;
+ margin-top: 8px;
+}
+.carei-abroad__results:empty {
+ display: none;
+}
+.carei-abroad__selected {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px;
+ margin-top: 8px;
+}
+.carei-abroad__selected:empty {
+ display: none;
+}
+.carei-abroad__card {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ height: 56px;
+ padding: 0 12px;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: var(--carei-radius);
+ background: var(--carei-white);
+ transition: background-color 0.2s, border-color 0.2s;
+ min-width: 0;
+ overflow: hidden;
+}
+.carei-abroad__card:hover {
+ background: #2F24820D;
+}
+.carei-abroad__card--selected,
+.carei-abroad__card--selected:hover {
+ background: rgba(47, 36, 130, 0.05);
+ border-color: rgba(47, 36, 130, 0.2);
+}
+.carei-abroad__flag {
+ flex-shrink: 0;
+ width: 24px;
+ height: 24px;
+ font-size: 20px;
+ line-height: 24px;
+ text-align: center;
+}
+.carei-abroad__name {
+ flex: 1;
+ font-family: 'Albert Sans', sans-serif;
+ font-weight: 600;
+ font-size: 15px;
+ color: var(--carei-blue);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.carei-abroad__price {
+ text-align: right;
+ color: #505050;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+.carei-abroad__price-small {
+ font-size: 10px;
+}
+.carei-abroad__price-val {
+ font-size: 14px;
+}
+.carei-abroad__action {
+ flex-shrink: 0;
+ width: 24px;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: none !important;
+ background: transparent !important;
+ background-color: transparent !important;
+ cursor: pointer;
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--carei-blue);
+ padding: 0;
+ line-height: 1;
+ border-radius: 50%;
+ -webkit-appearance: none;
+ appearance: none;
+ box-shadow: none;
+}
+
+@media (max-width: 600px) {
+ .carei-abroad__results,
+ .carei-abroad__selected {
+ grid-template-columns: 1fr;
+ }
}
/* ═══════════════════════════════════════════
diff --git a/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js b/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
index 42e20c9..385ee83 100644
--- a/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
+++ b/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
@@ -79,7 +79,7 @@
var overlay, form, segmentSelect, dateFrom, dateTo, daysCount;
var pickupSelect, returnSelect, returnWrap, sameReturnCheck;
- var extrasWrapper, extrasContainer, insuranceContainer, errorSummary;
+ var extrasWrapper, extrasContainer, insuranceContainer, abroadSection, abroadToggle, abroadSearch, abroadInput, abroadResults, abroadSelected, errorSummary;
var summaryOverlay, summaryDetails, summaryTable, summaryTotal, summaryError;
var summaryBack, summaryConfirm;
var successView, successNumber, successClose;
@@ -98,6 +98,12 @@
extrasWrapper = document.getElementById('carei-extras-wrapper');
extrasContainer = document.getElementById('carei-extras-container');
insuranceContainer = document.getElementById('carei-insurance-container');
+ abroadSection = document.getElementById('carei-abroad-section');
+ abroadToggle = document.getElementById('carei-abroad-toggle');
+ abroadSearch = document.getElementById('carei-abroad-search');
+ abroadInput = document.getElementById('carei-abroad-input');
+ abroadResults = document.getElementById('carei-abroad-results');
+ abroadSelected = document.getElementById('carei-abroad-selected');
errorSummary = document.getElementById('carei-error-summary');
// Summary overlay
summaryOverlay = document.getElementById('carei-summary-overlay');
@@ -122,6 +128,8 @@
var currentReservationId = null;
var agreementDefs = [];
var lastFocusedElement = null;
+ var abroadItems = [];
+ var selectedCountries = {};
// ─── Modal Open/Close ─────────────────────────────────────────
@@ -155,7 +163,7 @@
document.body.style.overflow = 'hidden';
if (!dataLoaded) {
loadInitialData();
- setDefaultDates();
+ initDateLabels();
dataLoaded = true;
}
setTimeout(function () {
@@ -276,30 +284,47 @@
function maybeShowExtras() {
var segment = segmentSelect ? segmentSelect.value : '';
var pickup = pickupSelect ? pickupSelect.value : '';
- if (segment && pickup) { showExtras(); loadExtras(); } else { hideExtras(); }
+ var from = dateFrom ? dateFrom.value : '';
+ var to = dateTo ? dateTo.value : '';
+ if (segment && pickup && from && to) { showExtras(); loadExtras(); } else { hideExtras(); }
}
function showExtras() { if (extrasWrapper) extrasWrapper.style.display = ''; }
function hideExtras() { if (extrasWrapper) extrasWrapper.style.display = 'none'; }
- // ─── Default Dates ────────────────────────────────────────────
+ // ─── Date Labels ──────────────────────────────────────────────
- function setDefaultDates() {
- if (!dateFrom || !dateTo) return;
- var tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); tomorrow.setHours(10, 0, 0, 0);
- var dayAfter = new Date(); dayAfter.setDate(dayAfter.getDate() + 2); dayAfter.setHours(10, 0, 0, 0);
- dateFrom.value = fmtDT(tomorrow);
- dateTo.value = fmtDT(dayAfter);
- updateDaysCount();
+ function initDateLabels() {
+ [dateFrom, dateTo].forEach(function (input) {
+ if (!input) return;
+ updateDateEmpty(input);
+ input.addEventListener('change', function () { updateDateEmpty(input); updateDaysCount(); });
+ input.addEventListener('input', function () { updateDateEmpty(input); });
+ });
}
- function fmtDT(d) {
- return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + 'T' + pad(d.getHours()) + ':' + pad(d.getMinutes());
+ function updateDateEmpty(input) {
+ var wrap = input.closest('.carei-form__date-wrap');
+ if (input.value) {
+ input.classList.remove('is-empty');
+ if (wrap) wrap.classList.add('has-value');
+ } else {
+ input.classList.add('is-empty');
+ if (wrap) wrap.classList.remove('has-value');
+ }
}
+
function pad(n) { return String(n).padStart(2, '0'); }
// ─── Days Count ───────────────────────────────────────────────
+ function getRentalDays() {
+ if (!dateFrom || !dateTo) return 1;
+ var from = new Date(dateFrom.value), to = new Date(dateTo.value);
+ if (isNaN(from.getTime()) || isNaN(to.getTime()) || to <= from) return 1;
+ return Math.ceil((to - from) / 86400000);
+ }
+
function updateDaysCount() {
if (!dateFrom || !dateTo || !daysCount) return;
var from = new Date(dateFrom.value), to = new Date(dateTo.value);
@@ -325,6 +350,8 @@
currentPriceListId = pricelist.id;
var items = pricelist.additionalItems;
var insuranceItems = [], extraItems = [];
+ abroadItems = [];
+ selectedCountries = {};
if (Array.isArray(items)) {
items.forEach(function (item) {
var name = (item.name || '').toLowerCase();
@@ -332,7 +359,11 @@
var code = (item.code || '').toUpperCase();
if (code.indexOf('BRAK') === 0 || code.indexOf('BRUD') === 0 || code.indexOf('KARA') === 0 ||
code.indexOf('MYCIE USŁU') === 0 || code === 'MYJ WEW') return;
- if (name.indexOf('ubezp') !== -1 || name.indexOf('ochrony') !== -1 ||
+ if (name.indexOf('wyjazd za granic') !== -1) {
+ item._countryName = parseCountryName(item.name);
+ item._countryFlag = getCountryFlag(item._countryName);
+ abroadItems.push(item);
+ } else if (name.indexOf('ubezp') !== -1 || name.indexOf('ochrony') !== -1 ||
name.indexOf('zniesienie') !== -1 || name.indexOf('insurance') !== -1) {
insuranceItems.push(item);
} else {
@@ -342,6 +373,8 @@
}
if (insuranceContainer) { insuranceContainer.innerHTML = ''; insuranceItems.forEach(function (item) { insuranceContainer.appendChild(buildExtraCard(item)); }); }
if (extrasContainer) { extrasContainer.innerHTML = ''; extraItems.forEach(function (item) { extrasContainer.appendChild(buildExtraCard(item)); }); }
+ if (abroadSection) { abroadSection.style.display = abroadItems.length > 0 ? '' : 'none'; }
+ renderAbroadSelected();
}).catch(function (err) { console.error('Failed to load pricelist:', err); });
}
@@ -363,6 +396,147 @@
return card;
}
+ // ─── Abroad Country Search ─────────────────────────────────────
+
+ var COUNTRY_FLAGS = {
+ 'niemcy': '\u{1F1E9}\u{1F1EA}', 'czechy': '\u{1F1E8}\u{1F1FF}', 'słowacja': '\u{1F1F8}\u{1F1F0}',
+ 'austria': '\u{1F1E6}\u{1F1F9}', 'francja': '\u{1F1EB}\u{1F1F7}', 'włochy': '\u{1F1EE}\u{1F1F9}',
+ 'hiszpania': '\u{1F1EA}\u{1F1F8}', 'holandia': '\u{1F1F3}\u{1F1F1}', 'belgia': '\u{1F1E7}\u{1F1EA}',
+ 'dania': '\u{1F1E9}\u{1F1F0}', 'szwecja': '\u{1F1F8}\u{1F1EA}', 'norwegia': '\u{1F1F3}\u{1F1F4}',
+ 'finlandia': '\u{1F1EB}\u{1F1EE}', 'szwajcaria': '\u{1F1E8}\u{1F1ED}', 'węgry': '\u{1F1ED}\u{1F1FA}',
+ 'chorwacja': '\u{1F1ED}\u{1F1F7}', 'słowenia': '\u{1F1F8}\u{1F1EE}', 'litwa': '\u{1F1F1}\u{1F1F9}',
+ 'łotwa': '\u{1F1F1}\u{1F1FB}', 'estonia': '\u{1F1EA}\u{1F1EA}', 'rumunia': '\u{1F1F7}\u{1F1F4}',
+ 'bułgaria': '\u{1F1E7}\u{1F1EC}', 'portugalia': '\u{1F1F5}\u{1F1F9}', 'grecja': '\u{1F1EC}\u{1F1F7}',
+ 'wielka brytania': '\u{1F1EC}\u{1F1E7}', 'irlandia': '\u{1F1EE}\u{1F1EA}', 'luksemburg': '\u{1F1F1}\u{1F1FA}',
+ 'serbia': '\u{1F1F7}\u{1F1F8}', 'czarnogóra': '\u{1F1F2}\u{1F1EA}', 'albania': '\u{1F1E6}\u{1F1F1}',
+ 'turcja': '\u{1F1F9}\u{1F1F7}', 'ukraina': '\u{1F1FA}\u{1F1E6}', 'mołdawia': '\u{1F1F2}\u{1F1E9}'
+ };
+
+ function parseCountryName(name) {
+ var raw = (name || '').replace(/wyjazd za granic[eę]\s*[-–—]?\s*/i, '').trim();
+ if (!raw) return name || '';
+ return raw.split(/\s+/).map(function (w) {
+ return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();
+ }).join(' ');
+ }
+
+ function getCountryFlag(countryName) {
+ var key = (countryName || '').toLowerCase();
+ return COUNTRY_FLAGS[key] || '\u{1F3F3}\u{FE0F}';
+ }
+
+ function initAbroad() {
+ if (!abroadToggle || !abroadSearch) return;
+ abroadToggle.addEventListener('change', function () {
+ if (abroadToggle.checked) {
+ abroadSearch.style.display = '';
+ } else {
+ abroadSearch.style.display = 'none';
+ selectedCountries = {};
+ if (abroadInput) abroadInput.value = '';
+ renderAbroadResults([]);
+ renderAbroadSelected();
+ }
+ });
+ var abroadClear = document.getElementById('carei-abroad-clear');
+ if (abroadInput) {
+ abroadInput.addEventListener('input', function () {
+ updateAbroadClear();
+ var query = abroadInput.value.trim().toLowerCase();
+ if (!query) { renderAbroadResults([]); return; }
+ var filtered = abroadItems.filter(function (item) {
+ return item._countryName.toLowerCase().indexOf(query) !== -1;
+ });
+ renderAbroadResults(filtered);
+ });
+ abroadInput.addEventListener('focus', function () {
+ var query = abroadInput.value.trim().toLowerCase();
+ if (query) {
+ var filtered = abroadItems.filter(function (item) {
+ return item._countryName.toLowerCase().indexOf(query) !== -1;
+ });
+ renderAbroadResults(filtered);
+ }
+ });
+ }
+ if (abroadClear) {
+ abroadClear.addEventListener('click', function () {
+ if (abroadInput) { abroadInput.value = ''; abroadInput.focus(); }
+ renderAbroadResults([]);
+ updateAbroadClear();
+ });
+ }
+
+ function updateAbroadClear() {
+ var wrap = abroadInput ? abroadInput.closest('.carei-abroad__input-wrap') : null;
+ if (wrap) {
+ if (abroadInput.value.trim()) { wrap.classList.add('has-text'); }
+ else { wrap.classList.remove('has-text'); }
+ }
+ }
+ }
+
+ function renderAbroadResults(items) {
+ if (!abroadResults) return;
+ abroadResults.innerHTML = '';
+ if (!items || items.length === 0) return;
+ items.forEach(function (item) {
+ var id = item.id || item.code;
+ var isSelected = !!selectedCountries[id];
+ abroadResults.appendChild(buildCountryCard(item, isSelected));
+ });
+ }
+
+ function renderAbroadSelected() {
+ if (!abroadSelected) return;
+ abroadSelected.innerHTML = '';
+ var keys = Object.keys(selectedCountries);
+ if (keys.length === 0) return;
+ keys.forEach(function (id) {
+ var item = selectedCountries[id];
+ abroadSelected.appendChild(buildCountryCard(item, true));
+ });
+ }
+
+ function buildCountryCard(item, isSelected) {
+ var id = item.id || item.code;
+ var price = parseFloat(item.price || item.minPrice || 0);
+ var priceHtml = '' + (price > 0 ? price.toFixed(0) + ' zł' : 'Gratis') + '';
+
+ var card = document.createElement('div');
+ card.className = 'carei-abroad__card' + (isSelected ? ' carei-abroad__card--selected' : '');
+ card.innerHTML =
+ '' + escHtml(item._countryFlag) + '' +
+ '' + escHtml(item._countryName) + '' +
+ '' + priceHtml + '' +
+ '' +
+ (isSelected
+ ? ''
+ : ''
+ ) + '';
+
+ card.querySelector('.carei-abroad__action').addEventListener('click', function (e) {
+ e.preventDefault();
+ if (selectedCountries[id]) {
+ delete selectedCountries[id];
+ } else {
+ selectedCountries[id] = item;
+ }
+ var query = abroadInput ? abroadInput.value.trim().toLowerCase() : '';
+ if (query) {
+ var filtered = abroadItems.filter(function (it) {
+ return it._countryName.toLowerCase().indexOf(query) !== -1;
+ });
+ renderAbroadResults(filtered);
+ } else {
+ renderAbroadResults([]);
+ }
+ renderAbroadSelected();
+ });
+
+ return card;
+ }
+
// ─── Select Helpers ───────────────────────────────────────────
function populateSelect(select, options, placeholder) {
@@ -588,13 +762,31 @@
function getSelectedExtrasForApi() {
var items = [];
if (!form) return items;
+ var days = getRentalDays();
form.querySelectorAll('input[name="extras[]"]:checked').forEach(function (cb) {
var price = parseFloat(cb.getAttribute('data-price') || 0);
+ var unit = cb.getAttribute('data-unit') || 'szt.';
+ var amount = unit === 'doba' ? days : 1;
items.push({
id: cb.value,
name: cb.getAttribute('data-name') || '',
- unit: cb.getAttribute('data-unit') || 'szt.',
- amount: 1,
+ unit: unit,
+ amount: amount,
+ priceBeforeDiscount: price,
+ discount: 0,
+ priceAfterDiscount: price
+ });
+ });
+ Object.keys(selectedCountries).forEach(function (id) {
+ var item = selectedCountries[id];
+ var price = parseFloat(item.price || item.minPrice || 0);
+ var unit = item.unit || 'szt.';
+ var amount = unit === 'doba' ? days : 1;
+ items.push({
+ id: item.id || item.code,
+ name: item.name,
+ unit: unit,
+ amount: amount,
priceBeforeDiscount: price,
discount: 0,
priceAfterDiscount: price
@@ -898,6 +1090,7 @@
initSameReturn();
initDynamicLoading();
initClearErrors();
+ initAbroad();
initSubmit();
}
diff --git a/wp-content/plugins/carei-reservation/includes/class-elementor-widget.php b/wp-content/plugins/carei-reservation/includes/class-elementor-widget.php
index 0c825ab..b39e8be 100644
--- a/wp-content/plugins/carei-reservation/includes/class-elementor-widget.php
+++ b/wp-content/plugins/carei-reservation/includes/class-elementor-widget.php
@@ -58,11 +58,11 @@ class Carei_Reservation_Widget extends \Elementor\Widget_Base {
-
+
Wypełnij formularz rezerwacji.
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
@@ -126,6 +129,26 @@ class Carei_Reservation_Widget extends \Elementor\Widget_Base {
+
Wyjazd zagraniczny
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Ubezpieczenie
@@ -148,51 +171,67 @@ class Carei_Reservation_Widget extends \Elementor\Widget_Base {
-
-
+
+
+
+
-
-
+
+
+
+
-
-
+
+
+
+
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 🇵🇱
- +48
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+ 🇵🇱
+ +48
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wp-content/themes/.DS_Store b/wp-content/themes/.DS_Store
new file mode 100644
index 0000000..ed6a7d8
Binary files /dev/null and b/wp-content/themes/.DS_Store differ
diff --git a/wp-includes/.DS_Store b/wp-includes/.DS_Store
new file mode 100644
index 0000000..3b26fc3
Binary files /dev/null and b/wp-includes/.DS_Store differ
diff --git a/wp-includes/Requests/.DS_Store b/wp-includes/Requests/.DS_Store
new file mode 100644
index 0000000..daaed11
Binary files /dev/null and b/wp-includes/Requests/.DS_Store differ
diff --git a/wp-includes/SimplePie/.DS_Store b/wp-includes/SimplePie/.DS_Store
new file mode 100644
index 0000000..293c5f7
Binary files /dev/null and b/wp-includes/SimplePie/.DS_Store differ
diff --git a/wp-includes/blocks/.DS_Store b/wp-includes/blocks/.DS_Store
new file mode 100644
index 0000000..dca73f4
Binary files /dev/null and b/wp-includes/blocks/.DS_Store differ
diff --git a/wp-includes/images/.DS_Store b/wp-includes/images/.DS_Store
new file mode 100644
index 0000000..e80bca2
Binary files /dev/null and b/wp-includes/images/.DS_Store differ
diff --git a/wp-includes/js/.DS_Store b/wp-includes/js/.DS_Store
new file mode 100644
index 0000000..f36b7cc
Binary files /dev/null and b/wp-includes/js/.DS_Store differ
diff --git a/wp-includes/rest-api/.DS_Store b/wp-includes/rest-api/.DS_Store
new file mode 100644
index 0000000..df2d9d6
Binary files /dev/null and b/wp-includes/rest-api/.DS_Store differ
diff --git a/wp-includes/sodium_compat/.DS_Store b/wp-includes/sodium_compat/.DS_Store
new file mode 100644
index 0000000..f166db1
Binary files /dev/null and b/wp-includes/sodium_compat/.DS_Store differ