feat(web): admin theme token editor with live preview (ATB-59) (#90)
* docs: add design doc for ATB-59 admin theme token editor
Covers file structure (extract to admin-themes.tsx), editor page layout,
HTMX preview endpoint, save/reset flows, error handling, and test plan.
* docs: add implementation plan for ATB-59 theme token editor
Covers extract-to-admin-themes.tsx, TDD for GET /admin/themes/:rkey,
preview endpoint, save, and reset-to-preset handlers.
* refactor(web): extract theme admin handlers into admin-themes.tsx (ATB-59)
* refactor(web): mount admin-themes routes, remove extracted code from admin.tsx (ATB-59)
* test(web): add failing tests for GET /admin/themes/:rkey (ATB-59)
* test(web): improve admin-themes test quality for GET /admin/themes/:rkey
- Extract MANAGE_THEMES constant to reduce repetition
- Rename setupAuth → setupAuthenticatedSession to match admin.test.tsx pattern
- Remove unnecessary fetch mock from unauthenticated test
- Strengthen CSS overrides assertion to require co-location via regex
- Add colorScheme and second token assertions to happy-path test
- Restore strict "Access Denied" assertion on 403 test
- Add ATB-62 reference to CSS overrides test description
* feat(web): GET /admin/themes/:rkey token editor page + fix Edit button (ATB-59)
* fix(web): block } in sanitizeTokenValue to prevent CSS block-escape injection (ATB-59)
* test(web): write failing tests for POST /admin/themes/:rkey/preview (ATB-59 TDD red)
* test(web): strengthen preview tests — add fallback test, fix semicolon sanitization assertion (ATB-59)
* test(web): fix preview test quality — align auth fixture, strengthen } assertion, clarify description (ATB-59)
* test(web): add 403 test for preview POST — manageThemes permission gate (ATB-59)
* feat(web): POST /admin/themes/:rkey/preview — HTMX live preview endpoint (ATB-59)
Adds the live-preview fragment endpoint used by the theme editor's HTMX
integration. Sanitizes token values via sanitizeTokenValue() before
rendering ThemePreviewContent, dropping any value containing '<', ';',
or '}' to prevent CSS injection.
* fix(web): tighten sanitization assertions to --name: format, restore var(--color-bg) in preview template (ATB-59)
* test(web): write failing tests for POST /admin/themes/:rkey/save (ATB-59)
* feat(web): POST /admin/themes/:rkey/save — persist token edits to AppView (ATB-59)
* fix(web): sanitize token values on save + add PUT body forwarding test (ATB-59)
* test(web): write failing tests for POST /admin/themes/:rkey/reset-to-preset (ATB-59)
* test(web): strengthen reset-to-preset 400 assertion (ATB-59)
* feat(web): POST /admin/themes/:rkey/reset-to-preset (ATB-59)
* fix(web): address code review issues — ATB-59
- Fix GET /admin/themes/:rkey to call public /api/themes/:rkey instead
of nonexistent /api/admin/themes/:rkey; remove unused cookie variable
- Validate name before AppView PUT in save handler; redirect with error
if empty (prevents wasteful round-trip and unclear AppView message)
- Replace c.json() with redirect-on-error in reset-to-preset handler so
browser form POSTs show friendly error pages instead of raw JSON
- Add network failure test for GET /admin/themes/:rkey (500 unavailable)
- Add empty-name validation test for save handler
- Move ATB-59 plan docs to docs/plans/complete/
* docs: move ATB-59 plan docs to complete/