63 lines
3.1 KiB
Markdown
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.
|