feat(welcome): landing lightbox, prod-served screenshots & session-end UX

- Serve real files at the SPA root (e.g. /welcome/*.png, favicon) from the built app — the
  landing screenshots were only ever shown by the Vite dev server, never in production.
- Add the Channel-manager screenshot; the two secondary previews are smaller thumbnails that
  open in a custom full-size lightbox (fit-to-viewport, Esc/backdrop/✕ to close).
- Drop a suspended/deleted user to the login page on the next 401 (and poll the session only
  while signed in, so the public login page no longer flickers); 'suspended' and 'account
  deleted' confirmation banners; strip redirect query params for a clean address bar.
This commit is contained in:
npeter83 2026-06-19 19:52:29 +02:00
parent 4571800991
commit c59695d2b3
7 changed files with 180 additions and 22 deletions

View file

@ -107,4 +107,11 @@ async def spa_fallback(full_path: str) -> FileResponse:
# Client-side routes fall back to index.html; real API/asset paths are matched above.
if full_path.startswith(("api/", "auth/", "healthz", "assets/")):
raise HTTPException(status_code=404)
# Serve real files that live at the SPA root (Vite copies public/ there — e.g. the landing
# screenshots under /welcome/, favicon). /assets is already mounted above; everything else
# that isn't a real file is a client-side route → index.html. Guard against path traversal.
if full_path:
candidate = (STATIC_DIR / full_path).resolve()
if candidate.is_file() and STATIC_DIR.resolve() in candidate.parents:
return FileResponse(candidate)
return FileResponse(STATIC_DIR / "index.html")