update
This commit is contained in:
@@ -47,6 +47,15 @@ Plugin Elementor do rezerwacji samochodu na stronie carei.pagedev.pl, zintegrowa
|
|||||||
| Inline display:none for steps | 4 | CSS class conflict resolution |
|
| Inline display:none for steps | 4 | CSS class conflict resolution |
|
||||||
| Calendar picker opacity:0 stretch | 7 | Ukrycie natywnej ikonki z zachowaniem kliknięcia |
|
| Calendar picker opacity:0 stretch | 7 | Ukrycie natywnej ikonki z zachowaniem kliknięcia |
|
||||||
| Search form niezależne API loading | 7 | Dane dostępne od razu, niezależnie od modala |
|
| Search form niezależne API loading | 7 | Dane dostępne od razu, niezależnie od modala |
|
||||||
|
| Static city→SVG coords (no geocoding) | 8 | Prostota, brak zewnętrznych zależności |
|
||||||
|
| Branch name D/L suffix stripping | 8 | API zwraca warianty Dworzec/Lotnisko — deduplikacja |
|
||||||
|
| CSS ::after for city separators | 8 | Zapobiega orphanowaniu `\|` na początku linii |
|
||||||
|
|
||||||
|
## Validated Requirements (Milestone v0.3)
|
||||||
|
- ✓ Mapa SVG Polski z dynamicznymi pinami oddziałów i tooltipami — Phase 8
|
||||||
|
- ✓ Siatka miast oddziałowych (widget Elementor) — Phase 8
|
||||||
|
- ✓ Grid oddziałów z adresami (widget Elementor) — Phase 8
|
||||||
|
- ✓ Cachowanie `/branch/list` z TTL 60 min — Phase 8
|
||||||
|
|
||||||
## Out of Scope (backlog)
|
## Out of Scope (backlog)
|
||||||
- Ubezpieczenie (pakiet Soft/Premium) — czeka na API Softra
|
- Ubezpieczenie (pakiet Soft/Premium) — czeka na API Softra
|
||||||
|
|||||||
@@ -35,5 +35,16 @@ Kompaktowy widget Elementor "Carei Search Form" osadzany w sekcji hero. Pola: se
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Milestone v0.3: Mapa Oddziałów + Cache API
|
||||||
|
|
||||||
|
**Goal:** Wizualna prezentacja sieci oddziałów Carei — interaktywna mapa SVG z pinami i siatka miast, plus ujednolicone cachowanie API.
|
||||||
|
|
||||||
|
**Status:** Complete ✅
|
||||||
|
|
||||||
|
### Phase 8: Mapa oddziałów + siatka miast + cache API ✅ Complete
|
||||||
|
Dwa widgety Elementor: (1) mapa Polski SVG z dynamicznymi pinami oddziałów i tooltipami adresowymi, (2) siatka miast. Cachowanie `/branch/list` z TTL 60 min.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Backlog (do realizacji gdy API będzie gotowe)
|
### Backlog (do realizacji gdy API będzie gotowe)
|
||||||
- **Ubezpieczenie:** Sekcja "Pakiet ochrony Soft/Premium" jak na Figmie. Wymaga dedykowanych pozycji ubezpieczeniowych w API pricelist.
|
- **Ubezpieczenie:** Sekcja "Pakiet ochrony Soft/Premium" jak na Figmie. Wymaga dedykowanych pozycji ubezpieczeniowych w API pricelist.
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Milestone: v0.2 Wyjazd Zagraniczny — Complete
|
Milestone: v0.3 Mapa Oddziałów + Cache API — Complete
|
||||||
Phase: 7 of 7 — All phases complete
|
Phase: 8 of 8 — All phases complete
|
||||||
Status: Milestone v0.2 complete
|
Status: Milestone v0.3 complete
|
||||||
Last activity: 2026-04-01 — Phase 6 retroactively closed, Phase 7 complete
|
Last activity: 2026-04-01 — Phase 8 complete, loop closed
|
||||||
|
|
||||||
Progress:
|
Progress:
|
||||||
- Milestone v0.1: [██████████] 100% ✅
|
- Milestone v0.1: [██████████] 100% ✅
|
||||||
- Milestone v0.2: [██████████] 100% ✅
|
- Milestone v0.2: [██████████] 100% ✅
|
||||||
|
- Milestone v0.3: [██████████] 100% ✅
|
||||||
|
|
||||||
## Loop Position
|
## Loop Position
|
||||||
|
|
||||||
@@ -22,6 +23,6 @@ PLAN ──▶ APPLY ──▶ UNIFY
|
|||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-01
|
Last session: 2026-04-01
|
||||||
Stopped at: Milestone v0.2 complete
|
Stopped at: Milestone v0.3 complete
|
||||||
Next action: Plan new milestone or new work
|
Next action: Plan new milestone or new work
|
||||||
Resume file: .paul/ROADMAP.md
|
Resume file: .paul/ROADMAP.md
|
||||||
|
|||||||
219
.paul/phases/08-map-and-cities-widgets/08-01-PLAN.md
Normal file
219
.paul/phases/08-map-and-cities-widgets/08-01-PLAN.md
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
---
|
||||||
|
phase: 08-map-and-cities-widgets
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-map-widget.php
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-cities-widget.php
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-softra-api.php
|
||||||
|
- wp-content/plugins/carei-reservation/carei-reservation.php
|
||||||
|
- wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
|
||||||
|
- wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
|
||||||
|
autonomous: false
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
## Goal
|
||||||
|
Dwa nowe widgety Elementor: (1) interaktywna mapa Polski z dynamicznymi pinami oddziałów i tooltipami adresowymi, (2) siatka miast oddziałowych. Plus ujednolicone cachowanie odpowiedzi API Softra (60 min).
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Wizualna prezentacja sieci oddziałów Carei na stronie — mapa z pinami i lista miast budują zaufanie klienta i ułatwiają wybór lokalizacji.
|
||||||
|
|
||||||
|
## Output
|
||||||
|
- `class-map-widget.php` — widget Elementor z mapą SVG Polski + dynamiczne piny
|
||||||
|
- `class-cities-widget.php` — widget Elementor z siatką miast
|
||||||
|
- Rozszerzony cache w `class-softra-api.php` — transient 60 min na `/branch/list`
|
||||||
|
- Zarejestrowane widgety w `carei-reservation.php`
|
||||||
|
- Style i JS w istniejących plikach assets
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
## Project Context
|
||||||
|
@.paul/PROJECT.md
|
||||||
|
@.paul/ROADMAP.md
|
||||||
|
@.paul/STATE.md
|
||||||
|
|
||||||
|
## Source Files
|
||||||
|
@wp-content/plugins/carei-reservation/carei-reservation.php
|
||||||
|
@wp-content/plugins/carei-reservation/includes/class-softra-api.php
|
||||||
|
@wp-content/plugins/carei-reservation/includes/class-search-widget.php (wzorzec widgetu)
|
||||||
|
@wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
|
||||||
|
@wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<skills>
|
||||||
|
No specialized flows configured.
|
||||||
|
</skills>
|
||||||
|
|
||||||
|
<acceptance_criteria>
|
||||||
|
|
||||||
|
## AC-1: Mapa Polski z dynamicznymi pinami oddziałów
|
||||||
|
```gherkin
|
||||||
|
Given strona z widgetem Carei Map załadowana
|
||||||
|
When dane oddziałów pobrane z API (lub cache)
|
||||||
|
Then na mapie SVG Polski wyświetlają się czerwone piny w lokalizacjach odpowiadających miastom oddziałów
|
||||||
|
And po najechaniu na pin pojawia się tooltip z adresem oddziału (ulica, kod, miasto)
|
||||||
|
And po kliknięciu pina tooltip pozostaje widoczny (toggle)
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-2: Siatka miast oddziałowych
|
||||||
|
```gherkin
|
||||||
|
Given strona z widgetem Carei Cities załadowana
|
||||||
|
When dane oddziałów pobrane z API (lub cache)
|
||||||
|
Then wyświetla się siatka z nazwami miast oddziałów rozdzielonymi separatorem "|"
|
||||||
|
And miasta są unikalne (bez duplikatów nawet jeśli oddział ma wiele branchy w jednym mieście)
|
||||||
|
And układ jest responsywny (grid na desktop, kolumna na mobile)
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-3: Cachowanie odpowiedzi API z TTL 60 min
|
||||||
|
```gherkin
|
||||||
|
Given plugin Carei Reservation aktywny
|
||||||
|
When frontend lub widget pobiera dane oddziałów z /branch/list
|
||||||
|
Then wynik jest cachowany jako WP transient z TTL 60 minut
|
||||||
|
And kolejne żądania w ciągu 60 min nie generują zapytań do Softra API
|
||||||
|
And po upływie TTL dane są odświeżane z API
|
||||||
|
```
|
||||||
|
|
||||||
|
</acceptance_criteria>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Cache API + Widget mapki Polski z pinami</name>
|
||||||
|
<files>
|
||||||
|
wp-content/plugins/carei-reservation/includes/class-softra-api.php,
|
||||||
|
wp-content/plugins/carei-reservation/includes/class-map-widget.php,
|
||||||
|
wp-content/plugins/carei-reservation/carei-reservation.php,
|
||||||
|
wp-content/plugins/carei-reservation/assets/css/carei-reservation.css,
|
||||||
|
wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
|
||||||
|
</files>
|
||||||
|
<action>
|
||||||
|
**1a. Cachowanie `/branch/list` (class-softra-api.php):**
|
||||||
|
- Dodaj metodę `get_branches_cached()` opakowującą `get_branches()` w transient `carei_branches_list` z TTL 60 min (HOUR_IN_SECONDS).
|
||||||
|
- Zmień `get_segments_branches_map()` by korzystała z `get_branches_cached()` zamiast `get_branches()`.
|
||||||
|
- Dodaj endpoint REST `/branches-full` w REST proxy zwracający pełne dane branchy (z description/address) — istniejący `/branches` zwraca tylko nazwy.
|
||||||
|
|
||||||
|
**1b. Widget mapy (class-map-widget.php):**
|
||||||
|
- Nowa klasa `Carei_Map_Widget extends \Elementor\Widget_Base`
|
||||||
|
- `get_name()` → `'carei-map'`, `get_title()` → `'Carei Map'`
|
||||||
|
- W `render()`:
|
||||||
|
- Pobierz oddziały z REST API `/carei/v1/branches-full` przez JS (lub inline z PHP jeśli cache aktywny)
|
||||||
|
- Wyrenderuj kontener `<div class="carei-map">` z inline SVG mapy Polski (kontur województw)
|
||||||
|
- SVG mapy: użytkownik dostarczy kod SVG — na razie placeholder z prostym konturem Polski
|
||||||
|
- Mapowanie miast na współrzędne SVG:
|
||||||
|
- W PHP: tablica asocjacyjna `CITY_COORDINATES` mapująca nazwy miast (lowercase, bez polskich znaków) na współrzędne [x, y] w viewBox SVG
|
||||||
|
- Miasta znane w Carei: Warszawa, Białystok, Wrocław, Kraków, Gdańsk, Poznań, Katowice, Łódź, Lublin, Szczecin, Rzeszów, Bydgoszcz, Olsztyn, Kielce, Opole, Zielona Góra, Radom itp.
|
||||||
|
- Przekaż współrzędne do JS przez `wp_localize_script` lub data-attribute
|
||||||
|
- W JS: dynamicznie dodaj `<circle>` (piny) na mapie SVG w pozycjach z mapowania
|
||||||
|
- Tooltip: na hover/click nad pinem — `<div class="carei-map__tooltip">` z adresem z pola `description` brancha
|
||||||
|
- Styl pina: czerwone kółko (#FF0000), r=6, hover r=8 z transition
|
||||||
|
- Styl tooltipa: ciemne tło (#2F2482), biały tekst, strzałka (jak na Figmie)
|
||||||
|
|
||||||
|
**1c. Rejestracja widgetu:**
|
||||||
|
- W `carei-reservation.php` w hooku `elementor/widgets/register`: require + register `Carei_Map_Widget`
|
||||||
|
|
||||||
|
**Avoid:**
|
||||||
|
- NIE używaj zewnętrznych bibliotek mapowych (Leaflet, Google Maps) — to prosta mapa SVG
|
||||||
|
- NIE hardkoduj danych oddziałów — zawsze z API/cache
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
- Widget "Carei Map" widoczny w panelu Elementor
|
||||||
|
- Mapa SVG renderuje się z pinami w lokalizacjach oddziałów
|
||||||
|
- Hover na pinie pokazuje tooltip z adresem
|
||||||
|
- Drugie załadowanie strony nie generuje nowego requestu do Softra (cache aktywny)
|
||||||
|
</verify>
|
||||||
|
<done>AC-1 satisfied: Mapa z dynamicznymi pinami i tooltipami. AC-3 satisfied: Cache 60 min na branch/list.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Widget siatki miast</name>
|
||||||
|
<files>
|
||||||
|
wp-content/plugins/carei-reservation/includes/class-cities-widget.php,
|
||||||
|
wp-content/plugins/carei-reservation/carei-reservation.php,
|
||||||
|
wp-content/plugins/carei-reservation/assets/css/carei-reservation.css,
|
||||||
|
wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
|
||||||
|
</files>
|
||||||
|
<action>
|
||||||
|
**2a. Widget miast (class-cities-widget.php):**
|
||||||
|
- Nowa klasa `Carei_Cities_Widget extends \Elementor\Widget_Base`
|
||||||
|
- `get_name()` → `'carei-cities'`, `get_title()` → `'Carei Cities'`
|
||||||
|
- W `render()`:
|
||||||
|
- Pobierz oddziały z cache/API (ten sam endpoint co mapa)
|
||||||
|
- Wyciągnij unikalne nazwy miast z pola description branchy (parse miasto z adresu)
|
||||||
|
- Renderuj `<div class="carei-cities">` z siatką miast
|
||||||
|
- HTML: `<span class="carei-cities__item">Miasto</span>` rozdzielone separatorem `|`
|
||||||
|
- Layout: CSS grid/flex, 5 kolumn na desktop (jak na Figmie), 2-3 kolumny na tablet, 1 na mobile
|
||||||
|
- Font: Albert Sans, kolor #2F2482
|
||||||
|
- Miasta dynamiczne — jeśli oddział dodany w Softra, automatycznie pojawia się w widgecie
|
||||||
|
|
||||||
|
**2b. Rejestracja widgetu:**
|
||||||
|
- W `carei-reservation.php`: require + register `Carei_Cities_Widget`
|
||||||
|
|
||||||
|
**Avoid:**
|
||||||
|
- NIE hardkoduj listy miast
|
||||||
|
- NIE duplikuj requestów — użyj tego samego cache co mapa
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
- Widget "Carei Cities" widoczny w panelu Elementor
|
||||||
|
- Siatka miast renderuje się z unikalnymi miastami z API
|
||||||
|
- Responsywność: 5 kolumn desktop → mniej na mobile
|
||||||
|
- Brak duplikatów miast
|
||||||
|
</verify>
|
||||||
|
<done>AC-2 satisfied: Siatka miast dynamiczna, responsywna, unikalne wartości.</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="checkpoint:human-verify" gate="blocking">
|
||||||
|
<what-built>Dwa widgety Elementor: mapa Polski z pinami oddziałów + siatka miast. Cachowanie API 60 min.</what-built>
|
||||||
|
<how-to-verify>
|
||||||
|
1. Otwórz stronę w Elementorze, dodaj widget "Carei Map" — sprawdź czy piny są na mapie
|
||||||
|
2. Najedź na pin — tooltip z adresem powinien się pojawić
|
||||||
|
3. Dodaj widget "Carei Cities" — sprawdź siatkę miast
|
||||||
|
4. Sprawdź responsywność (mobile preview w Elementorze)
|
||||||
|
5. Opcjonalnie: podaj kod SVG mapy Polski do zastąpienia placeholdera
|
||||||
|
</how-to-verify>
|
||||||
|
<resume-signal>Type "approved" to continue, or describe issues to fix</resume-signal>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<boundaries>
|
||||||
|
|
||||||
|
## DO NOT CHANGE
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-elementor-widget.php (główny widget rezerwacji)
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-admin-panel.php (admin panel)
|
||||||
|
- Istniejące endpointy REST (nie zmieniaj zachowania `/branches`, `/car-classes` itd.)
|
||||||
|
- Logika formularza rezerwacji w JS (sekcje modal, booking flow)
|
||||||
|
|
||||||
|
## SCOPE LIMITS
|
||||||
|
- Mapa to SVG statyczny z dynamicznymi pinami — NIE interaktywna mapa z zoomem
|
||||||
|
- Brak geokodowania w runtime — współrzędne miast zmapowane statycznie w PHP
|
||||||
|
- Tooltip prosty (adres) — bez linków, bez routingu do formularza
|
||||||
|
- Cachowanie tylko na `/branch/list` — inne endpointy bez zmian w tym planie
|
||||||
|
|
||||||
|
</boundaries>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] Widget "Carei Map" renderuje mapę z pinami na prawidłowych pozycjach
|
||||||
|
- [ ] Tooltip na hover/click pokazuje adres oddziału
|
||||||
|
- [ ] Widget "Carei Cities" wyświetla unikalne miasta w siatce
|
||||||
|
- [ ] Cache transient `carei_branches_list` aktywny z TTL 60 min
|
||||||
|
- [ ] Responsywność obu widgetów (desktop + mobile)
|
||||||
|
- [ ] Brak błędów JS w konsoli
|
||||||
|
- [ ] Brak broken layouts w istniejących widgetach (rezerwacja, search form)
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Oba widgety dostępne w Elementorze i renderują dane z API
|
||||||
|
- Piny na mapie odpowiadają miastom oddziałów z Softra
|
||||||
|
- Tooltips wyświetlają adresy
|
||||||
|
- Siatka miast dynamiczna i responsywna
|
||||||
|
- Cache 60 min działa — brak nadmiarowych requestów do API
|
||||||
|
- Istniejąca funkcjonalność nienaruszona
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.paul/phases/08-map-and-cities-widgets/08-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
145
.paul/phases/08-map-and-cities-widgets/08-01-SUMMARY.md
Normal file
145
.paul/phases/08-map-and-cities-widgets/08-01-SUMMARY.md
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
---
|
||||||
|
phase: 08-map-and-cities-widgets
|
||||||
|
plan: 01
|
||||||
|
subsystem: ui
|
||||||
|
tags: [elementor, svg, map, api-cache, transient]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 01-reservation-form-plugin
|
||||||
|
provides: Softra API client, REST proxy, plugin bootstrap
|
||||||
|
|
||||||
|
provides:
|
||||||
|
- Carei Map widget (SVG map with dynamic pins + tooltips)
|
||||||
|
- Carei Cities widget (city name grid)
|
||||||
|
- Carei Branches widget (branch grid with addresses)
|
||||||
|
- Branches API caching (60min transient)
|
||||||
|
- REST endpoint /branches-full
|
||||||
|
|
||||||
|
affects: []
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Branch name cleaning: strip D/L suffixes, NAME_FIXES for truncated names"
|
||||||
|
- "City coordinates: static PHP array mapping normalized names to SVG viewBox coords"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-map-widget.php
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-cities-widget.php
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-branches-widget.php
|
||||||
|
modified:
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-softra-api.php
|
||||||
|
- wp-content/plugins/carei-reservation/includes/class-rest-proxy.php
|
||||||
|
- wp-content/plugins/carei-reservation/carei-reservation.php
|
||||||
|
- wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
|
||||||
|
- wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Branch name D=Dworzec, L=Lotnisko — strip suffixes, deduplicate to base city"
|
||||||
|
- "Tooltip format: Oddział [City] + ul. Street + ZipCode City"
|
||||||
|
- "Branches widget added beyond original plan scope"
|
||||||
|
- "Cities separator via CSS ::after to prevent line-start orphan |"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "NAME_FIXES const for API name corrections (shared across widgets)"
|
||||||
|
- "get_branches_cached() as single source for all branch data"
|
||||||
|
|
||||||
|
duration: ~45min
|
||||||
|
started: 2026-04-01T17:30:00Z
|
||||||
|
completed: 2026-04-01T18:15:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 8 Plan 01: Map, Cities & Branches Widgets Summary
|
||||||
|
|
||||||
|
**Three Elementor widgets for branch visualization: SVG map with dynamic pins/tooltips, city name list, and full branch grid with addresses. Plus 60-min API cache.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Duration | ~45min |
|
||||||
|
| Tasks | 3 completed (2 auto + 1 checkpoint) |
|
||||||
|
| Files modified | 7 (3 created, 4 modified) |
|
||||||
|
|
||||||
|
## Acceptance Criteria Results
|
||||||
|
|
||||||
|
| Criterion | Status | Notes |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| AC-1: Mapa Polski z dynamicznymi pinami | Pass | Real SVG (Vector.svg), pins from API, tooltip with address |
|
||||||
|
| AC-2: Siatka miast oddziałowych | Pass | Unique cities, ::after separators, responsive |
|
||||||
|
| AC-3: Cachowanie API 60 min | Pass | `get_branches_cached()` with HOUR_IN_SECONDS transient |
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- SVG map of Poland (user-provided Vector.svg) with dynamic red pins positioned by city coordinate mapping, tooltips showing "Oddział [City] / ul. Street / ZipCode City"
|
||||||
|
- Cities widget with deduplicated, title-cased names from API, CSS ::after separators that never orphan to line start
|
||||||
|
- Branches grid widget (5→3→2→1 columns responsive) with full address data from API fields (street, zipCode, city)
|
||||||
|
- Unified branch name cleaning: D/L suffix stripping, NAME_FIXES for truncated API names (BYDGOSZC→BYDGOSZCZ, GORZÓW WIE→GORZÓW WIELKOPOLSKI, RZSZÓW→RZESZÓW, SK-KAM→skip)
|
||||||
|
- 60-min transient cache on /branch/list, used by all three widgets via single `get_branches_cached()` method
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
| File | Change | Purpose |
|
||||||
|
|------|--------|---------|
|
||||||
|
| `includes/class-map-widget.php` | Created | SVG map widget with pins, tooltips, city coords |
|
||||||
|
| `includes/class-cities-widget.php` | Created | City name grid widget |
|
||||||
|
| `includes/class-branches-widget.php` | Created | Branch grid with addresses |
|
||||||
|
| `includes/class-softra-api.php` | Modified | Added `get_branches_cached()` with 60min transient |
|
||||||
|
| `includes/class-rest-proxy.php` | Modified | Added `/branches-full` endpoint |
|
||||||
|
| `carei-reservation.php` | Modified | Registered 3 new widgets |
|
||||||
|
| `assets/css/carei-reservation.css` | Modified | Styles for map, cities, branches widgets |
|
||||||
|
| `assets/js/carei-reservation.js` | Modified | Dynamic pin rendering + tooltip logic |
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
| Decision | Rationale | Impact |
|
||||||
|
|----------|-----------|--------|
|
||||||
|
| Static city→SVG coordinate mapping in PHP | No runtime geocoding, simple and fast | New cities need manual coord addition |
|
||||||
|
| D suffix = Dworzec, display as "Oddział [City]" | User request for consistent naming | All tooltips show "Oddział X" format |
|
||||||
|
| CSS ::after for city separators | Prevents `\|` orphaning to line start on wrap | Cleaner than separate `<span>` elements |
|
||||||
|
| Added Branches widget (not in original plan) | User requested during execution | Extra widget, no negative impact |
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
| Type | Count | Impact |
|
||||||
|
|------|-------|--------|
|
||||||
|
| Scope additions | 1 | Branches grid widget added |
|
||||||
|
| Auto-fixed | 3 | API name cleaning, separator orphans, tooltip content |
|
||||||
|
|
||||||
|
**Total impact:** Scope addition was user-requested. Auto-fixes were essential for data quality.
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. API branch names with D/L suffixes causing 39 duplicates**
|
||||||
|
- Found during: checkpoint verification
|
||||||
|
- Issue: API returns "GDAŃSK", "GDAŃSK D", "GDAŃSK L" as separate branches
|
||||||
|
- Fix: Strip suffixes, NAME_FIXES for truncated names, deduplicate
|
||||||
|
- Verification: 17 unique cities displayed
|
||||||
|
|
||||||
|
**2. Separator `|` orphaning to new line start**
|
||||||
|
- Found during: user review
|
||||||
|
- Fix: Replaced `<span>` separator with CSS `::after` pseudo-element
|
||||||
|
|
||||||
|
**3. Tooltip showing raw API description instead of formatted address**
|
||||||
|
- Found during: user review
|
||||||
|
- Fix: Built address from `street`, `zipCode`, `city` API fields
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
**Ready:**
|
||||||
|
- All branch visualization widgets operational
|
||||||
|
- API cache in place for all branch data consumers
|
||||||
|
- Branch name cleaning pattern reusable
|
||||||
|
|
||||||
|
**Concerns:**
|
||||||
|
- City coordinates are static — new Softra branches in unmapped cities won't show pins
|
||||||
|
- Some API zipCodes are null (e.g., Białystok)
|
||||||
|
|
||||||
|
**Blockers:** None
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 08-map-and-cities-widgets, Plan: 01*
|
||||||
|
*Completed: 2026-04-01*
|
||||||
2
.playwright-mcp/console-2026-04-01T17-48-34-799Z.log
Normal file
2
.playwright-mcp/console-2026-04-01T17-48-34-799Z.log
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[ 2171ms] [LOG] JQMIGRATE: Migrate is installed, version 3.4.1 @ https://carei.pagedev.pl/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1:1
|
||||||
|
[ 2728ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://carei.pagedev.pl/favicon.ico:0
|
||||||
1
.playwright-mcp/console-2026-04-01T17-50-48-199Z.log
Normal file
1
.playwright-mcp/console-2026-04-01T17-50-48-199Z.log
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ 230ms] [LOG] JQMIGRATE: Migrate is installed, version 3.4.1 @ https://carei.pagedev.pl/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1:1
|
||||||
618
.playwright-mcp/page-2026-04-01T17-48-37-691Z.yml
Normal file
618
.playwright-mcp/page-2026-04-01T17-48-37-691Z.yml
Normal file
@@ -0,0 +1,618 @@
|
|||||||
|
- generic [active] [ref=e1]:
|
||||||
|
- link "Przejdź do treści" [ref=e2] [cursor=pointer]:
|
||||||
|
- /url: "#content"
|
||||||
|
- banner [ref=e3]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link [ref=e7] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- navigation "Menu" [ref=e9]:
|
||||||
|
- list [ref=e10]:
|
||||||
|
- listitem [ref=e11]:
|
||||||
|
- link "Wynajem długoterminowy" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl/wynajem-dlugoterminowy/
|
||||||
|
- listitem [ref=e13]:
|
||||||
|
- link "Wynajem krótkoterminowy" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- listitem [ref=e15]:
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl/kontakt/
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- list [ref=e20]:
|
||||||
|
- listitem [ref=e21]:
|
||||||
|
- link "+48 572 663 614" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: tel:+48572663614
|
||||||
|
- img [ref=e24]
|
||||||
|
- generic [ref=e30]: +48 572 663 614
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- button "Złóż zapytanie o rezerwację" [ref=e33] [cursor=pointer]:
|
||||||
|
- img [ref=e34]
|
||||||
|
- text: Złóż zapytanie o rezerwację
|
||||||
|
- option "Wybierz segment pojazdu" [disabled] [selected]
|
||||||
|
- option "Miejsce odbioru" [disabled] [selected]
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- heading "Wypożyczalnia samochodów osobowych" [level=4] [ref=e44]
|
||||||
|
- heading "Wybierz segment i zacznij podróż." [level=2] [ref=e46]
|
||||||
|
- paragraph [ref=e48]:
|
||||||
|
- text: Otrzymaj auto w ciągu
|
||||||
|
- strong [ref=e49]: 1h
|
||||||
|
- text: od przyjęcia przez nas zlecenia.
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- heading "Wypełnij formularz rezerwacji." [level=2] [ref=e54]
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- combobox [ref=e58] [cursor=pointer]:
|
||||||
|
- option "Wybierz segment" [disabled] [selected]
|
||||||
|
- img
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e61]:
|
||||||
|
- img
|
||||||
|
- generic: Od kiedy?
|
||||||
|
- textbox "Od kiedy?" [ref=e62]
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- img
|
||||||
|
- generic: Do kiedy?
|
||||||
|
- textbox "Do kiedy?" [ref=e65]
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img
|
||||||
|
- combobox [ref=e68] [cursor=pointer]:
|
||||||
|
- option "Miejsce odbioru" [disabled] [selected]
|
||||||
|
- img
|
||||||
|
- generic [ref=e70] [cursor=pointer]:
|
||||||
|
- checkbox "Zwrot w tej samej lokalizacji" [checked]
|
||||||
|
- img [ref=e72]
|
||||||
|
- generic [ref=e74]: Zwrot w tej samej lokalizacji
|
||||||
|
- button "Złóż zapytanie o rezerwację" [ref=e75] [cursor=pointer]:
|
||||||
|
- img [ref=e76]
|
||||||
|
- text: Złóż zapytanie o rezerwację
|
||||||
|
- generic [ref=e79]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- img [ref=e84]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- heading "Szybka i dokładna obsługa zamówień" [level=3] [ref=e92]
|
||||||
|
- paragraph [ref=e93]: Gwarantujemy pełną gotowość auta na Twój przyjazd.
|
||||||
|
- generic [ref=e99]:
|
||||||
|
- img [ref=e102]
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- heading "Bez opłat przygotowawczych" [level=3] [ref=e109]
|
||||||
|
- paragraph [ref=e110]: Stawiamy na jasne zasady, nie doliczamy ukrytych kosztów.
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- heading "Atrakcyjne promocje weekendowe" [level=3] [ref=e124]
|
||||||
|
- paragraph [ref=e125]: Oszczędzaj na wynajmie planując weekendowy wyjazd.
|
||||||
|
- generic [ref=e127]:
|
||||||
|
- heading "Jak wypożyczyć auto krótkoterminowo?" [level=2] [ref=e132]
|
||||||
|
- paragraph [ref=e137]: Najszybciej i najprościej zrobić to z Carei – w ciągu 1h od przyjęcia przez nas zlecenia otrzymasz już samochód.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e145]:
|
||||||
|
- generic [ref=e146]:
|
||||||
|
- generic: "1."
|
||||||
|
- generic [ref=e147]:
|
||||||
|
- heading "Złóż zapytanie o rezerwację" [level=3] [ref=e148]
|
||||||
|
- paragraph [ref=e149]: W formularzu zaznacz jaka oferta Cię interesuje i podaj nam dane do kontaktu.
|
||||||
|
- generic [ref=e152]:
|
||||||
|
- generic [ref=e153]:
|
||||||
|
- generic: "2."
|
||||||
|
- generic [ref=e154]:
|
||||||
|
- heading "Skontaktuje się z Tobą obsługa klienta" [level=3] [ref=e155]
|
||||||
|
- paragraph [ref=e156]: Nasza infolinia działa 24h na dobę i przedstawi Ci konkretną propozycję
|
||||||
|
- generic [ref=e159]:
|
||||||
|
- generic [ref=e160]:
|
||||||
|
- generic: "3."
|
||||||
|
- generic [ref=e161]:
|
||||||
|
- heading "Odbierz kluczyki" [level=3] [ref=e162]
|
||||||
|
- paragraph [ref=e163]: Gwarantujemy minimum formalności przy odbiorze auta.
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e170] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e171]:
|
||||||
|
- img [ref=e173]
|
||||||
|
- generic [ref=e175]: Złóż zapytanie o rezerwację
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- heading "Chcesz wynająć auto na dłużej niż miesiąc?" [level=2] [ref=e185]
|
||||||
|
- paragraph [ref=e187]: Przygotujemy dla Ciebie atrakcyjne warunki wynajmu długoterminowego.
|
||||||
|
- link "Oferta najmu długoterminowego" [ref=e189] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e191]: Oferta najmu długoterminowego
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- img [ref=e201]
|
||||||
|
- generic [ref=e219]:
|
||||||
|
- heading "17 oddziałów w całej Polsce" [level=3] [ref=e221]:
|
||||||
|
- text: 17 oddziałów
|
||||||
|
- text: w całej Polsce
|
||||||
|
- heading "Podróżuj z Carei!" [level=2] [ref=e223]
|
||||||
|
- generic [ref=e224]:
|
||||||
|
- paragraph [ref=e225]: Od 2006 roku zajmujemy się szeroko rozumianym wynajmem samochodów osobowych na terenie Polski.
|
||||||
|
- paragraph [ref=e226]:
|
||||||
|
- text: W naszej ofercie znajdują się
|
||||||
|
- strong [ref=e227]: samochody standardowe oraz klasy premium
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e230]:
|
||||||
|
- generic [ref=e231]: BIAŁYSTOK
|
||||||
|
- generic [ref=e232]: "|"
|
||||||
|
- generic [ref=e233]: BYDGOSZC D
|
||||||
|
- generic [ref=e234]: "|"
|
||||||
|
- generic [ref=e235]: BYDGOSZC L
|
||||||
|
- generic [ref=e236]: "|"
|
||||||
|
- generic [ref=e237]: BYDGOSZCZ
|
||||||
|
- generic [ref=e238]: "|"
|
||||||
|
- generic [ref=e239]: GDAŃSK
|
||||||
|
- generic [ref=e240]: "|"
|
||||||
|
- generic [ref=e241]: GDAŃSK D
|
||||||
|
- generic [ref=e242]: "|"
|
||||||
|
- generic [ref=e243]: GDAŃSK L
|
||||||
|
- generic [ref=e244]: "|"
|
||||||
|
- generic [ref=e245]: GORZÓW WIE
|
||||||
|
- generic [ref=e246]: "|"
|
||||||
|
- generic [ref=e247]: KATOWICE
|
||||||
|
- generic [ref=e248]: "|"
|
||||||
|
- generic [ref=e249]: KATOWICE D
|
||||||
|
- generic [ref=e250]: "|"
|
||||||
|
- generic [ref=e251]: KATOWICE L
|
||||||
|
- generic [ref=e252]: "|"
|
||||||
|
- generic [ref=e253]: KIELCE
|
||||||
|
- generic [ref=e254]: "|"
|
||||||
|
- generic [ref=e255]: KRAKÓW
|
||||||
|
- generic [ref=e256]: "|"
|
||||||
|
- generic [ref=e257]: KRAKÓW D
|
||||||
|
- generic [ref=e258]: "|"
|
||||||
|
- generic [ref=e259]: KRAKÓW L
|
||||||
|
- generic [ref=e260]: "|"
|
||||||
|
- generic [ref=e261]: LUBLIN
|
||||||
|
- generic [ref=e262]: "|"
|
||||||
|
- generic [ref=e263]: LUBLIN D
|
||||||
|
- generic [ref=e264]: "|"
|
||||||
|
- generic [ref=e265]: LUBLIN L
|
||||||
|
- generic [ref=e266]: "|"
|
||||||
|
- generic [ref=e267]: OLSZTYN
|
||||||
|
- generic [ref=e268]: "|"
|
||||||
|
- generic [ref=e269]: POZNAŃ
|
||||||
|
- generic [ref=e270]: "|"
|
||||||
|
- generic [ref=e271]: POZNAŃ D
|
||||||
|
- generic [ref=e272]: "|"
|
||||||
|
- generic [ref=e273]: POZNAŃ L
|
||||||
|
- generic [ref=e274]: "|"
|
||||||
|
- generic [ref=e275]: RADOM
|
||||||
|
- generic [ref=e276]: "|"
|
||||||
|
- generic [ref=e277]: RADOM D
|
||||||
|
- generic [ref=e278]: "|"
|
||||||
|
- generic [ref=e279]: RADOM L
|
||||||
|
- generic [ref=e280]: "|"
|
||||||
|
- generic [ref=e281]: RUMIA D
|
||||||
|
- generic [ref=e282]: "|"
|
||||||
|
- generic [ref=e283]: RZESZÓW
|
||||||
|
- generic [ref=e284]: "|"
|
||||||
|
- generic [ref=e285]: RZESZÓW L
|
||||||
|
- generic [ref=e286]: "|"
|
||||||
|
- generic [ref=e287]: RZSZÓW D
|
||||||
|
- generic [ref=e288]: "|"
|
||||||
|
- generic [ref=e289]: SK-KAM
|
||||||
|
- generic [ref=e290]: "|"
|
||||||
|
- generic [ref=e291]: SOPOT D
|
||||||
|
- generic [ref=e292]: "|"
|
||||||
|
- generic [ref=e293]: SZCZECIN
|
||||||
|
- generic [ref=e294]: "|"
|
||||||
|
- generic [ref=e295]: WARSZAWA
|
||||||
|
- generic [ref=e296]: "|"
|
||||||
|
- generic [ref=e297]: WARSZAWA D
|
||||||
|
- generic [ref=e298]: "|"
|
||||||
|
- generic [ref=e299]: WARSZAWA L
|
||||||
|
- generic [ref=e300]: "|"
|
||||||
|
- generic [ref=e301]: WROCŁAW
|
||||||
|
- generic [ref=e302]: "|"
|
||||||
|
- generic [ref=e303]: WROCŁAW D
|
||||||
|
- generic [ref=e304]: "|"
|
||||||
|
- generic [ref=e305]: WROCŁAW L
|
||||||
|
- generic [ref=e306]: "|"
|
||||||
|
- generic [ref=e307]: ŁÓDŹ
|
||||||
|
- generic [ref=e314]:
|
||||||
|
- heading "Wypożycz auto na swój wyjazd." [level=2] [ref=e316]
|
||||||
|
- paragraph [ref=e318]:
|
||||||
|
- text: Szybka obsługa zamówienia
|
||||||
|
- text: i minimum formalności.
|
||||||
|
- generic [ref=e319]:
|
||||||
|
- region "Carousel" [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- group [ref=e322]:
|
||||||
|
- generic [ref=e326]:
|
||||||
|
- heading [level=3] [ref=e328]: Segment B
|
||||||
|
- paragraph [ref=e330]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e332]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e334] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e335]:
|
||||||
|
- img [ref=e337]
|
||||||
|
- generic [ref=e339]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e340]:
|
||||||
|
- generic [ref=e344]:
|
||||||
|
- heading [level=3] [ref=e346]: Segment LUX
|
||||||
|
- paragraph [ref=e348]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e350]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e352] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- img [ref=e355]
|
||||||
|
- generic [ref=e357]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e358]:
|
||||||
|
- generic [ref=e362]:
|
||||||
|
- heading [level=3] [ref=e364]: Segment C/C+
|
||||||
|
- paragraph [ref=e366]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e368]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e370] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e371]:
|
||||||
|
- img [ref=e373]
|
||||||
|
- generic [ref=e375]: Złóż zapytanie o rezerwację
|
||||||
|
- group "1 / 3" [ref=e376]:
|
||||||
|
- generic [ref=e380]:
|
||||||
|
- heading "Segment B" [level=3] [ref=e382]
|
||||||
|
- paragraph [ref=e384]:
|
||||||
|
- text: "Przykładowy model:"
|
||||||
|
- text: Toyota Yaris
|
||||||
|
- paragraph [ref=e386]: Od 79 zł brutto / doba
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e388] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e389]:
|
||||||
|
- img [ref=e391]
|
||||||
|
- generic [ref=e393]: Złóż zapytanie o rezerwację
|
||||||
|
- group "2 / 3" [ref=e394]:
|
||||||
|
- generic [ref=e398]:
|
||||||
|
- heading "Segment LUX" [level=3] [ref=e400]
|
||||||
|
- paragraph [ref=e402]:
|
||||||
|
- text: "Przykładowy model:"
|
||||||
|
- text: Toyota Yaris
|
||||||
|
- paragraph [ref=e404]: Od 79 zł brutto / doba
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e406] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e407]:
|
||||||
|
- img [ref=e409]
|
||||||
|
- generic [ref=e411]: Złóż zapytanie o rezerwację
|
||||||
|
- group "3 / 3" [ref=e412]:
|
||||||
|
- generic [ref=e416]:
|
||||||
|
- heading "Segment C/C+" [level=3] [ref=e418]
|
||||||
|
- paragraph [ref=e420]:
|
||||||
|
- text: "Przykładowy model:"
|
||||||
|
- text: Toyota Yaris
|
||||||
|
- paragraph [ref=e422]: Od 79 zł brutto / doba
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e424] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e425]:
|
||||||
|
- img [ref=e427]
|
||||||
|
- generic [ref=e429]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e430]:
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- heading [level=3] [ref=e436]: Segment B
|
||||||
|
- paragraph [ref=e438]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e440]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e442] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e443]:
|
||||||
|
- img [ref=e445]
|
||||||
|
- generic [ref=e447]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e448]:
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- heading [level=3] [ref=e454]: Segment LUX
|
||||||
|
- paragraph [ref=e456]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e458]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e460] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e461]:
|
||||||
|
- img [ref=e463]
|
||||||
|
- generic [ref=e465]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e466]:
|
||||||
|
- generic [ref=e470]:
|
||||||
|
- heading [level=3] [ref=e472]: Segment C/C+
|
||||||
|
- paragraph [ref=e474]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e476]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- img [ref=e481]
|
||||||
|
- generic [ref=e483]: Złóż zapytanie o rezerwację
|
||||||
|
- button "Poprzedni slajd" [ref=e484] [cursor=pointer]:
|
||||||
|
- img [ref=e485]
|
||||||
|
- button "Następny slajd" [ref=e487] [cursor=pointer]:
|
||||||
|
- img [ref=e488]
|
||||||
|
- heading "Opinie o Carei." [level=2] [ref=e500]
|
||||||
|
- region "Carousel" [ref=e502]:
|
||||||
|
- generic [ref=e503]:
|
||||||
|
- group [ref=e504]:
|
||||||
|
- generic [ref=e506]:
|
||||||
|
- generic [ref=e507]:
|
||||||
|
- img [ref=e510]:
|
||||||
|
- generic [ref=e511]:
|
||||||
|
- img [ref=e513]
|
||||||
|
- img [ref=e516]
|
||||||
|
- generic [ref=e518]:
|
||||||
|
- img [ref=e520]
|
||||||
|
- img [ref=e523]
|
||||||
|
- generic [ref=e525]:
|
||||||
|
- img [ref=e527]
|
||||||
|
- img [ref=e530]
|
||||||
|
- generic [ref=e532]:
|
||||||
|
- img [ref=e534]
|
||||||
|
- img [ref=e537]
|
||||||
|
- generic [ref=e539]:
|
||||||
|
- img [ref=e541]
|
||||||
|
- img [ref=e544]
|
||||||
|
- link [ref=e547] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e549]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e550]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e551]: Aneta W.
|
||||||
|
- group [ref=e552]:
|
||||||
|
- generic [ref=e554]:
|
||||||
|
- generic [ref=e555]:
|
||||||
|
- img [ref=e558]:
|
||||||
|
- generic [ref=e559]:
|
||||||
|
- img [ref=e561]
|
||||||
|
- img [ref=e564]
|
||||||
|
- generic [ref=e566]:
|
||||||
|
- img [ref=e568]
|
||||||
|
- img [ref=e571]
|
||||||
|
- generic [ref=e573]:
|
||||||
|
- img [ref=e575]
|
||||||
|
- img [ref=e578]
|
||||||
|
- generic [ref=e580]:
|
||||||
|
- img [ref=e582]
|
||||||
|
- img [ref=e585]
|
||||||
|
- generic [ref=e587]:
|
||||||
|
- img [ref=e589]
|
||||||
|
- img [ref=e592]
|
||||||
|
- link [ref=e595] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e597]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e598]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e599]: Aneta W.
|
||||||
|
- group [ref=e600]:
|
||||||
|
- generic [ref=e602]:
|
||||||
|
- generic [ref=e603]:
|
||||||
|
- img [ref=e606]:
|
||||||
|
- generic [ref=e607]:
|
||||||
|
- img [ref=e609]
|
||||||
|
- img [ref=e612]
|
||||||
|
- generic [ref=e614]:
|
||||||
|
- img [ref=e616]
|
||||||
|
- img [ref=e619]
|
||||||
|
- generic [ref=e621]:
|
||||||
|
- img [ref=e623]
|
||||||
|
- img [ref=e626]
|
||||||
|
- generic [ref=e628]:
|
||||||
|
- img [ref=e630]
|
||||||
|
- img [ref=e633]
|
||||||
|
- generic [ref=e635]:
|
||||||
|
- img [ref=e637]
|
||||||
|
- img [ref=e640]
|
||||||
|
- link [ref=e643] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e645]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e646]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e647]: Aneta W.
|
||||||
|
- group "1 / 4" [ref=e648]:
|
||||||
|
- generic [ref=e650]:
|
||||||
|
- generic [ref=e651]:
|
||||||
|
- img "Ocena 5 z 5" [ref=e654]:
|
||||||
|
- generic [ref=e655]:
|
||||||
|
- img [ref=e657]
|
||||||
|
- img [ref=e660]
|
||||||
|
- generic [ref=e662]:
|
||||||
|
- img [ref=e664]
|
||||||
|
- img [ref=e667]
|
||||||
|
- generic [ref=e669]:
|
||||||
|
- img [ref=e671]
|
||||||
|
- img [ref=e674]
|
||||||
|
- generic [ref=e676]:
|
||||||
|
- img [ref=e678]
|
||||||
|
- img [ref=e681]
|
||||||
|
- generic [ref=e683]:
|
||||||
|
- img [ref=e685]
|
||||||
|
- img [ref=e688]
|
||||||
|
- link [ref=e691] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e693]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e694]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e695]: Aneta W.
|
||||||
|
- group "2 / 4" [ref=e696]:
|
||||||
|
- generic [ref=e698]:
|
||||||
|
- generic [ref=e699]:
|
||||||
|
- img "Ocena 5 z 5" [ref=e702]:
|
||||||
|
- generic [ref=e703]:
|
||||||
|
- img [ref=e705]
|
||||||
|
- img [ref=e708]
|
||||||
|
- generic [ref=e710]:
|
||||||
|
- img [ref=e712]
|
||||||
|
- img [ref=e715]
|
||||||
|
- generic [ref=e717]:
|
||||||
|
- img [ref=e719]
|
||||||
|
- img [ref=e722]
|
||||||
|
- generic [ref=e724]:
|
||||||
|
- img [ref=e726]
|
||||||
|
- img [ref=e729]
|
||||||
|
- generic [ref=e731]:
|
||||||
|
- img [ref=e733]
|
||||||
|
- img [ref=e736]
|
||||||
|
- link [ref=e739] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e741]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e742]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e743]: Aneta W.
|
||||||
|
- group "3 / 4" [ref=e744]:
|
||||||
|
- generic [ref=e746]:
|
||||||
|
- generic [ref=e747]:
|
||||||
|
- img "Ocena 5 z 5" [ref=e750]:
|
||||||
|
- generic [ref=e751]:
|
||||||
|
- img [ref=e753]
|
||||||
|
- img [ref=e756]
|
||||||
|
- generic [ref=e758]:
|
||||||
|
- img [ref=e760]
|
||||||
|
- img [ref=e763]
|
||||||
|
- generic [ref=e765]:
|
||||||
|
- img [ref=e767]
|
||||||
|
- img [ref=e770]
|
||||||
|
- generic [ref=e772]:
|
||||||
|
- img [ref=e774]
|
||||||
|
- img [ref=e777]
|
||||||
|
- generic [ref=e779]:
|
||||||
|
- img [ref=e781]
|
||||||
|
- img [ref=e784]
|
||||||
|
- link [ref=e787] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e789]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e790]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e791]: Aneta W.
|
||||||
|
- group [ref=e792]:
|
||||||
|
- generic [ref=e794]:
|
||||||
|
- generic [ref=e795]:
|
||||||
|
- img [ref=e798]:
|
||||||
|
- generic [ref=e799]:
|
||||||
|
- img [ref=e801]
|
||||||
|
- img [ref=e804]
|
||||||
|
- generic [ref=e806]:
|
||||||
|
- img [ref=e808]
|
||||||
|
- img [ref=e811]
|
||||||
|
- generic [ref=e813]:
|
||||||
|
- img [ref=e815]
|
||||||
|
- img [ref=e818]
|
||||||
|
- generic [ref=e820]:
|
||||||
|
- img [ref=e822]
|
||||||
|
- img [ref=e825]
|
||||||
|
- generic [ref=e827]:
|
||||||
|
- img [ref=e829]
|
||||||
|
- img [ref=e832]
|
||||||
|
- link [ref=e835] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e837]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e838]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e839]: Aneta W.
|
||||||
|
- group [ref=e840]:
|
||||||
|
- generic [ref=e842]:
|
||||||
|
- generic [ref=e843]:
|
||||||
|
- img [ref=e846]:
|
||||||
|
- generic [ref=e847]:
|
||||||
|
- img [ref=e849]
|
||||||
|
- img [ref=e852]
|
||||||
|
- generic [ref=e854]:
|
||||||
|
- img [ref=e856]
|
||||||
|
- img [ref=e859]
|
||||||
|
- generic [ref=e861]:
|
||||||
|
- img [ref=e863]
|
||||||
|
- img [ref=e866]
|
||||||
|
- generic [ref=e868]:
|
||||||
|
- img [ref=e870]
|
||||||
|
- img [ref=e873]
|
||||||
|
- generic [ref=e875]:
|
||||||
|
- img [ref=e877]
|
||||||
|
- img [ref=e880]
|
||||||
|
- link [ref=e883] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e885]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e886]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e887]: Aneta W.
|
||||||
|
- group [ref=e888]:
|
||||||
|
- generic [ref=e890]:
|
||||||
|
- generic [ref=e891]:
|
||||||
|
- img [ref=e894]:
|
||||||
|
- generic [ref=e895]:
|
||||||
|
- img [ref=e897]
|
||||||
|
- img [ref=e900]
|
||||||
|
- generic [ref=e902]:
|
||||||
|
- img [ref=e904]
|
||||||
|
- img [ref=e907]
|
||||||
|
- generic [ref=e909]:
|
||||||
|
- img [ref=e911]
|
||||||
|
- img [ref=e914]
|
||||||
|
- generic [ref=e916]:
|
||||||
|
- img [ref=e918]
|
||||||
|
- img [ref=e921]
|
||||||
|
- generic [ref=e923]:
|
||||||
|
- img [ref=e925]
|
||||||
|
- img [ref=e928]
|
||||||
|
- link [ref=e931] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e933]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e934]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e935]: Aneta W.
|
||||||
|
- group [ref=e936]:
|
||||||
|
- generic [ref=e938]:
|
||||||
|
- generic [ref=e939]:
|
||||||
|
- img [ref=e942]:
|
||||||
|
- generic [ref=e943]:
|
||||||
|
- img [ref=e945]
|
||||||
|
- img [ref=e948]
|
||||||
|
- generic [ref=e950]:
|
||||||
|
- img [ref=e952]
|
||||||
|
- img [ref=e955]
|
||||||
|
- generic [ref=e957]:
|
||||||
|
- img [ref=e959]
|
||||||
|
- img [ref=e962]
|
||||||
|
- generic [ref=e964]:
|
||||||
|
- img [ref=e966]
|
||||||
|
- img [ref=e969]
|
||||||
|
- generic [ref=e971]:
|
||||||
|
- img [ref=e973]
|
||||||
|
- img [ref=e976]
|
||||||
|
- link [ref=e979] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e981]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e982]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e983]: Aneta W.
|
||||||
|
- contentinfo [ref=e984]:
|
||||||
|
- generic [ref=e987]:
|
||||||
|
- heading "Szukasz więcej informacji?" [level=4] [ref=e989]
|
||||||
|
- heading "Skontaktuj się z naszą obsługą." [level=3] [ref=e994]:
|
||||||
|
- text: Skontaktuj się
|
||||||
|
- text: z naszą obsługą.
|
||||||
|
- generic [ref=e998]:
|
||||||
|
- generic [ref=e1000]:
|
||||||
|
- link "Assistance" [ref=e1002] [cursor=pointer]:
|
||||||
|
- /url: tel:+48572663614
|
||||||
|
- img [ref=e1003]
|
||||||
|
- generic [ref=e1007]:
|
||||||
|
- heading "Assistance" [level=3] [ref=e1008]:
|
||||||
|
- link "Assistance" [ref=e1009] [cursor=pointer]:
|
||||||
|
- /url: tel:+48572663614
|
||||||
|
- paragraph [ref=e1010]: +48 572 663 614
|
||||||
|
- generic [ref=e1012]:
|
||||||
|
- link "Biuro" [ref=e1014] [cursor=pointer]:
|
||||||
|
- /url: mailto:bok@carei.pl
|
||||||
|
- img [ref=e1015]
|
||||||
|
- generic [ref=e1021]:
|
||||||
|
- heading "Biuro" [level=3] [ref=e1022]:
|
||||||
|
- link "Biuro" [ref=e1023] [cursor=pointer]:
|
||||||
|
- /url: mailto:bok@carei.pl
|
||||||
|
- paragraph [ref=e1024]: bok@carei.pl
|
||||||
|
- generic [ref=e1035]:
|
||||||
|
- heading "Carei - Wypożyczalnia aut osobowych" [level=3] [ref=e1037]
|
||||||
|
- generic [ref=e1038]:
|
||||||
|
- paragraph [ref=e1040]:
|
||||||
|
- text: CAREI Sp. z o.o. Sp. k.
|
||||||
|
- text: ul. Solipska 1/U4,
|
||||||
|
- text: 02-482 Warszawa
|
||||||
|
- paragraph [ref=e1042]:
|
||||||
|
- text: "NIP: 527 249 90 39"
|
||||||
|
- text: "REGON: 140473129 KRS: 0000668452"
|
||||||
|
- generic [ref=e1050]:
|
||||||
|
- paragraph [ref=e1052]: Copyright © 2026 Carei
|
||||||
|
- paragraph [ref=e1054]: "Designed by: Kreatywny Brand"
|
||||||
|
- generic [ref=e1055]: laptop
|
||||||
587
.playwright-mcp/page-2026-04-01T17-50-49-058Z.yml
Normal file
587
.playwright-mcp/page-2026-04-01T17-50-49-058Z.yml
Normal file
@@ -0,0 +1,587 @@
|
|||||||
|
- generic [active] [ref=e1]:
|
||||||
|
- link "Przejdź do treści" [ref=e2] [cursor=pointer]:
|
||||||
|
- /url: "#content"
|
||||||
|
- banner [ref=e3]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link [ref=e7] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- navigation "Menu" [ref=e9]:
|
||||||
|
- list [ref=e10]:
|
||||||
|
- listitem [ref=e11]:
|
||||||
|
- link "Wynajem długoterminowy" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl/wynajem-dlugoterminowy/
|
||||||
|
- listitem [ref=e13]:
|
||||||
|
- link "Wynajem krótkoterminowy" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- listitem [ref=e15]:
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl/kontakt/
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- list [ref=e20]:
|
||||||
|
- listitem [ref=e21]:
|
||||||
|
- link "+48 572 663 614" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: tel:+48572663614
|
||||||
|
- img [ref=e24]
|
||||||
|
- generic [ref=e30]: +48 572 663 614
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- button "Złóż zapytanie o rezerwację" [ref=e33] [cursor=pointer]:
|
||||||
|
- img [ref=e34]
|
||||||
|
- text: Złóż zapytanie o rezerwację
|
||||||
|
- option "Wybierz segment pojazdu" [disabled] [selected]
|
||||||
|
- option "Miejsce odbioru" [disabled] [selected]
|
||||||
|
- generic [ref=e39]:
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- heading "Wypożyczalnia samochodów osobowych" [level=4] [ref=e44]
|
||||||
|
- heading "Wybierz segment i zacznij podróż." [level=2] [ref=e46]
|
||||||
|
- paragraph [ref=e48]:
|
||||||
|
- text: Otrzymaj auto w ciągu
|
||||||
|
- strong [ref=e49]: 1h
|
||||||
|
- text: od przyjęcia przez nas zlecenia.
|
||||||
|
- generic [ref=e53]:
|
||||||
|
- heading "Wypełnij formularz rezerwacji." [level=2] [ref=e54]
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- combobox [ref=e58] [cursor=pointer]:
|
||||||
|
- option "Wybierz segment" [disabled] [selected]
|
||||||
|
- option "Segment B"
|
||||||
|
- option "Segment C"
|
||||||
|
- option "Segment C+"
|
||||||
|
- option "Segment D"
|
||||||
|
- option "Segment E"
|
||||||
|
- option "Segment LCV"
|
||||||
|
- option "Segment LUX"
|
||||||
|
- option "Segment P"
|
||||||
|
- option "Segment SUV"
|
||||||
|
- option "Segment SUV+"
|
||||||
|
- option "Segment VAN"
|
||||||
|
- img
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e61]:
|
||||||
|
- img
|
||||||
|
- generic: Od kiedy?
|
||||||
|
- textbox "Od kiedy?" [ref=e62]
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- img
|
||||||
|
- generic: Do kiedy?
|
||||||
|
- textbox "Do kiedy?" [ref=e65]
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img
|
||||||
|
- combobox [disabled] [ref=e68] [cursor=pointer]:
|
||||||
|
- option "Najpierw wybierz segment" [disabled] [selected]
|
||||||
|
- img
|
||||||
|
- generic [ref=e70] [cursor=pointer]:
|
||||||
|
- checkbox "Zwrot w tej samej lokalizacji" [checked]
|
||||||
|
- img [ref=e72]
|
||||||
|
- generic [ref=e74]: Zwrot w tej samej lokalizacji
|
||||||
|
- button "Złóż zapytanie o rezerwację" [ref=e75] [cursor=pointer]:
|
||||||
|
- img [ref=e76]
|
||||||
|
- text: Złóż zapytanie o rezerwację
|
||||||
|
- generic [ref=e79]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- img [ref=e84]
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- heading "Szybka i dokładna obsługa zamówień" [level=3] [ref=e92]
|
||||||
|
- paragraph [ref=e93]: Gwarantujemy pełną gotowość auta na Twój przyjazd.
|
||||||
|
- generic [ref=e99]:
|
||||||
|
- img [ref=e102]
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- heading "Bez opłat przygotowawczych" [level=3] [ref=e109]
|
||||||
|
- paragraph [ref=e110]: Stawiamy na jasne zasady, nie doliczamy ukrytych kosztów.
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- heading "Atrakcyjne promocje weekendowe" [level=3] [ref=e124]
|
||||||
|
- paragraph [ref=e125]: Oszczędzaj na wynajmie planując weekendowy wyjazd.
|
||||||
|
- generic [ref=e127]:
|
||||||
|
- heading "Jak wypożyczyć auto krótkoterminowo?" [level=2] [ref=e132]
|
||||||
|
- paragraph [ref=e137]: Najszybciej i najprościej zrobić to z Carei – w ciągu 1h od przyjęcia przez nas zlecenia otrzymasz już samochód.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e145]:
|
||||||
|
- generic [ref=e146]:
|
||||||
|
- generic: "1."
|
||||||
|
- generic [ref=e147]:
|
||||||
|
- heading "Złóż zapytanie o rezerwację" [level=3] [ref=e148]
|
||||||
|
- paragraph [ref=e149]: W formularzu zaznacz jaka oferta Cię interesuje i podaj nam dane do kontaktu.
|
||||||
|
- generic [ref=e152]:
|
||||||
|
- generic [ref=e153]:
|
||||||
|
- generic: "2."
|
||||||
|
- generic [ref=e154]:
|
||||||
|
- heading "Skontaktuje się z Tobą obsługa klienta" [level=3] [ref=e155]
|
||||||
|
- paragraph [ref=e156]: Nasza infolinia działa 24h na dobę i przedstawi Ci konkretną propozycję
|
||||||
|
- generic [ref=e159]:
|
||||||
|
- generic [ref=e160]:
|
||||||
|
- generic: "3."
|
||||||
|
- generic [ref=e161]:
|
||||||
|
- heading "Odbierz kluczyki" [level=3] [ref=e162]
|
||||||
|
- paragraph [ref=e163]: Gwarantujemy minimum formalności przy odbiorze auta.
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e170] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e171]:
|
||||||
|
- img [ref=e173]
|
||||||
|
- generic [ref=e175]: Złóż zapytanie o rezerwację
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- heading "Chcesz wynająć auto na dłużej niż miesiąc?" [level=2] [ref=e185]
|
||||||
|
- paragraph [ref=e187]: Przygotujemy dla Ciebie atrakcyjne warunki wynajmu długoterminowego.
|
||||||
|
- link "Oferta najmu długoterminowego" [ref=e189] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e191]: Oferta najmu długoterminowego
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- img [ref=e201]
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- heading "17 oddziałów w całej Polsce" [level=3] [ref=e224]:
|
||||||
|
- text: 17 oddziałów
|
||||||
|
- text: w całej Polsce
|
||||||
|
- heading "Podróżuj z Carei!" [level=2] [ref=e226]
|
||||||
|
- generic [ref=e227]:
|
||||||
|
- paragraph [ref=e228]: Od 2006 roku zajmujemy się szeroko rozumianym wynajmem samochodów osobowych na terenie Polski.
|
||||||
|
- paragraph [ref=e229]:
|
||||||
|
- text: W naszej ofercie znajdują się
|
||||||
|
- strong [ref=e230]: samochody standardowe oraz klasy premium
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e233]:
|
||||||
|
- generic [ref=e234]: Białystok
|
||||||
|
- generic [ref=e235]: "|"
|
||||||
|
- generic [ref=e236]: Bydgoszcz
|
||||||
|
- generic [ref=e237]: "|"
|
||||||
|
- generic [ref=e238]: Gdańsk
|
||||||
|
- generic [ref=e239]: "|"
|
||||||
|
- generic [ref=e240]: Gorzów Wielkopolski
|
||||||
|
- generic [ref=e241]: "|"
|
||||||
|
- generic [ref=e242]: Katowice
|
||||||
|
- generic [ref=e243]: "|"
|
||||||
|
- generic [ref=e244]: Kielce
|
||||||
|
- generic [ref=e245]: "|"
|
||||||
|
- generic [ref=e246]: Kraków
|
||||||
|
- generic [ref=e247]: "|"
|
||||||
|
- generic [ref=e248]: Lublin
|
||||||
|
- generic [ref=e249]: "|"
|
||||||
|
- generic [ref=e250]: Olsztyn
|
||||||
|
- generic [ref=e251]: "|"
|
||||||
|
- generic [ref=e252]: Poznań
|
||||||
|
- generic [ref=e253]: "|"
|
||||||
|
- generic [ref=e254]: Radom
|
||||||
|
- generic [ref=e255]: "|"
|
||||||
|
- generic [ref=e256]: Rumia
|
||||||
|
- generic [ref=e257]: "|"
|
||||||
|
- generic [ref=e258]: Rzeszów
|
||||||
|
- generic [ref=e259]: "|"
|
||||||
|
- generic [ref=e260]: Sopot
|
||||||
|
- generic [ref=e261]: "|"
|
||||||
|
- generic [ref=e262]: Szczecin
|
||||||
|
- generic [ref=e263]: "|"
|
||||||
|
- generic [ref=e264]: Warszawa
|
||||||
|
- generic [ref=e265]: "|"
|
||||||
|
- generic [ref=e266]: Wrocław
|
||||||
|
- generic [ref=e267]: "|"
|
||||||
|
- generic [ref=e268]: Łódź
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- heading "Wypożycz auto na swój wyjazd." [level=2] [ref=e277]
|
||||||
|
- paragraph [ref=e279]:
|
||||||
|
- text: Szybka obsługa zamówienia
|
||||||
|
- text: i minimum formalności.
|
||||||
|
- generic [ref=e280]:
|
||||||
|
- region "Carousel" [ref=e281]:
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- group [ref=e283]:
|
||||||
|
- generic [ref=e287]:
|
||||||
|
- heading [level=3] [ref=e289]: Segment B
|
||||||
|
- paragraph [ref=e291]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e293]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e295] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e296]:
|
||||||
|
- img [ref=e298]
|
||||||
|
- generic [ref=e300]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e301]:
|
||||||
|
- generic [ref=e305]:
|
||||||
|
- heading [level=3] [ref=e307]: Segment LUX
|
||||||
|
- paragraph [ref=e309]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e311]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e313] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e314]:
|
||||||
|
- img [ref=e316]
|
||||||
|
- generic [ref=e318]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e319]:
|
||||||
|
- generic [ref=e323]:
|
||||||
|
- heading [level=3] [ref=e325]: Segment C/C+
|
||||||
|
- paragraph [ref=e327]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e329]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e331] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Złóż zapytanie o rezerwację
|
||||||
|
- group "1 / 3" [ref=e337]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- heading "Segment B" [level=3] [ref=e343]
|
||||||
|
- paragraph [ref=e345]:
|
||||||
|
- text: "Przykładowy model:"
|
||||||
|
- text: Toyota Yaris
|
||||||
|
- paragraph [ref=e347]: Od 79 zł brutto / doba
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e349] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e350]:
|
||||||
|
- img [ref=e352]
|
||||||
|
- generic [ref=e354]: Złóż zapytanie o rezerwację
|
||||||
|
- group "2 / 3" [ref=e355]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- heading "Segment LUX" [level=3] [ref=e361]
|
||||||
|
- paragraph [ref=e363]:
|
||||||
|
- text: "Przykładowy model:"
|
||||||
|
- text: Toyota Yaris
|
||||||
|
- paragraph [ref=e365]: Od 79 zł brutto / doba
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e367] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- img [ref=e370]
|
||||||
|
- generic [ref=e372]: Złóż zapytanie o rezerwację
|
||||||
|
- group "3 / 3" [ref=e373]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- heading "Segment C/C+" [level=3] [ref=e379]
|
||||||
|
- paragraph [ref=e381]:
|
||||||
|
- text: "Przykładowy model:"
|
||||||
|
- text: Toyota Yaris
|
||||||
|
- paragraph [ref=e383]: Od 79 zł brutto / doba
|
||||||
|
- link "Złóż zapytanie o rezerwację" [ref=e385] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e386]:
|
||||||
|
- img [ref=e388]
|
||||||
|
- generic [ref=e390]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e391]:
|
||||||
|
- generic [ref=e395]:
|
||||||
|
- heading [level=3] [ref=e397]: Segment B
|
||||||
|
- paragraph [ref=e399]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e401]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e403] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e404]:
|
||||||
|
- img [ref=e406]
|
||||||
|
- generic [ref=e408]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e409]:
|
||||||
|
- generic [ref=e413]:
|
||||||
|
- heading [level=3] [ref=e415]: Segment LUX
|
||||||
|
- paragraph [ref=e417]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e419]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e421] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e422]:
|
||||||
|
- img [ref=e424]
|
||||||
|
- generic [ref=e426]: Złóż zapytanie o rezerwację
|
||||||
|
- group [ref=e427]:
|
||||||
|
- generic [ref=e431]:
|
||||||
|
- heading [level=3] [ref=e433]: Segment C/C+
|
||||||
|
- paragraph [ref=e435]: "Przykładowy model: Toyota Yaris"
|
||||||
|
- paragraph [ref=e437]: Od 79 zł brutto / doba
|
||||||
|
- link [ref=e439] [cursor=pointer]:
|
||||||
|
- /url: "#"
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e442]
|
||||||
|
- generic [ref=e444]: Złóż zapytanie o rezerwację
|
||||||
|
- button "Poprzedni slajd" [ref=e445] [cursor=pointer]:
|
||||||
|
- img [ref=e446]
|
||||||
|
- button "Następny slajd" [ref=e448] [cursor=pointer]:
|
||||||
|
- img [ref=e449]
|
||||||
|
- heading "Opinie o Carei." [level=2] [ref=e461]
|
||||||
|
- region "Carousel" [ref=e463]:
|
||||||
|
- generic [ref=e464]:
|
||||||
|
- group [ref=e465]:
|
||||||
|
- generic [ref=e467]:
|
||||||
|
- generic [ref=e468]:
|
||||||
|
- img [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- img [ref=e474]
|
||||||
|
- img [ref=e477]
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- img [ref=e481]
|
||||||
|
- img [ref=e484]
|
||||||
|
- generic [ref=e486]:
|
||||||
|
- img [ref=e488]
|
||||||
|
- img [ref=e491]
|
||||||
|
- generic [ref=e493]:
|
||||||
|
- img [ref=e495]
|
||||||
|
- img [ref=e498]
|
||||||
|
- generic [ref=e500]:
|
||||||
|
- img [ref=e502]
|
||||||
|
- img [ref=e505]
|
||||||
|
- link [ref=e508] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e510]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e511]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e512]: Aneta W.
|
||||||
|
- group [ref=e513]:
|
||||||
|
- generic [ref=e515]:
|
||||||
|
- generic [ref=e516]:
|
||||||
|
- img [ref=e519]:
|
||||||
|
- generic [ref=e520]:
|
||||||
|
- img [ref=e522]
|
||||||
|
- img [ref=e525]
|
||||||
|
- generic [ref=e527]:
|
||||||
|
- img [ref=e529]
|
||||||
|
- img [ref=e532]
|
||||||
|
- generic [ref=e534]:
|
||||||
|
- img [ref=e536]
|
||||||
|
- img [ref=e539]
|
||||||
|
- generic [ref=e541]:
|
||||||
|
- img [ref=e543]
|
||||||
|
- img [ref=e546]
|
||||||
|
- generic [ref=e548]:
|
||||||
|
- img [ref=e550]
|
||||||
|
- img [ref=e553]
|
||||||
|
- link [ref=e556] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e558]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e559]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e560]: Aneta W.
|
||||||
|
- group [ref=e561]:
|
||||||
|
- generic [ref=e563]:
|
||||||
|
- generic [ref=e564]:
|
||||||
|
- img [ref=e567]:
|
||||||
|
- generic [ref=e568]:
|
||||||
|
- img [ref=e570]
|
||||||
|
- img [ref=e573]
|
||||||
|
- generic [ref=e575]:
|
||||||
|
- img [ref=e577]
|
||||||
|
- img [ref=e580]
|
||||||
|
- generic [ref=e582]:
|
||||||
|
- img [ref=e584]
|
||||||
|
- img [ref=e587]
|
||||||
|
- generic [ref=e589]:
|
||||||
|
- img [ref=e591]
|
||||||
|
- img [ref=e594]
|
||||||
|
- generic [ref=e596]:
|
||||||
|
- img [ref=e598]
|
||||||
|
- img [ref=e601]
|
||||||
|
- link [ref=e604] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e606]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e607]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e608]: Aneta W.
|
||||||
|
- group "1 / 4" [ref=e609]:
|
||||||
|
- generic [ref=e611]:
|
||||||
|
- generic [ref=e612]:
|
||||||
|
- img "Ocena 5 z 5" [ref=e615]:
|
||||||
|
- generic [ref=e616]:
|
||||||
|
- img [ref=e618]
|
||||||
|
- img [ref=e621]
|
||||||
|
- generic [ref=e623]:
|
||||||
|
- img [ref=e625]
|
||||||
|
- img [ref=e628]
|
||||||
|
- generic [ref=e630]:
|
||||||
|
- img [ref=e632]
|
||||||
|
- img [ref=e635]
|
||||||
|
- generic [ref=e637]:
|
||||||
|
- img [ref=e639]
|
||||||
|
- img [ref=e642]
|
||||||
|
- generic [ref=e644]:
|
||||||
|
- img [ref=e646]
|
||||||
|
- img [ref=e649]
|
||||||
|
- link [ref=e652] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e654]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e655]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e656]: Aneta W.
|
||||||
|
- group "2 / 4" [ref=e657]:
|
||||||
|
- generic [ref=e659]:
|
||||||
|
- generic [ref=e660]:
|
||||||
|
- img "Ocena 5 z 5" [ref=e663]:
|
||||||
|
- generic [ref=e664]:
|
||||||
|
- img [ref=e666]
|
||||||
|
- img [ref=e669]
|
||||||
|
- generic [ref=e671]:
|
||||||
|
- img [ref=e673]
|
||||||
|
- img [ref=e676]
|
||||||
|
- generic [ref=e678]:
|
||||||
|
- img [ref=e680]
|
||||||
|
- img [ref=e683]
|
||||||
|
- generic [ref=e685]:
|
||||||
|
- img [ref=e687]
|
||||||
|
- img [ref=e690]
|
||||||
|
- generic [ref=e692]:
|
||||||
|
- img [ref=e694]
|
||||||
|
- img [ref=e697]
|
||||||
|
- link [ref=e700] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e702]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e703]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e704]: Aneta W.
|
||||||
|
- group "3 / 4" [ref=e705]:
|
||||||
|
- generic [ref=e707]:
|
||||||
|
- generic [ref=e708]:
|
||||||
|
- img "Ocena 5 z 5" [ref=e711]:
|
||||||
|
- generic [ref=e712]:
|
||||||
|
- img [ref=e714]
|
||||||
|
- img [ref=e717]
|
||||||
|
- generic [ref=e719]:
|
||||||
|
- img [ref=e721]
|
||||||
|
- img [ref=e724]
|
||||||
|
- generic [ref=e726]:
|
||||||
|
- img [ref=e728]
|
||||||
|
- img [ref=e731]
|
||||||
|
- generic [ref=e733]:
|
||||||
|
- img [ref=e735]
|
||||||
|
- img [ref=e738]
|
||||||
|
- generic [ref=e740]:
|
||||||
|
- img [ref=e742]
|
||||||
|
- img [ref=e745]
|
||||||
|
- link [ref=e748] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e750]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e751]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e752]: Aneta W.
|
||||||
|
- group [ref=e753]:
|
||||||
|
- generic [ref=e755]:
|
||||||
|
- generic [ref=e756]:
|
||||||
|
- img [ref=e759]:
|
||||||
|
- generic [ref=e760]:
|
||||||
|
- img [ref=e762]
|
||||||
|
- img [ref=e765]
|
||||||
|
- generic [ref=e767]:
|
||||||
|
- img [ref=e769]
|
||||||
|
- img [ref=e772]
|
||||||
|
- generic [ref=e774]:
|
||||||
|
- img [ref=e776]
|
||||||
|
- img [ref=e779]
|
||||||
|
- generic [ref=e781]:
|
||||||
|
- img [ref=e783]
|
||||||
|
- img [ref=e786]
|
||||||
|
- generic [ref=e788]:
|
||||||
|
- img [ref=e790]
|
||||||
|
- img [ref=e793]
|
||||||
|
- link [ref=e796] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e798]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e799]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e800]: Aneta W.
|
||||||
|
- group [ref=e801]:
|
||||||
|
- generic [ref=e803]:
|
||||||
|
- generic [ref=e804]:
|
||||||
|
- img [ref=e807]:
|
||||||
|
- generic [ref=e808]:
|
||||||
|
- img [ref=e810]
|
||||||
|
- img [ref=e813]
|
||||||
|
- generic [ref=e815]:
|
||||||
|
- img [ref=e817]
|
||||||
|
- img [ref=e820]
|
||||||
|
- generic [ref=e822]:
|
||||||
|
- img [ref=e824]
|
||||||
|
- img [ref=e827]
|
||||||
|
- generic [ref=e829]:
|
||||||
|
- img [ref=e831]
|
||||||
|
- img [ref=e834]
|
||||||
|
- generic [ref=e836]:
|
||||||
|
- img [ref=e838]
|
||||||
|
- img [ref=e841]
|
||||||
|
- link [ref=e844] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e846]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e847]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e848]: Aneta W.
|
||||||
|
- group [ref=e849]:
|
||||||
|
- generic [ref=e851]:
|
||||||
|
- generic [ref=e852]:
|
||||||
|
- img [ref=e855]:
|
||||||
|
- generic [ref=e856]:
|
||||||
|
- img [ref=e858]
|
||||||
|
- img [ref=e861]
|
||||||
|
- generic [ref=e863]:
|
||||||
|
- img [ref=e865]
|
||||||
|
- img [ref=e868]
|
||||||
|
- generic [ref=e870]:
|
||||||
|
- img [ref=e872]
|
||||||
|
- img [ref=e875]
|
||||||
|
- generic [ref=e877]:
|
||||||
|
- img [ref=e879]
|
||||||
|
- img [ref=e882]
|
||||||
|
- generic [ref=e884]:
|
||||||
|
- img [ref=e886]
|
||||||
|
- img [ref=e889]
|
||||||
|
- link [ref=e892] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e894]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e895]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e896]: Aneta W.
|
||||||
|
- group [ref=e897]:
|
||||||
|
- generic [ref=e899]:
|
||||||
|
- generic [ref=e900]:
|
||||||
|
- img [ref=e903]:
|
||||||
|
- generic [ref=e904]:
|
||||||
|
- img [ref=e906]
|
||||||
|
- img [ref=e909]
|
||||||
|
- generic [ref=e911]:
|
||||||
|
- img [ref=e913]
|
||||||
|
- img [ref=e916]
|
||||||
|
- generic [ref=e918]:
|
||||||
|
- img [ref=e920]
|
||||||
|
- img [ref=e923]
|
||||||
|
- generic [ref=e925]:
|
||||||
|
- img [ref=e927]
|
||||||
|
- img [ref=e930]
|
||||||
|
- generic [ref=e932]:
|
||||||
|
- img [ref=e934]
|
||||||
|
- img [ref=e937]
|
||||||
|
- link [ref=e940] [cursor=pointer]:
|
||||||
|
- /url: https://carei.pagedev.pl
|
||||||
|
- paragraph [ref=e942]:
|
||||||
|
- text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
|
||||||
|
- strong [ref=e943]: Id eget felis enim
|
||||||
|
- text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
|
||||||
|
- generic [ref=e944]: Aneta W.
|
||||||
|
- contentinfo [ref=e945]:
|
||||||
|
- generic [ref=e948]:
|
||||||
|
- heading "Szukasz więcej informacji?" [level=4] [ref=e950]
|
||||||
|
- heading "Skontaktuj się z naszą obsługą." [level=3] [ref=e955]:
|
||||||
|
- text: Skontaktuj się
|
||||||
|
- text: z naszą obsługą.
|
||||||
|
- generic [ref=e959]:
|
||||||
|
- generic [ref=e961]:
|
||||||
|
- link "Assistance" [ref=e963] [cursor=pointer]:
|
||||||
|
- /url: tel:+48572663614
|
||||||
|
- img [ref=e964]
|
||||||
|
- generic [ref=e968]:
|
||||||
|
- heading "Assistance" [level=3] [ref=e969]:
|
||||||
|
- link "Assistance" [ref=e970] [cursor=pointer]:
|
||||||
|
- /url: tel:+48572663614
|
||||||
|
- paragraph [ref=e971]: +48 572 663 614
|
||||||
|
- generic [ref=e973]:
|
||||||
|
- link "Biuro" [ref=e975] [cursor=pointer]:
|
||||||
|
- /url: mailto:bok@carei.pl
|
||||||
|
- img [ref=e976]
|
||||||
|
- generic [ref=e982]:
|
||||||
|
- heading "Biuro" [level=3] [ref=e983]:
|
||||||
|
- link "Biuro" [ref=e984] [cursor=pointer]:
|
||||||
|
- /url: mailto:bok@carei.pl
|
||||||
|
- paragraph [ref=e985]: bok@carei.pl
|
||||||
|
- generic [ref=e996]:
|
||||||
|
- heading "Carei - Wypożyczalnia aut osobowych" [level=3] [ref=e998]
|
||||||
|
- generic [ref=e999]:
|
||||||
|
- paragraph [ref=e1001]:
|
||||||
|
- text: CAREI Sp. z o.o. Sp. k.
|
||||||
|
- text: ul. Solipska 1/U4,
|
||||||
|
- text: 02-482 Warszawa
|
||||||
|
- paragraph [ref=e1003]:
|
||||||
|
- text: "NIP: 527 249 90 39"
|
||||||
|
- text: "REGON: 140473129 KRS: 0000668452"
|
||||||
|
- generic [ref=e1011]:
|
||||||
|
- paragraph [ref=e1013]: Copyright © 2026 Carei
|
||||||
|
- paragraph [ref=e1015]: "Designed by: Kreatywny Brand"
|
||||||
|
- generic [ref=e1016]: laptop
|
||||||
25
.vscode/ftp-kr.sync.cache.json
vendored
25
.vscode/ftp-kr.sync.cache.json
vendored
@@ -31,37 +31,12 @@
|
|||||||
"lmtime": 0,
|
"lmtime": 0,
|
||||||
"modified": false
|
"modified": false
|
||||||
},
|
},
|
||||||
".playwright-mcp": {},
|
|
||||||
"readme.html": {
|
"readme.html": {
|
||||||
"type": "-",
|
"type": "-",
|
||||||
"size": 7425,
|
"size": 7425,
|
||||||
"lmtime": 0,
|
"lmtime": 0,
|
||||||
"modified": false
|
"modified": false
|
||||||
},
|
},
|
||||||
".serena": {
|
|
||||||
".gitignore": {
|
|
||||||
"type": "-",
|
|
||||||
"size": 28,
|
|
||||||
"lmtime": 1774382289791,
|
|
||||||
"modified": false
|
|
||||||
},
|
|
||||||
"memories": {},
|
|
||||||
"project.local.yml": {
|
|
||||||
"type": "-",
|
|
||||||
"size": 407,
|
|
||||||
"lmtime": 1774382289788,
|
|
||||||
"modified": false
|
|
||||||
},
|
|
||||||
"project.yml": {
|
|
||||||
"type": "-",
|
|
||||||
"size": 9594,
|
|
||||||
"lmtime": 1774382289785,
|
|
||||||
"modified": false
|
|
||||||
},
|
|
||||||
"cache": {
|
|
||||||
"php": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"softra-test.php": {
|
"softra-test.php": {
|
||||||
"type": "-",
|
"type": "-",
|
||||||
"size": 6081,
|
"size": 6081,
|
||||||
|
|||||||
BIN
carei-cities-current.png
Normal file
BIN
carei-cities-current.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
carei-cities-section.png
Normal file
BIN
carei-cities-section.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
BIN
carei-full-page.png
Normal file
BIN
carei-full-page.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
BIN
wp-admin/.DS_Store
vendored
BIN
wp-admin/.DS_Store
vendored
Binary file not shown.
BIN
wp-content/.DS_Store
vendored
BIN
wp-content/.DS_Store
vendored
Binary file not shown.
BIN
wp-content/languages/.DS_Store
vendored
BIN
wp-content/languages/.DS_Store
vendored
Binary file not shown.
BIN
wp-content/plugins/.DS_Store
vendored
BIN
wp-content/plugins/.DS_Store
vendored
Binary file not shown.
@@ -1403,3 +1403,164 @@ button.carei-reservation-trigger:hover {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════════════════════════════
|
||||||
|
Carei Map Widget
|
||||||
|
═══════════════════════════════════════════ */
|
||||||
|
|
||||||
|
.carei-map {
|
||||||
|
position: relative;
|
||||||
|
max-width: 520px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-map__svg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-map__pin {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: r 0.2s ease, fill 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-map__pin:hover,
|
||||||
|
.carei-map__pin--active {
|
||||||
|
r: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-map__tooltip {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 10;
|
||||||
|
transform: translate(-50%, -100%);
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-map__tooltip-content {
|
||||||
|
background: var(--carei-blue);
|
||||||
|
color: var(--carei-white);
|
||||||
|
font-family: var(--carei-font);
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.4;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-radius: var(--carei-radius);
|
||||||
|
white-space: pre-line;
|
||||||
|
min-width: 160px;
|
||||||
|
max-width: 260px;
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-map__tooltip-content::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border: 6px solid transparent;
|
||||||
|
border-top-color: var(--carei-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════════════════════════════
|
||||||
|
Carei Cities Widget
|
||||||
|
═══════════════════════════════════════════ */
|
||||||
|
|
||||||
|
.carei-cities {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px 0;
|
||||||
|
font-family: var(--carei-font);
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--carei-blue);
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-cities__item {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-cities__item::after {
|
||||||
|
content: '|';
|
||||||
|
padding: 0 14px;
|
||||||
|
opacity: 0.35;
|
||||||
|
font-weight: 300;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-cities__item:last-child::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.carei-cities {
|
||||||
|
font-size: 13px;
|
||||||
|
gap: 4px 0;
|
||||||
|
}
|
||||||
|
.carei-cities__item::after {
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════════════════════════════
|
||||||
|
Carei Branches Widget
|
||||||
|
═══════════════════════════════════════════ */
|
||||||
|
|
||||||
|
.carei-branches {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
font-family: var(--carei-font);
|
||||||
|
color: var(--carei-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-branches__item {
|
||||||
|
padding: 24px 16px;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-branches__name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carei-branches__street,
|
||||||
|
.carei-branches__zip-city {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.5;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.carei-branches {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.carei-branches {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
.carei-branches__item {
|
||||||
|
padding: 18px 12px;
|
||||||
|
}
|
||||||
|
.carei-branches__name {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.carei-branches__street,
|
||||||
|
.carei-branches__zip-city {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.carei-branches {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1265,6 +1265,110 @@
|
|||||||
initClearErrors();
|
initClearErrors();
|
||||||
initAbroad();
|
initAbroad();
|
||||||
initSubmit();
|
initSubmit();
|
||||||
|
initMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ═══════════════════════════════════════════
|
||||||
|
Carei Map — dynamic pins & tooltips
|
||||||
|
═══════════════════════════════════════════ */
|
||||||
|
|
||||||
|
function initMap() {
|
||||||
|
var mapEl = document.querySelector('.carei-map');
|
||||||
|
if (!mapEl) return;
|
||||||
|
|
||||||
|
var pins;
|
||||||
|
try {
|
||||||
|
pins = JSON.parse(mapEl.getAttribute('data-pins') || '[]');
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!pins.length) return;
|
||||||
|
|
||||||
|
var svg = mapEl.querySelector('.carei-map__svg');
|
||||||
|
var pinsGroup = svg.querySelector('.carei-map__pins');
|
||||||
|
var tooltip = mapEl.querySelector('.carei-map__tooltip');
|
||||||
|
var tooltipContent = mapEl.querySelector('.carei-map__tooltip-content');
|
||||||
|
if (!svg || !pinsGroup || !tooltip || !tooltipContent) return;
|
||||||
|
|
||||||
|
var activePin = null;
|
||||||
|
var SVG_NS = 'http://www.w3.org/2000/svg';
|
||||||
|
|
||||||
|
pins.forEach(function (pin) {
|
||||||
|
var circle = document.createElementNS(SVG_NS, 'circle');
|
||||||
|
circle.setAttribute('cx', pin.x);
|
||||||
|
circle.setAttribute('cy', pin.y);
|
||||||
|
circle.setAttribute('r', '6');
|
||||||
|
circle.setAttribute('fill', '#FF0000');
|
||||||
|
circle.setAttribute('class', 'carei-map__pin');
|
||||||
|
circle.setAttribute('data-city', pin.city);
|
||||||
|
circle.setAttribute('data-address', pin.address || '');
|
||||||
|
|
||||||
|
circle.addEventListener('mouseenter', function () {
|
||||||
|
showTooltip(pin, circle);
|
||||||
|
});
|
||||||
|
circle.addEventListener('mouseleave', function () {
|
||||||
|
if (activePin !== circle) {
|
||||||
|
hideTooltip();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
circle.addEventListener('click', function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (activePin === circle) {
|
||||||
|
activePin = null;
|
||||||
|
circle.classList.remove('carei-map__pin--active');
|
||||||
|
hideTooltip();
|
||||||
|
} else {
|
||||||
|
if (activePin) activePin.classList.remove('carei-map__pin--active');
|
||||||
|
activePin = circle;
|
||||||
|
circle.classList.add('carei-map__pin--active');
|
||||||
|
showTooltip(pin, circle);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pinsGroup.appendChild(circle);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Click outside closes tooltip
|
||||||
|
document.addEventListener('click', function () {
|
||||||
|
if (activePin) {
|
||||||
|
activePin.classList.remove('carei-map__pin--active');
|
||||||
|
activePin = null;
|
||||||
|
hideTooltip();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function showTooltip(pin, circle) {
|
||||||
|
// Build tooltip text: address lines + bold city
|
||||||
|
var addr = pin.address || '';
|
||||||
|
var lines = addr ? addr.replace(/\\n/g, '\n') : pin.city;
|
||||||
|
tooltipContent.textContent = '';
|
||||||
|
|
||||||
|
// If address has postal code, format nicely
|
||||||
|
if (addr) {
|
||||||
|
tooltipContent.innerHTML = addr.replace(/\n/g, '<br>');
|
||||||
|
} else {
|
||||||
|
tooltipContent.textContent = pin.city;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position tooltip relative to map container
|
||||||
|
var svgRect = svg.getBoundingClientRect();
|
||||||
|
var mapRect = mapEl.getBoundingClientRect();
|
||||||
|
var svgWidth = svg.viewBox.baseVal.width || 600;
|
||||||
|
var svgHeight = svg.viewBox.baseVal.height || 570;
|
||||||
|
var scaleX = svgRect.width / svgWidth;
|
||||||
|
var scaleY = svgRect.height / svgHeight;
|
||||||
|
|
||||||
|
var left = (svgRect.left - mapRect.left) + pin.x * scaleX;
|
||||||
|
var top = (svgRect.top - mapRect.top) + pin.y * scaleY;
|
||||||
|
|
||||||
|
tooltip.style.display = 'block';
|
||||||
|
tooltip.style.left = left + 'px';
|
||||||
|
tooltip.style.top = top + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideTooltip() {
|
||||||
|
tooltip.style.display = 'none';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
|
|||||||
@@ -88,6 +88,15 @@ add_action( 'elementor/widgets/register', function ( $widgets_manager ) {
|
|||||||
|
|
||||||
require_once CAREI_RESERVATION_PATH . 'includes/class-search-widget.php';
|
require_once CAREI_RESERVATION_PATH . 'includes/class-search-widget.php';
|
||||||
$widgets_manager->register( new Carei_Search_Widget() );
|
$widgets_manager->register( new Carei_Search_Widget() );
|
||||||
|
|
||||||
|
require_once CAREI_RESERVATION_PATH . 'includes/class-map-widget.php';
|
||||||
|
$widgets_manager->register( new Carei_Map_Widget() );
|
||||||
|
|
||||||
|
require_once CAREI_RESERVATION_PATH . 'includes/class-cities-widget.php';
|
||||||
|
$widgets_manager->register( new Carei_Cities_Widget() );
|
||||||
|
|
||||||
|
require_once CAREI_RESERVATION_PATH . 'includes/class-branches-widget.php';
|
||||||
|
$widgets_manager->register( new Carei_Branches_Widget() );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elementor Widget: Carei Branches — grid oddziałów z adresami.
|
||||||
|
*/
|
||||||
|
class Carei_Branches_Widget extends \Elementor\Widget_Base {
|
||||||
|
|
||||||
|
const NAME_FIXES = array(
|
||||||
|
'BYDGOSZC' => 'BYDGOSZCZ',
|
||||||
|
'GORZÓW WIE' => 'GORZÓW WIELKOPOLSKI',
|
||||||
|
'RZSZÓW' => 'RZESZÓW',
|
||||||
|
'SK-KAM' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function get_name() {
|
||||||
|
return 'carei-branches';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_title() {
|
||||||
|
return 'Carei Branches';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_icon() {
|
||||||
|
return 'eicon-posts-grid';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_categories() {
|
||||||
|
return array( 'general' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_style_depends() {
|
||||||
|
return array( 'carei-reservation-css' );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function register_controls() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean branch name and return base city.
|
||||||
|
*/
|
||||||
|
private static function clean_name( $raw ) {
|
||||||
|
$name = trim( $raw );
|
||||||
|
$name = preg_replace( '/\s+[DL]$/u', '', $name );
|
||||||
|
if ( isset( self::NAME_FIXES[ $name ] ) ) {
|
||||||
|
$name = self::NAME_FIXES[ $name ];
|
||||||
|
}
|
||||||
|
if ( empty( $name ) || preg_match( '/^[A-Z]{2,4}-[A-Z]{2,4}$/u', $name ) ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get unique branches with addresses.
|
||||||
|
*/
|
||||||
|
private function get_branches_data() {
|
||||||
|
$api = Carei_Softra_API::get_instance();
|
||||||
|
if ( null === $api ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$branches = $api->get_branches_cached();
|
||||||
|
if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
$seen = array();
|
||||||
|
|
||||||
|
foreach ( $branches as $b ) {
|
||||||
|
$raw_name = isset( $b['name'] ) ? $b['name'] : '';
|
||||||
|
$city = self::clean_name( $raw_name );
|
||||||
|
if ( empty( $city ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$norm = mb_strtolower( $city, 'UTF-8' );
|
||||||
|
if ( isset( $seen[ $norm ] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$seen[ $norm ] = true;
|
||||||
|
|
||||||
|
$display_city = mb_convert_case( $city, MB_CASE_TITLE, 'UTF-8' );
|
||||||
|
$street = isset( $b['street'] ) ? trim( $b['street'] ) : '';
|
||||||
|
$zip = isset( $b['zipCode'] ) ? trim( (string) $b['zipCode'] ) : '';
|
||||||
|
$api_city = isset( $b['city'] ) ? trim( $b['city'] ) : '';
|
||||||
|
$api_city_tc = mb_convert_case( $api_city, MB_CASE_TITLE, 'UTF-8' );
|
||||||
|
|
||||||
|
// Format street
|
||||||
|
if ( $street ) {
|
||||||
|
$street_lower = mb_strtolower( $street, 'UTF-8' );
|
||||||
|
$has_prefix = preg_match( '/^(ul\.|al\.|pl\.|os\.)/u', $street_lower );
|
||||||
|
$street = $has_prefix ? $street : 'ul. ' . $street;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[] = array(
|
||||||
|
'name' => 'Oddział ' . $display_city,
|
||||||
|
'street' => $street,
|
||||||
|
'zipCity' => trim( $zip . ' ' . $api_city_tc ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
usort( $result, function ( $a, $b ) {
|
||||||
|
return strcmp( $a['name'], $b['name'] );
|
||||||
|
} );
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function render() {
|
||||||
|
$branches = $this->get_branches_data();
|
||||||
|
if ( empty( $branches ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="carei-branches">
|
||||||
|
<?php foreach ( $branches as $branch ) : ?>
|
||||||
|
<div class="carei-branches__item">
|
||||||
|
<div class="carei-branches__name"><?php echo esc_html( $branch['name'] ); ?></div>
|
||||||
|
<?php if ( $branch['street'] ) : ?>
|
||||||
|
<div class="carei-branches__street"><?php echo esc_html( $branch['street'] ); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if ( $branch['zipCity'] ) : ?>
|
||||||
|
<div class="carei-branches__zip-city"><?php echo esc_html( $branch['zipCity'] ); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elementor Widget: Carei Cities — siatka miast oddziałów.
|
||||||
|
*/
|
||||||
|
class Carei_Cities_Widget extends \Elementor\Widget_Base {
|
||||||
|
|
||||||
|
public function get_name() {
|
||||||
|
return 'carei-cities';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_title() {
|
||||||
|
return 'Carei Cities';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_icon() {
|
||||||
|
return 'eicon-bullet-list';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_categories() {
|
||||||
|
return array( 'general' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_style_depends() {
|
||||||
|
return array( 'carei-reservation-css' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_script_depends() {
|
||||||
|
return array( 'carei-reservation-js' );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function register_controls() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncated / misspelled names from Softra API → correct full city names.
|
||||||
|
*/
|
||||||
|
const NAME_FIXES = array(
|
||||||
|
'BYDGOSZC' => 'BYDGOSZCZ',
|
||||||
|
'GORZÓW WIE' => 'GORZÓW WIELKOPOLSKI',
|
||||||
|
'RZSZÓW' => 'RZESZÓW',
|
||||||
|
'SK-KAM' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean branch name: handle D(Dworzec)/L suffixes, fix truncated names, title-case.
|
||||||
|
* API returns names like "GDAŃSK D", "GDAŃSK L", "BYDGOSZC D", "SK-KAM", "GORZÓW WIE".
|
||||||
|
* D-suffix branches without a base variant → "Oddział [City]".
|
||||||
|
*/
|
||||||
|
private static function clean_city_name( $raw ) {
|
||||||
|
$name = trim( $raw );
|
||||||
|
// Detect D (Dworzec) suffix before stripping
|
||||||
|
$is_dworzec = (bool) preg_match( '/\s+D$/u', $name );
|
||||||
|
// Strip trailing single-letter suffixes (D=Dworzec, L=Lotnisko/inne)
|
||||||
|
$name = preg_replace( '/\s+[DL]$/u', '', $name );
|
||||||
|
// Fix known truncated/misspelled names
|
||||||
|
if ( isset( self::NAME_FIXES[ $name ] ) ) {
|
||||||
|
$name = self::NAME_FIXES[ $name ];
|
||||||
|
}
|
||||||
|
// Skip empty or non-city codes
|
||||||
|
if ( empty( $name ) || preg_match( '/^[A-Z]{2,4}-[A-Z]{2,4}$/u', $name ) ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
// Title-case: "GDAŃSK" → "Gdańsk"
|
||||||
|
$name = mb_convert_case( $name, MB_CASE_TITLE, 'UTF-8' );
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract unique city names from branches.
|
||||||
|
*/
|
||||||
|
private function get_city_names() {
|
||||||
|
$api = Carei_Softra_API::get_instance();
|
||||||
|
if ( null === $api ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$branches = $api->get_branches_cached();
|
||||||
|
if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$cities = array();
|
||||||
|
$seen = array();
|
||||||
|
|
||||||
|
foreach ( $branches as $b ) {
|
||||||
|
$name = isset( $b['name'] ) ? $b['name'] : '';
|
||||||
|
$city = self::clean_city_name( $name );
|
||||||
|
if ( empty( $city ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$norm = mb_strtolower( $city, 'UTF-8' );
|
||||||
|
if ( isset( $seen[ $norm ] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$seen[ $norm ] = true;
|
||||||
|
$cities[] = $city;
|
||||||
|
}
|
||||||
|
|
||||||
|
sort( $cities );
|
||||||
|
return $cities;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function render() {
|
||||||
|
$cities = $this->get_city_names();
|
||||||
|
if ( empty( $cities ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="carei-cities">
|
||||||
|
<?php foreach ( $cities as $i => $city ) : ?>
|
||||||
|
<span class="carei-cities__item"><?php echo esc_html( $city ); ?></span>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -117,6 +117,13 @@ class Carei_REST_Proxy {
|
|||||||
),
|
),
|
||||||
) );
|
) );
|
||||||
|
|
||||||
|
// GET /branches-full (cached, full branch objects with descriptions)
|
||||||
|
register_rest_route( self::NAMESPACE, '/branches-full', array(
|
||||||
|
'methods' => 'GET',
|
||||||
|
'callback' => array( $this, 'get_branches_full' ),
|
||||||
|
'permission_callback' => '__return_true',
|
||||||
|
) );
|
||||||
|
|
||||||
// GET /agreements
|
// GET /agreements
|
||||||
register_rest_route( self::NAMESPACE, '/agreements', array(
|
register_rest_route( self::NAMESPACE, '/agreements', array(
|
||||||
'methods' => 'GET',
|
'methods' => 'GET',
|
||||||
@@ -276,6 +283,14 @@ class Carei_REST_Proxy {
|
|||||||
) );
|
) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function get_branches_full( WP_REST_Request $request ) {
|
||||||
|
$api = $this->api();
|
||||||
|
if ( is_wp_error( $api ) ) {
|
||||||
|
return $api;
|
||||||
|
}
|
||||||
|
return $this->respond( $api->get_branches_cached() );
|
||||||
|
}
|
||||||
|
|
||||||
public function get_agreements( WP_REST_Request $request ) {
|
public function get_agreements( WP_REST_Request $request ) {
|
||||||
$api = $this->api();
|
$api = $this->api();
|
||||||
if ( is_wp_error( $api ) ) {
|
if ( is_wp_error( $api ) ) {
|
||||||
|
|||||||
@@ -153,6 +153,26 @@ class Carei_Softra_API {
|
|||||||
return $this->request( 'GET', '/branch/list' );
|
return $this->request( 'GET', '/branch/list' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get branches with 60-min transient cache.
|
||||||
|
*/
|
||||||
|
public function get_branches_cached() {
|
||||||
|
$cache_key = 'carei_branches_list';
|
||||||
|
$cached = get_transient( $cache_key );
|
||||||
|
if ( false !== $cached ) {
|
||||||
|
return $cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
$branches = $this->get_branches();
|
||||||
|
if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
|
||||||
|
return is_wp_error( $branches ) ? $branches : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
set_transient( $cache_key, $branches, HOUR_IN_SECONDS );
|
||||||
|
|
||||||
|
return $branches;
|
||||||
|
}
|
||||||
|
|
||||||
public function get_all_car_classes() {
|
public function get_all_car_classes() {
|
||||||
return $this->request( 'GET', '/car/class/listAll' );
|
return $this->request( 'GET', '/car/class/listAll' );
|
||||||
}
|
}
|
||||||
@@ -170,7 +190,7 @@ class Carei_Softra_API {
|
|||||||
return $cached;
|
return $cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
$branches = $this->get_branches();
|
$branches = $this->get_branches_cached();
|
||||||
if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
|
if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
|
||||||
return is_wp_error( $branches ) ? $branches : array();
|
return is_wp_error( $branches ) ? $branches : array();
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
wp-content/themes/.DS_Store
vendored
BIN
wp-content/themes/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/.DS_Store
vendored
BIN
wp-includes/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/Requests/.DS_Store
vendored
BIN
wp-includes/Requests/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/SimplePie/.DS_Store
vendored
BIN
wp-includes/SimplePie/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/blocks/.DS_Store
vendored
BIN
wp-includes/blocks/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/images/.DS_Store
vendored
BIN
wp-includes/images/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/js/.DS_Store
vendored
BIN
wp-includes/js/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/rest-api/.DS_Store
vendored
BIN
wp-includes/rest-api/.DS_Store
vendored
Binary file not shown.
BIN
wp-includes/sodium_compat/.DS_Store
vendored
BIN
wp-includes/sodium_compat/.DS_Store
vendored
Binary file not shown.
Reference in New Issue
Block a user