diff --git a/docs/plans/2026-05-08-1439-go-m6-6-1-payment-qr-modal.md b/docs/plans/2026-05-08-1439-go-m6-6-1-payment-qr-modal.md new file mode 100644 index 0000000..f29d69e --- /dev/null +++ b/docs/plans/2026-05-08-1439-go-m6-6-1-payment-qr-modal.md @@ -0,0 +1,335 @@ +# M6.6.1 — Pay-button QR popup modal (`/adults`, `/juniors`) + +> Plan-mode note: per project convention this plan should live at +> `docs/plans/2026-05-08-1439-go-m6-6-1-payment-qr-modal.md`. The first +> execution step after approval is to copy this file there. +> Branch: `feat/go-m6-6-1-payment-qr-modal` off `main`. + +## Context + +M6.6 ([docs/plans/2026-05-08-1334-go-m6-6-action-pages.md](docs/plans/2026-05-08-1334-go-m6-6-action-pages.md)) +landed the backend `/qr` PNG endpoint plus `/sync-bank`, `/flush-cache`, +`/version`. While doing it, the **client-side** half of the Pay flow was +collapsed from a modal-with-details into a plain `` — +clicking Pay now navigates the whole tab to the raw PNG. + +The Python app instead opens an in-page `#qrModal` showing the QR image +*plus* labelled details (account, amount, message, title), then closes +the modal on outside-click or `[close]` +([templates/adults.html:631-648](templates/adults.html#L631-L648), +JS at [templates/adults.html:963-993](templates/adults.html#L963-L993)). +This is the UX the user expects from the dashboard — staying on the +table while displaying the QR is significantly more practical than +losing context to a fullscreen image. + +M6.6.1 restores parity: the Pay/Pay-All buttons open an in-page +`#qrModal`, identical in structure to the Python original, driven by a +new vanilla-JS module `payment-qr.js` that mirrors the `member-detail.js` +convention from M6.5. + +All the building blocks are already in place: + +- **`/qr` endpoint** ships PNGs ([go/internal/web/qr.go](go/internal/web/qr.go), tested by [TestServeQR](go/internal/web/html_handler_test.go#L207-L231)). +- **CSS** for `#qrModal .modal-content`, `.qr-image`, `.qr-details` is + already in [go/internal/web/static/css/app.css:445-478](go/internal/web/static/css/app.css#L445-L478) — lifted during M6.1. +- **Template helpers** `qrHref` / `qrHrefAll` ([go/internal/web/render.go:63-85](go/internal/web/render.go#L63-L85)) + already produce the correct query string + Czech `MM/YYYY` format + for the `message=` param. They're useful for sanity (and for any + no-JS fallback) but become dead code post-M6.6.1 — see §Out of scope. +- **Bank account** is already exposed as `$.Data.BankAccount` to every + template that has a Pay button. +- **JS module convention**: `member-detail.js` is the M6.5 baseline — + IIFE, `'use strict'`, event delegation off `data-*` attributes, no + inline `onclick`, no globals leaked. + +## Approach + +### 1. Replace `` with ` +``` + +```gotmpl + +``` + +Why ` {{end}} {{end}} {{$row.Balance}} {{if gt $row.PayableAmount 0}} - Pay All + {{end}} @@ -164,6 +164,24 @@ +
+ +
+ + {{end}}