# Frontend spec A React 19 SPA built with Vite, routed by React Router 7. Entry: `src/main.jsx` → `src/App.jsx`. Global state lives in `src/store/AppContext.jsx`. --- ## Routing & access control (`src/App.jsx`) | Route | Screen | Access | |---|---|---| | `/login` | `Login.jsx` | public | | `/onboarding` | `Onboarding.jsx` | logged-in, not yet enrolled | | `/` | `Dashboard.jsx` | enrolled user | | `/learn` | `Leren.jsx` | enrolled user | | `/test` | `Testen.jsx` | enrolled user | | `/leaderboard` | `Leaderboard.jsx` | enrolled user | | `/admin/*` | `Admin/index.jsx` | `role === 'admin'` | `ProtectedRoute`: - redirects to `/login` if not authenticated; - redirects to `/onboarding` if `enrollment_status !== 'active'` — **except** admins heading to the admin panel, who are exempt; - enforces `requireAdmin` for `/admin`. Navigation chrome (top bar + mobile bottom nav) is rendered by `ProtectedRoute`. `ChatLauncher` (R42) is mounted globally. --- ## Auth & global state (`AppContext.jsx`) - Loads `team_members` on mount; auto-creates an `Admin` (PIN `0000`) if the table is empty. - PIN login resolves a member and stores the id in `sessionStorage.respellion_session`. - `state.currentUser` holds the member; `state.weekNumber` is the user's **absolute curriculum week**, derived from `curriculum_started_at` via `getPersonalWeekNumber` (0 until enrolled). - `enrollCurrentUser()` stamps `curriculum_started_at = now`, sets `enrollment_status = 'active'`, and updates state. --- ## Onboarding (`Onboarding.jsx`) A blocking first-login screen. One CTA — "Start my journey" — calls `enrollCurrentUser()` and routes to `/`. Week 1 begins immediately. Users already enrolled are redirected to `/`. See `docs/curriculum-spec.md`. --- ## Employee screens - **Dashboard** — current cycle/week, assigned topic, cycle progress ring, quick links to Learn and Test, mini leaderboard, recent activity. - **Learning Station (`/learn`)** — the week's required topic + the rest of the knowledge library; opening a topic shows the micro-learning selector (`src/components/micro_learning/`). Completing ≥1 micro-learning marks the week done. - **Test (`/test`)** — 5-question quiz with a 5-minute timer, per-question feedback, and a results/review screen. Sets the `quiz:active` flag to hide R42. - **Leaderboard (`/leaderboard`)** — podium + ranked list + badges (see `docs/gamification-spec.md`). Labels show `Cycle X · Week Y of 26`, where Y/X come from `getCurriculumWeek` / `getCurriculumCycle` applied to `state.weekNumber`. --- ## Admin panel (`Admin/index.jsx`) Tabbed: **Sources** (upload + extraction), **Content** (review/refine generated content), **Quizzes**, **Curriculum** (generate/preview/activate a schedule), **Graph** (D3 knowledge graph + R42 suggestions queue), **Team** (manage members), **Settings** (per-tier model overrides, simulation toggle, smoke-test reset). --- ## Design system - CSS variables in `src/index.css`: colors (`--color-bg`, `--color-paper`, `--color-teal`, `--color-accent`), radii (`--r-sm`, `--r-lg`, `--r-org`). - Tailwind v4 utilities map to those variables (`bg-teal`, `text-fg-muted`, `border-bg-warm`, …). Avoid raw hex. - `stylesheet.css` (repo root) is the authoritative visual reference — frozen. - Reuse `src/components/ui/` primitives: `Card`, `Button`, `Tag`, `Input`. - Framer Motion for entry animations; mobile-first (target 375px). --- ## Build (`vite.config.js`) - Injects `__BUILD_SHA__` / `__BUILD_TIME__` (shown by `BuildStamp`). - Dev server proxies `/api/anthropic` to Anthropic and injects `ANTHROPIC_API_KEY`. - Source maps on; production build outputs to `dist/`.