Files
Thinh Lam 688fac73e9
CI/CD / backend (push) Failing after 2m8s
CI/CD / frontend (push) Failing after 1m40s
CI/CD / deploy (push) Has been skipped
sciagent code + Gitea Actions CI/CD
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 09:38:30 +07:00

114 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 1 Signup page — how it works
This document describes [`Signup.tsx`](./Signup.tsx): a **standalone registration screen** for the `fe01` “phase1” demo flow. Use it as a spec when re-implementing the same behavior elsewhere.
## Where it lives in the app
- **Component:** `fe01/src/phase1/pages/Signup.tsx` (default export `Signup`)
- **Route:** `/phase1/signup` (see `fe01/src/App.tsx`)
This is **not** the same as the main apps tabbed login/signup at `/signup`, which uses `SignupForm` (`fe01/src/components/auth/SignupForm.tsx`) with extra fields and optional OTP. The phase1 page is intentionally simpler.
## Dependencies
| Area | What |
|------|------|
| **Router** | `react-router-dom`: `Link`, `useNavigate` — success screen uses `navigate('/login')` (root login, not phase1). Link at bottom goes to `/phase1/login`. |
| **API** | `authService` from `@/phase1/lib/auth-service``register()` and `resendVerify()`. |
| **UI** | shadcn-style: `Button`, `Input`, `Label`, `Card*`, `Alert`, `Select`; icons from `lucide-react`. |
**Base URL:** `authService` uses `import.meta.env.VITE_API_URL` or falls back to `http://localhost:3000` (see `auth-service.ts`). Ensure your re-implementation uses the same env variable or your chosen API base.
## User-facing flow (two screens)
1. **Form screen** — collect name, school email, password, role → submit.
2. **Success screen** — shown when registration succeeds: explains that a verification email was sent, offers **resend verification** and **back to login**.
There is **no** auto-redirect after signup; the user must verify email via the link in mail (handled by backend + a separate verify route elsewhere, e.g. `/verify-email?userId=...&token=...`).
## State model
| State | Type | Role |
|-------|------|------|
| `email`, `password`, `fullName` | `string` | Controlled form fields |
| `role` | `'Admin' \| 'Editor' \| 'Viewer'` | Default `'Viewer'` |
| `error` | `string` | Inline validation / API error message |
| `loading` | `boolean` | Disables inputs and shows spinner on submit/resend |
| `successMsg` | `string \| null` | Message from API after successful register or resend |
| `registeredEmail` | `string \| null` | Email used for resend; together with `successMsg` gates the success UI |
**Success UI condition:** `successMsg && registeredEmail` — both must be set after a successful `register()`.
## Role picker
- **Canonical values** sent to API: `Admin`, `Editor`, `Viewer` (must match backend).
- **Display:** Vietnamese labels + icons + a one-line **description** under the select (`ROLE_OPTIONS` array in the component).
Re-implementing: keep the **API values** exactly as the backend expects; only labels/descriptions are presentation.
## Client-side validation (before `register`)
Order in `handleSubmit`:
1. Clear `error`.
2. `fullName` — non-empty after trim.
3. `email` — non-empty after trim.
4. **Domain check**`validateDomain()`:
- Must contain `@`.
- Part after `@` (lower case, trimmed) must equal one of **`ump.edu.vn`** or **`umc.edu.vn`** (hardcoded hint list `ALLOWED_DOMAINS_HINT`).
5. `password` — length ≥ 8.
**Important:** This list is a **UX hint**. The file comment states the server re-validates using `SystemSettings` / `Auth.AllowedEmailDomains`. Your copy can change the hint list, but must stay aligned with server policy.
**On submit:** email is sent as `email.trim().toLowerCase()`; `fullName` is `fullName.trim()`.
## API: `register`
**Call:** `authService.register({ email, password, fullName, role })`
**HTTP:** `POST {API_URL}/auth/register`
**Headers:** `Content-Type: application/json`, `X-Client-Origin: window.location.origin`
**Body:** JSON `{ email, password, fullName, role }` with `role` one of `Admin` | `Editor` | `Viewer`.
**On failure (`!res.ok`):** `authService` returns `{ success: false, error: string }` — page sets `error` and stops.
**On success:** `{ success: true, userId, email, role, emailSent, message }` — page sets `registeredEmail` from `res.email`, `successMsg` from `res.message`, does **not** set tokens (registration does not log the user in).
## API: resend verification
**When:** User is on success screen and clicks “Gửi lại email xác nhận”.
**Call:** `authService.resendVerify(registeredEmail)`
**HTTP:** `POST {API_URL}/auth/resend-verify` with JSON `{ email }`, same `X-Client-Origin` pattern.
**On response:** Page updates `successMsg` with `res.message` (does not clear the success layout).
## Error display
- Errors render in a destructive `Alert` above the submit button.
- Success screen uses a non-destructive `Alert` for `successMsg`.
## Styling / layout notes
- **Form:** centered card on `bg-muted/20`, max width `max-w-md`.
- **Success:** full-height centered layout with gradient background and slightly richer card styling (backdrop blur, green mail icon).
- **Accessibility:** labels use `htmlFor` matching input `id`; password field has `minLength={8}` and `required` in addition to JS checks.
## Checklist for a faithful re-implementation
- [ ] Same route or intentionally different — document if you move it.
- [ ] `register` + `resendVerify` endpoints, payloads, and headers (`X-Client-Origin`, `credentials: 'include'` if cookies matter for your stack).
- [ ] Two-step UI: form → “check your email” with resend + login navigation.
- [ ] Client validation order and domain hint list (or replace hint with server-driven list if you add an endpoint).
- [ ] Role enum matches backend; Vietnamese copy optional.
- [ ] Distinguish this simple flow from `SignupForm` (OTP/extra fields) if both exist in the product.
## Related files
- `fe01/src/phase1/lib/auth-service.ts``register`, `resendVerify`, `verifyEmail`
- `fe01/src/App.tsx` — route wiring
- `fe01/src/components/auth/SignupForm.tsx` — richer signup used on main `/login` + `/signup` (different product path)