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

63 lines
3.1 KiB
Markdown

# 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:122``window.location.href = 'index.html'`
- `main.js:44``window.location.href = 'index.html'`
- `appointments.js:50``window.location.href = 'index.html'`
- `customers.js:78``window.location.href = 'index.html'`
- `repair-orders.js:58``window.location.href = 'index.html'`
- `shared/header-functionality.js:318` — logout handler → `'index.html'`
### Login success → `dashboard.html`
- `login.js:33``window.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
### Nav links → `dashboard.html`
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
### Quote deep-link → `dashboard.html?quoteId=...`
- `customers.js:676``href="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.com`**may 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.