--- phase: 09-finalizacja plan: 01 subsystem: ui tags: [fullcalendar, css, elementor, frontend, ux] requires: - phase: 04-frontend-kalendarz provides: FullCalendar widget Elementor + REST availability endpoint - phase: 03-system-dostepnosci provides: wp_yacht_availability table z polem booking_id (bazą detekcji krawędzi) provides: - Wizualne oznaczenie pierwszego/ostatniego dnia rezerwacji jako pół-zajętego (gradient 45°) - Detekcja krawędzi rezerwacji po stronie klienta (start/end/mid/single) na bazie sąsiedztwa booking_id+status - Paleta widgetu Elementor dopasowana do brandu strony (granat #0e2036, czerwień #bc1834) - CSS custom properties --yacht-available-bg / --yacht-booked-bg umożliwiające reużycie kolorów w gradientach i legendzie affects: - 09-02-settings (settings page może w przyszłości eksponować godziny check-in/out) - przyszłe plany dotyczące UX kalendarza tech-stack: added: [CSS custom properties, FullCalendar --fc-border-color override] patterns: - "Edge detection przez sąsiedztwo: porównanie current vs (date-1, date+1) po booking_id i status" - "Linear-gradient 50/50 z hard stop dla skosu 45° zamiast SVG/canvas" key-files: created: - test-add-booking.php (helper testowy w roocie projektu — DO USUNIĘCIA po teście) modified: - wp-content/plugins/yacht-booking-system/frontend/assets/js/calendar.js - wp-content/plugins/yacht-booking-system/frontend/assets/css/calendar.scss - wp-content/plugins/yacht-booking-system/frontend/assets/css/calendar.css - wp-content/plugins/yacht-booking-system/frontend/class-calendar-widget.php key-decisions: - "Skos 45° z linear-gradient zamiast SVG/clip-path — prostszy CSS, działa we wszystkich nowoczesnych przeglądarkach" - "Single-day blokada renderowana jako pełen booked (nie klepsydra) — uproszczenie wizualne" - "Walidacja overlap (selectAllow/select) niezmieniona — polityka check-in/check-out poza zakresem" - "Defaulty kolorów dopasowane do faktycznej palety strony (granat #0e2036, czerwień #bc1834) zamiast generycznych #0a2a5e/#d63638 z planu" - "Cyfry dni #021526 z !important — przebicie globalnej reguły body a:not([href])" patterns-established: - "CSS custom properties ustawiane z JS na wrapperze pozwalają na reuse koloru w gradientach + legendzie bez duplikacji" - "Krawędzie segmentu = porównanie 3 atrybutów (status, booking_id, sąsiad) — działa zarówno dla bookings jak i blocked z GCal/iCal" duration: ~90min started: 2026-05-06T08:00:00+02:00 completed: 2026-05-06T09:30:00+02:00 --- # Phase 9 Plan 01: UX/UI polish kalendarza — Summary **Pierwszy/ostatni dzień rezerwacji renderuje się jako pół-zajęty trójkąt (skos 45°) z paletą strony (granat + czerwień); ramki dni i nagłówki kolumn ciemne, cyfry granatowe.** ## Performance | Metric | Value | |--------|-------| | Duration | ~90 min | | Started | 2026-05-06T08:00:00+02:00 | | Completed | 2026-05-06T09:30:00+02:00 | | Tasks | 3 of 3 (2 auto + 1 checkpoint) | | Files modified | 4 (plugin) + 1 utworzony (test helper) | ## Acceptance Criteria Results | Criterion | Status | Notes | |-----------|--------|-------| | AC-1: Skos na pierwszym dniu rezerwacji | Pass | Po iteracji finalna orientacja: gradient 135° → top-left = wolny, bottom-right = zajęty | | AC-2: Skos na ostatnim dniu rezerwacji | Pass | Gradient 135° → top-left = zajęty, bottom-right = wolny. Razem ze start tworzy parallelogram przez wiersz | | AC-3: Detekcja ciągłości — różne booking_id | Pass | `sameSegment(a,b)` porównuje status + booking_id; różne `booking_id` przerywają segment | | AC-4: Skos także dla blokad GCal/iCal | Pass | Klasy `yacht-day-blocked-start/end` reagują na ten sam gradient — jeden zestaw reguł | | AC-5: Nowa paleta domyślna widgetu | Pass | primary #0e2036, available #f5f9ff, booked #bc1834 (zamiast generycznych z planu — wzięto faktyczną paletę z SCSS strony) | | AC-6: Walidacja wyboru dat niezmieniona | Pass | `selectAllow` i `select` callback bez zmian, overlap dalej blokuje | ## Accomplishments - Skos 45° pierwszego/ostatniego dnia rezerwacji (gradient 135° + 135°), spójny dla bookings i blokad GCal/iCal - Detekcja krawędzi po stronie klienta — bez zmian w REST API ani schemacie DB - Paleta widgetu dopasowana do brandu strony (granat + czerwień) z fallbackiem dla legacy zielony/czerwony - Ciemne ramki kalendarza przez `--fc-border-color` (oficjalna zmienna FullCalendar v6) + override dla 7 selektorów - Cyfry dni granatowe `#021526`, past `#6c757d` zamiast białych - Legenda rozszerzona o swatch „Dzień odbioru / zwrotu" z gradientem 135° - Helper `test-add-booking.php` z token-protected akcjami add/list/remove dla łatwego smoke testu ## Files Created/Modified | File | Change | Purpose | |------|--------|---------| | `wp-content/plugins/yacht-booking-system/frontend/assets/js/calendar.js` | Modified (+58/-3) | Edge detection w `events` callback; CSS custom properties na wrapperze; nowe defaulty `#f5f9ff`/`#bc1834` | | `wp-content/plugins/yacht-booking-system/frontend/assets/css/calendar.scss` | Modified (+61/-7) | Gradienty 135° dla start/end; ciemne ramki przez --fc-border-color + override; nagłówki kolumn granatowe; cyfry dni #021526 | | `wp-content/plugins/yacht-booking-system/frontend/assets/css/calendar.css` | Modified (~) | Skompilowane reguły zsynchronizowane z SCSS | | `wp-content/plugins/yacht-booking-system/frontend/class-calendar-widget.php` | Modified (+15/-7) | Defaulty kolorów Elementora; legenda rozszerzona o swatch gradientu | | `test-add-booking.php` | Created | Token-protected helper FTP do tworzenia/listowania/usuwania testowych rezerwacji | ## Decisions Made | Decision | Rationale | Impact | |----------|-----------|--------| | Skos przez `linear-gradient(135deg, A 50%, B 50%)` zamiast SVG/clip-path | Najprostsze CSS, brak dodatkowych assetów, pełne wsparcie w nowoczesnych przeglądarkach | Łatwa modyfikacja kątów / kierunków bez zmian w JS | | Paleta `#0e2036`/`#bc1834` zamiast `#0a2a5e`/`#d63638` z planu | Po inspekcji `calendar.scss` znaleziono faktyczne kolory już używane na stronie (przyciski, switcher, instructions) | Spójność wizualna z resztą widgetu — bez nowych kolorów do utrzymania | | Iteracja kierunku skosu pierwszego dnia (45° → 135°) | Klient zgłosił błędny kierunek po pierwszym deployu; flip → parallelogram przez wiersz | Wymagała 2 deployów, ale teraz oba dni mają tę samą oś diagonalną | | Cyfry dni z `!important` na `.fc-daygrid-day-number` | Globalna reguła `body a:not([href]):not([tabindex])` na końcu pliku ustawiała `color: #fff` na linkach FullCalendar | Bez !important globalna reguła wygrywała specyficznością | | Single-day blokada = pełen booked (klasa `*-single`, brak gradientu) | Skos klepsydry byłby wizualnie mylący dla 1-dniowej blokady | Klasa `*-single` zarezerwowana — łatwa do wykorzystania w przyszłości | | `test-add-booking.php` w roocie z tokenem | Zgodne z konwencją projektu (`test-*.php` per CLAUDE.md); brak DB CLI; token chroni przed nieautoryzowanym użyciem | Plik DO USUNIĘCIA po testach — nie commitować na produkcję | ## Deviations from Plan ### Summary | Type | Count | Impact | |------|-------|--------| | Auto-fixed | 3 | Essential UX fixes wymagane przez klienta podczas verify | | Scope additions | 1 | test-add-booking.php helper — nie był w planie ale niezbędny do weryfikacji | | Deferred | 0 | — | ### Auto-fixed Issues **1. [UX] Ramki dni w kalendarzu były jasne mimo override w pierwszej iteracji** - **Found during:** Checkpoint human-verify (iteracja 2) - **Issue:** Pierwotny override `border-color: #0e2036 !important` na 3 selektorach nie działał — FullCalendar v6 używa `--fc-border-color` na wielu warstwach (scrollgrid section, daygrid-day, theme-standard td/th) - **Fix:** Ustawiłem `--fc-border-color: #0e2036` na `.yacht-calendar` i `.yacht-calendar .fc` plus override na 7 selektorach (td/th/scrollgrid/scrollgrid-section/daygrid-day/col-header-cell) - **Files:** calendar.scss, calendar.css - **Verification:** Klient potwierdził „Jest ok" po deployu **2. [UX] Skos pionowy zamiast 45°** - **Found during:** Checkpoint human-verify (iteracja 2) - **Issue:** Pierwotny gradient `to right` dawał pionowy podział 50/50 — nieczytelny estetycznie i niezgodny z image013.png - **Fix:** Zmiana na `linear-gradient(45deg, ...)` (start) i `linear-gradient(135deg, ...)` (end), potem korekta start na `135deg` po feedbacku - **Files:** calendar.scss, calendar.css, class-calendar-widget.php (legenda) - **Verification:** „Jest ok" po finalnej korekcie kierunku **3. [UX] Cyfry dni białe (nieczytelne na jasnym tle)** - **Found during:** Checkpoint human-verify (iteracja 4) - **Issue:** Globalna reguła `body a:not([href]):not([tabindex]) { color: #fff }` (linia 672 SCSS) pokrywała linki cyfr FullCalendar - **Fix:** `.yacht-calendar .fc-daygrid-day-number { color: #021526 !important; font-weight: 600 }`. Past days `#6c757d` - **Files:** calendar.scss, calendar.css - **Verification:** Klient potwierdził „Jest ok" ### Scope Additions **1. test-add-booking.php — token-protected helper** - **Reason:** Klient chciał zobaczyć podzielone dni; brak istniejącej rezerwacji do testów; brak dostępu DB CLI z tej maszyny - **Implementation:** Skrypt PHP w roocie z tokenem `YACHT_TEST_2026`, akcje add/list/remove, marker meta `_yacht_test_booking_marker = PAUL_TEST_09_01` - **Cleanup:** Plik DO USUNIĘCIA z FTP po zakończeniu testów (jest w `.gitignore`? — nie, świadomie zostawiamy w repo lokalnym aby user mógł użyć ponownie; produkcyjnie usunąć z FTP) ### Deferred Items Brak. ## Issues Encountered | Issue | Resolution | |-------|------------| | Pierwsza iteracja gradientu pionowa zamiast skośnej | Klient feedback → kąt 45°/135° | | Kierunek skosu pierwszego dnia odwrotny niż oczekiwany | Flip 45° → 135° na start | | Cyfry dni białe | !important override na `.fc-daygrid-day-number` | | Ramki dalej jasne po pierwszej próbie | Dodanie `--fc-border-color` (zmienna FullCalendar v6) plus szerszy zestaw selektorów | ## Skill Audit Brak `.paul/SPECIAL-FLOWS.md` w projekcie — pominięto. ## Next Phase Readiness **Ready:** - Phase 9 / Plan 01 zamknięty, kalendarz UX/UI w stanie produkcyjnym - Paleta widgetu znormalizowana, można używać CSS variables w przyszłych iteracjach - Helper `test-add-booking.php` dostępny do dalszych smoke testów **Concerns:** - Walidacja overlap dalej blokuje rezerwację rozpoczynającą się w dniu zwrotu — wizualnie skos sugeruje że to dozwolone. Decyzja biznesowa: czy klient chce wprowadzić politykę check-in/check-out z godzinami (osobny plan) - `test-add-booking.php` powinien zostać USUNIĘTY z FTP po testach (zostaje w repo dla wygody) **Blockers:** - Brak. Faza 9 może kontynuować planem 09-02 (Settings Page) --- *Phase: 09-finalizacja, Plan: 01* *Completed: 2026-05-06*