Sekcja Elementor zawierająca modal miała elementor-hidden-mobile/tablet, co powodowało display:none na rodzicu. Modal position:fixed wewnątrz ukrytego elementu miał zerowe wymiary. Fix: przeniesienie overlay do document.body w initRefs(). Plan Phase 13 (pakiety ochronne) utworzony, BLOCKED — czeka na klienta. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9.1 KiB
9.1 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, delegation
| phase | plan | type | wave | depends_on | files_modified | autonomous | delegation | |||
|---|---|---|---|---|---|---|---|---|---|---|
| 13-protection-packages | 01 | execute | 1 |
|
false | off |
Purpose
Klient chce prezentować pakiety ochronne w zrozumiały sposób — zamiast generycznego "od X do Y zł" użytkownik widzi jedną konkretną cenę dopasowaną do długości jego rezerwacji. Wybór pakietu jest opcjonalny i wzajemnie wykluczający (SOFT lub PREMIUM, nie oba).
Output
- Sekcja "Pakiety ochronne" z dwoma kafelkami (SOFT, PREMIUM) z dynamiczną ceną
- Cena przeliczana automatycznie przy zmianie dat
- Wybrany pakiet uwzględniany w podsumowaniu i booking submission
Source Files
@wp-content/plugins/carei-reservation/assets/js/carei-reservation.js @wp-content/plugins/carei-reservation/assets/css/carei-reservation.css @wp-content/plugins/carei-reservation/includes/class-elementor-widget.php
No SPECIAL-FLOWS.md — skills section omitted.<acceptance_criteria>
AC-1: Tiered price calculation
Given insurance items from API with minPrice, price (per day), and maxPrice
When the user has selected rental dates spanning N days
Then each protection package shows:
- minPrice (flat) when N <= 3
- price × N when 4 <= N <= 15
- maxPrice (flat) when N > 15
AC-2: Mutually exclusive selection
Given two protection package cards (SOFT, PREMIUM) are displayed
When the user clicks on one package
Then the other package is deselected (radio behavior)
And the user can also deselect to choose no package
AC-3: Dynamic price update on date change
Given protection packages are displayed with calculated prices
When the user changes pickup or return date
Then the prices on both cards recalculate immediately
And the correct tier (flat/per-day/flat) is applied based on new duration
AC-4: Package included in booking submission
Given the user has selected a protection package (SOFT or PREMIUM)
When the booking is submitted
Then the selected package is included in priceItems with correct calculated price
And the package appears in the summary overlay with its name and total price
</acceptance_criteria>
Task 1: Render protection packages as radio-style cards with tiered pricing wp-content/plugins/carei-reservation/assets/js/carei-reservation.js, wp-content/plugins/carei-reservation/assets/css/carei-reservation.css 1. In the pricelist loading section (~line 432-458), after filtering insuranceItems: - Create a new function `buildProtectionCard(item, days)` that: - Calculates price based on days: `days <= 3` → item.minPrice, `days >= 4 && days <= 15` → item.price * days, `days > 15` → item.maxPrice - Renders a card with radio behavior (use checkbox with JS toggle for deselect capability) - Shows price label: "180 zł" (flat) or "60 zł/doba = 420 zł" (per-day with total) - Card design: prominent tile with package name, price, and a brief description if available from API - Replace current `insuranceContainer` rendering: instead of `buildExtraCard` for each item, use `buildProtectionCard` - Use `name="protection"` with type="radio" BUT wrap in a click handler that allows deselection (click selected = deselect)2. Add function `updateProtectionPrices()` that:
- Reads current days count from the date fields (reuse existing daysCount logic)
- Recalculates prices for both cards
- Updates the displayed price labels
- Call this function when dates change (hook into existing date change handler)
3. CSS for protection cards in carei-reservation.css:
- Two cards side by side (flex row, gap)
- Active/selected state with border highlight (#2F2482)
- Responsive: stack vertically on mobile
- Style consistent with existing extra cards but visually distinct (larger, more prominent)
Avoid: Changing the existing `buildExtraCard` function — it still serves regular extras.
Avoid: Hardcoding prices — all pricing comes from API item fields (minPrice, price, maxPrice).
- Open reservation form, select dates for 2 days → packages show flat minPrice
- Change dates to 7 days → packages show per-day price × 7
- Change dates to 20 days → packages show flat maxPrice
- Click SOFT → SOFT selected, click PREMIUM → SOFT deselected + PREMIUM selected
- Click selected card again → deselected (no package chosen)
AC-1, AC-2, AC-3 satisfied: Protection packages render with correct tiered pricing, mutually exclusive selection, and dynamic price updates
Task 2: Wire protection package into booking submission and summary
wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
1. In the booking submission logic (where extras[] checkboxes are collected):
- Add collection of selected protection package: query `input[name="protection"]:checked`
- Build priceItem with: id, name, unit='szt.', amount=1, priceBeforeDiscount = calculated total price, discount=0, priceAfterDiscount = same
- Append to the priceItems array sent to API
2. In the summary overlay rendering:
- Add a row for the selected protection package showing package name and total price
- If no package selected, don't show a row
3. Ensure the protection price is included in the total calculation in the summary.
Avoid: Changing the admin panel storage logic — protection items go through as regular priceItems, same as extras.
Avoid: Duplicating protection item if it also appears in extras — ensure the filtering separates them cleanly.
- Select SOFT package + submit → summary shows "Pakiet ochrony Soft — XXX zł"
- Submit without package → no protection row in summary
- Full booking flow completes with package included in API call
AC-4 satisfied: Selected package included in booking submission and visible in summary
Protection package cards with tiered pricing, radio selection, date-driven recalculation, and booking integration
1. Otwórz stronę carei.pagedev.pl i kliknij rezerwację
2. Wybierz segment, lokalizację i daty na 2 dni → sprawdź cenę pakietów (powinna być cena minimalna)
3. Zmień daty na 7 dni → cena powinna się przeliczyć (cena za dobę × 7)
4. Zmień daty na 20 dni → cena powinna być stała (maksymalna)
5. Kliknij SOFT → zaznaczony, kliknij PREMIUM → SOFT odznaczony, PREMIUM zaznaczony
6. Kliknij zaznaczony ponownie → odznaczony (brak pakietu)
7. Wybierz pakiet i przejdź do podsumowania → pakiet widoczny z ceną
8. Sprawdź na mobile → karty jedna pod drugą
Type "approved" to continue, or describe issues to fix
DO NOT CHANGE
- class-rest-proxy.php (API proxy unchanged — data comes from existing pricelist endpoint)
- class-admin-panel.php (admin storage — protection items stored same as extras via priceItems)
- class-softra-api.php (Softra API client — no changes needed)
- Abroad section logic (wyjazd zagraniczny)
- Hero search form widget
SCOPE LIMITS
- No new API endpoints — protection packages come from existing pricelist/additionalItems
- No backend pricing logic — all tier calculation is client-side based on API item fields
- No new admin UI for managing packages — data managed in Softra system
- Description/zakres usług text comes from API item.description — no hardcoded descriptions
<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- Protection packages display correctly for all 3 pricing tiers
- Booking flow works end-to-end with selected package </success_criteria>