register and sign in pages
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# frontend
|
||||
|
||||
Vite + React + TypeScript SPA for the SAR Link portal. No Node at runtime:
|
||||
production is a static bundle served by nginx.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Build | Vite 8 |
|
||||
| UI | React 19, Tailwind CSS v4 |
|
||||
| Routing | React Router 7 (SPA, `BrowserRouter`) |
|
||||
| Auth | knox token in `localStorage`, `AuthProvider` in `src/lib/auth.tsx` |
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
src/lib/api.ts fetch wrapper, typed endpoints, ApiError
|
||||
src/lib/auth.tsx AuthProvider (session bootstrap, sign in/out)
|
||||
src/lib/auth-context.ts AuthContext + useAuth
|
||||
src/lib/date.ts local-time YYYY-MM-DD formatting
|
||||
src/components/ ui primitives, Select, DateField, AppLayout, RequireAuth
|
||||
src/pages/ Login (two-step), Register (form), Dashboard, NotFound
|
||||
```
|
||||
|
||||
## Run it
|
||||
|
||||
From the repo root (starts the API and database too):
|
||||
|
||||
```sh
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Or on the host, against a backend on `localhost:8000`:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Then `http://localhost:5173`.
|
||||
|
||||
## Talking to the API
|
||||
|
||||
The app always calls a relative `/api/...`. Nothing hardcodes a backend URL:
|
||||
|
||||
- **dev** — `vite.config.ts` proxies `/api`, `/admin`, `/static` and `/media` to
|
||||
`VITE_API_PROXY_TARGET` (`http://backend:8000` in compose).
|
||||
- **prod** — nginx serves `dist/` and proxies the same prefixes to gunicorn.
|
||||
|
||||
So there is no CORS in production, and no API origin to configure at build time.
|
||||
|
||||
## Sign-in and registration
|
||||
|
||||
`src/pages/Login.tsx` is one form whose second step the API chooses:
|
||||
|
||||
1. Mobile number -> `POST /api/auth/start/`
|
||||
2. The response's `next` decides what appears under it:
|
||||
- `password` -> password field -> `POST /api/auth/login/password/`
|
||||
- `otp` -> 6-digit code, with a resend cooldown -> `POST /api/auth/verify/`
|
||||
3. `verify/` answers with `next`: `dashboard` (token stored, on to the portal)
|
||||
or `register` (the returned ticket goes to `/register` in router state).
|
||||
|
||||
The code step looks the same whether or not the number has an account - the UI
|
||||
has no idea until the code is confirmed, which is the point.
|
||||
|
||||
`src/pages/Register.tsx` requires that ticket (no ticket -> back to `/login`),
|
||||
shows the verified number read-only, and collects name, ID card/passport/work
|
||||
permit number, date of birth (`DateField`, a react-day-picker popover with
|
||||
month and year dropdowns), atoll + island (from `GET /api/locations/atolls/`, island
|
||||
list filtered by the chosen atoll) and the two agreement checkboxes linking to
|
||||
sarlink.net/terms and /policy. Submitting shows a "pending approval" panel - it
|
||||
does not sign the applicant in.
|
||||
|
||||
A pending or rejected account that signs in later sees a status banner on the
|
||||
dashboard instead of services.
|
||||
|
||||
On reload `AuthProvider` calls `GET /api/auth/me/` to turn the stored token
|
||||
back into a user, and clears it if the API rejects it.
|
||||
|
||||
## Adding a dependency
|
||||
|
||||
`node_modules` lives in a Docker volume that outlives image rebuilds, so a new
|
||||
entry in `package.json` isn't in the container until it's installed there. The
|
||||
dev service runs `npm install` on every start, so:
|
||||
|
||||
```sh
|
||||
npm install <pkg> # updates package.json + lock on the host
|
||||
docker compose restart frontend # installs it in the container
|
||||
```
|
||||
|
||||
If it still can't resolve the import, the volume is stale — recreate it with
|
||||
`docker compose up -d -V frontend`.
|
||||
|
||||
## Scripts
|
||||
|
||||
```sh
|
||||
npm run dev # dev server on :5173
|
||||
npm run build # tsc -b && vite build -> dist/
|
||||
npm run preview # serve dist/ locally
|
||||
npm run lint # oxlint
|
||||
```
|
||||
Reference in New Issue
Block a user