Files
carei.pagedev.pl/.paul/phases/13-protection-packages/13-01-PLAN.md
Jacek Pyziak 6f6c1fcf17 fix(14-mobile-modal-fix): Modal rezerwacji działa na mobile/tablet
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>
2026-04-10 00:05:53 +02:00

9.1 KiB
Raw Blame History

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
wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
wp-content/plugins/carei-reservation/includes/class-elementor-widget.php
false off
## Goal Wyświetlanie pakietów ochronnych SOFT i PREMIUM jako dedykowanych kafelków z ceną obliczaną dynamicznie na podstawie liczby dni wynajmu (3 progi cenowe: minimalna 1-3 dni, za dobę 4-15 dni, maksymalna 16+ dni).

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
## Project Context @.paul/PROJECT.md @.paul/ROADMAP.md @.paul/STATE.md

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
Before declaring plan complete: - [ ] Protection packages display with correct tiered pricing for all 3 duration ranges - [ ] Selection is mutually exclusive with deselect capability - [ ] Prices recalculate on date change - [ ] Selected package included in booking submission priceItems - [ ] Summary overlay shows selected package with price - [ ] No regressions in existing extras or abroad sections - [ ] Responsive layout works on mobile - [ ] All acceptance criteria met

<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>
After completion, create `.paul/phases/13-protection-packages/13-01-SUMMARY.md`