Files
newwalls.pl/.paul/PROJECT.md
Jacek Pyziak ac03f807c1 feat(02-product-actions-fixes): Phase 02 complete — customization, price label, structure fix
Plan 02-03: Customization save + success modal (5/5 AC)
- 26-field squaremeter POST payload (verbose PL dim, qty_alt/qty_alth)
- Chain POST /module/ps_shoppingcart/ajax -> Bootstrap #blockcart-modal
- Critical fix: moved {/block} so inline script actually renders
- __p02p02InFlight re-entrancy guard

Plan 02-04: Live cena per-sqm label obok "Dodaj do koszyka" (5/5 AC)
- .p02p04-total-price label, gorna .current-price static
- Separate __p02p04Bound + setInterval reconciliation
- Poll-retry prestashop.on registration

Plan 02-05: Struktura materialu w POST payload (4/4 AC)
- Enumerate [name^="group["] spoza formy, doklej do payload
- Fix: group_5 select w .product-bar-box nie trafial do koszyka

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:55:05 +02:00

72 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PROJECT.md
## Name
newwalls.pl — PrestaShop 1.7 (theme: ayon)
## Mission
Sklep z tapetami na wymiar. Klient prowadzi migrację wyglądu strony produktu na nowy layout. Do czasu zakończenia testów nowy layout jest warunkowany IP administratora.
## Core Constraints
- Stary i nowy wygląd strony produktu współegzystują w `themes/ayon/templates/catalog/product.tpl`:
- Stary layout: `{if $smarty.server.REMOTE_ADDR != '89.69.31.86'} ... {/if}`
- Nowy layout: `{if $smarty.server.REMOTE_ADDR == '89.69.31.86'} ... {/if}`
- Nie wolno modyfikować starego layoutu (produkcja działa dla zwykłych użytkowników).
- Partial `themes/ayon/templates/catalog/_partials/product-variants.tpl` jest współdzielony — zmiany w nim muszą być zgodne z oboma layoutami.
- Stack: PrestaShop 1.7, Smarty, jQuery, SCSS (`themes/ayon/assets/css/custom.scss``custom.css`).
## Value Proposition
Nowy layout strony produktu ma dać czystszy, bardziej prezentowalny UI konfiguratora tapety przy zachowaniu dotychczasowej funkcjonalności (wybór wariantu kolorystycznego, wymiary, dodanie do koszyka itd.).
## Known Broken After Redesign
### ✅ Naprawione (Phase 01)
- `.product-variants` (wariant kolorystyczny) — wygląd grid 3×1 wg Figma 27:9867 + klik zmienia wariant in-place (AJAX `action=refresh` + `history.pushState`).
### ✅ Naprawione (Phase 02)
- **Konfigurator „piece"** (Plan 02-01) — crop + odbicie lustrzane, drag + mirror, re-init po AJAX refresh. Reuse `#piece` z shared partial.
- **Add-to-cart submission** (Plan 02-02) — capture-phase native handler w custom.js + inline mirror, blockcart refresh, idempotency guard. Button+qty poza formą `#add-to-cart-or-refresh` — manualny serialize + POST.
- **Customization save + success modal** (Plan 02-03) — full squaremeter payload (26 fields, verbose PL dim), chain POST do `/module/ps_shoppingcart/ajax` → Bootstrap `#blockcart-modal`. `__p02p02InFlight` re-entrancy guard. Inline script finally renders (Plan 02-03 `{/block}` move).
- **Live cena labelka** (Plan 02-04) — `.p02p04-total-price` obok "Dodaj do koszyka", reactively updates z piece dimensions + variant AJAX refresh. Górna `.current-price` zostaje statyczna info-label.
- **Struktura materiału w POST payload** (Plan 02-05) — enumeracja external PS attribute groups (`[name^="group["]` poza formą) w POST payload. Wybrana „Tekstura materiału" (`<select id="group_5">`) trafia do koszyka z prawidłowym `id_product_attribute`.
### ⚠️ Do naprawy (Phase 03+ / deferred)
- **Plan 02-06 (deferred nice-to-have)** — systemowy cache-buster `?v=<mtime>` dla `<script src=custom.js>`; pozwoli wycofac inline mirror z Plan 02-02/02-03/02-04/02-05.
- **Plan 02-07** — Puste bloki `<div class="product-box--data"></div>`: `product-protect`, `product-installation`, `product-order-sample` — wypełnić treścią.
- Brakujące elementy dla pełnego PS `updatedProduct` flow (`.product-cover-thumbnails`, `.js-product-images2-modal`, `.product-details`, `.product-customization`, `.product-additional-info`) — edge case'y przy zmianie wariantu z różnymi miniaturami/opisami.
- Resize handles bezpośrednio na `#piece` (deferred bonus z Plan 02-01).
## Established Patterns (Phase 01)
- **Scoped CSS under `body#product .product-variants-data--new`** — izoluje zmiany nowego layoutu od globalnych reguł i starego widoku.
- **Własny AJAX refresh w `custom.js`** — `action=refresh` (nie `productrefresh`), POST na `window.location.href.split('?')[0].split('#')[0]`, `dataType: 'json'`, header `Accept: application/json`.
- **In-place DOM update**: `history.pushState(resp.product_url)` + `$('.product-prices-data .product-prices').replaceWith(resp.product_prices)` + `$('.product_image_wrapper').html(resp.product_cover_thumbnails)` + `prestashop.emit('updatedProduct', resp)`. Fallback na `window.location.reload()` przy błędzie.
- **Pipeline SCSS → CSS**: edytuj tylko `themes/ayon/assets/css/custom.scss`, `custom.css` auto-generowany przez user'a watcher (feedback memory).
## Established Patterns (Phase 02)
- **Capture-phase native addEventListener + `useCapture=true`** — blokuje PS core delegated handlers (bubble phase) w customowym flow, gdy trzeba całkowicie nadpisać PS behavior (Plan 02-02).
- **Idempotency guard per Plan** (`__p02pNNBound`) — kazdy plan ma own flag, nie shared; chroni inline mirror przed blokada gdy custom.js cached stale. Separate guards pozwalaja na plan-level cache-aware deployment (Plan 02-02/03/04).
- **Re-entrancy flag** (`__pNNInFlight`) — chroni przed podwójnym POST gdy handler i inline mirror oba firują. Reset w `complete:` callback jQuery.ajax (Plan 02-03).
- **Inline mirror IIFE w `{block name='content'}`** — `<script>` wewnatrz Smarty block, cache-safety dopóki systemowego cache-bustera (Plan 02-05) nie ma. `{/block}` musi zamykac się PO script (Plan 02-03 critical fix).
- **Playwright MCP ground truth capture** — temporary flip IP gate → capture 26-field OLD payload przed portowaniem do NEW (Plan 02-03). Bez tego verbose PL dim format i `qty_alt`/`qty_alth` by zostaly pominiete.
- **Manual FTP deploy via `curl -T ftp://...`** — ftp-kr VSCode watcher nie łapie zmian Claude Code Edit tool (feedback memory). Deploy 226 confirmation per file.
- **Poll-retry dla late globals** (`prestashop`, itp.) — inline script runtime, `window.prestashop` moze jeszcze nie istniec. `(function fn(){ if (avail) register(); else setTimeout(fn, 200); })()` niezawodnie obsługuje race (Plan 02-04).
- **Synchronous IIFE init zamiast jQuery(document).ready** — ready nie firuje konsekwentnie w inline Smarty block context. Synchronous call + recalc-safe early-return pokrywa DOM-not-ready case (Plan 02-04).
- **setInterval reconciliation** gdy external code overwritea nasz DOM po initial render (np. squaremeter init). 10×500ms okno = 5s pokrycie (Plan 02-04).
- **External PS attribute groups enumeration** — `[name^="group["]` inputs spoza `#add-to-cart-or-refresh` muszą być ręcznie enumerowane i dołączane do payload (`$form.serialize()` ich nie łapie). Defensive `closest('#form').length` skip (unika duplicate gdy kiedyś przesunięte do formy) + filter radio/checkbox przez `:checked` (Plan 02-05).
## Key Decisions (aggregated)
| Data | Faza/Plan | Decyzja | Wpływ |
|---|---|---|---|
| 2026-04-23 | 01-01 | Własny AJAX `action=refresh` + `history.pushState` zamiast PS core productrefresh | In-place wariant switch bez reload; base pattern dla wszystkich subsequent AJAX updates w NEW layoucie |
| 2026-04-23 | 02-01 | Override `totalpriceinfospecific`/`prod` na no-op | Spowodowało regresję squaremeter customization flow (Plan 02-02/03 fix); no-op zostaje ale fields syncowane manualnie w POST |
| 2026-04-23 | 02-02 | Capture-phase native handler (useCapture=true) | Pattern dla blokowania PS core bubble handlers przy customowym flow |
| 2026-04-23 | 02-02 | Inline mirror IIFE w product.tpl | Cache-safety dopóki Plan 02-05 nie dostarczy systemowego cache-bustera |
| 2026-04-24 | 02-03 | Playwright capture z flipped IP → ground truth payload | Bez tego verbose PL dim format + fields (qty_alt/qty_alth/calculated_total itp.) zostałyby pominięte; dał 5/5 AC pass |
| 2026-04-24 | 02-03 | Move `{/block}` inside script wrapper | Krytyczne: Smarty `{extends}` renderuje TYLKO blocki; inline script z Plan 02-02 był dead code przez cały czas |
| 2026-04-24 | 02-04 | Scope pivot: label zamiast `.current-price` | User request mid-task; górna cena zostaje info-label, konkretna suma blisko buttona |
| 2026-04-24 | 02-04 | Poll-retry prestashop.on + separate __p02p04Bound | Late-loading globals + stale-cache safety |
| 2026-04-24 | 02-05 | Enumerate `[name^="group["]` spoza formy → payload | Future-proof: kolejne PS attribute groups pokryte automatycznie bez code change |
---
*Last updated: 2026-04-24 after Phase 02 (5 plans)*