Files
2026-07-12 10:17:17 -04:00

3.1 KiB

SPQ Auth Flow & Page Structure

File roles

File Role
index.html Login/signup page — the root page. No auth redirect on load.
dashboard.html Dashboard — the main app (was previously index.html).
appointments.html, repair-orders.html, customers.html Sub-pages with shared header/nav pointing to dashboard.html.

Auth redirects

Not logged in:
  / → index.html (login form, NO redirect)
  /dashboard.html → auth guard → redirects to /index.html

Logged in:
  / → detects token in localStorage → redirects to /dashboard.html
  /dashboard.html → stays
  Logout → redirects to /index.html

Why index.html is the login page

Originally index.html was the dashboard and login.html was the login page. This caused a redirect loop: when PocketBase auth state was unstable (stale/expired token), onAuthStateChanged on the dashboard saw no user and redirected to login.html, whose own onAuthStateChanged saw the stored token and redirected back to index.html — creating a flip-flop between the two URLs.

Fix: Made index.html the login page and moved the dashboard to dashboard.html. Now visiting the root (/) shows the login form directly with zero redirects. The dashboard only redirects when it detects no user (→ /), and the login only redirects when it detects a user (→ /dashboard.html). No more reciprocal bounce.

Reference: all redirect targets

When renaming or restructuring pages, update these files:

Auth failure → index.html (login)

  • dashboard.js:122window.location.href = 'index.html'
  • main.js:44window.location.href = 'index.html'
  • appointments.js:50window.location.href = 'index.html'
  • customers.js:78window.location.href = 'index.html'
  • repair-orders.js:58window.location.href = 'index.html'
  • shared/header-functionality.js:318 — logout handler → 'index.html'

Login success → dashboard.html

  • login.js:33window.location.href = 'dashboard.html'
  • index.html:131 — inline script: location.replace('dashboard.html?cb='+Date.now())
  • index.html:577 — login success handler
  • index.html:1035 — signup success handler

All href="dashboard.html" in: appointments.html, repair-orders.html, customers.html, dashboard.html

  • dashboard.html nav has active-page class on its own link
  • customers.js:676href="dashboard.html?quoteId=${escapeHtml(quote.id)}"

Keyboard shortcut → dashboard.html

  • dashboard.js:2144 — case 'q' keyboard shortcut

Dual-VPS config Host header note

The VPS has two ShopProQuote nginx configs:

  • shopproquote-duckdns (for grajmedia.duckdns.org) — Host: grajmedia.duckdns.org ✓ correct
  • shopproquote (for shopproquote.graj-media.com) — Host: graj-media.commay not match home nginx which only has server_name grajmedia.duckdns.org. See vps-reverse-proxy skill's "Host header mismatch → SPA redirect loop" pitfall.