A self-paced onboarding track that introduces a new employee to every KB theme in breadth (not depth), so they grasp how Respellion works day to day and week to week. Offered as a CTA inside the Dashboard "New here?" explainer card; always available regardless of enrollment. Design: - Theme is the trackable unit; the 5 "days" are a read-time presentation grouping, so re-chunking never loses progress. Completion is stored per theme in onboarding_completions. - Per-theme overview generated lazily on first open (fast-tier emit_onboarding_overview tool), cached in onboarding_overviews keyed by theme + a topics_fingerprint that triggers regeneration when the theme's topic set changes. - Reachable via /onboarding-track using the existing skipEnrollmentGate prop, decoupled from the 26-week curriculum (distinct from /onboarding, the enrollment page). Backend: - pb_migrations/1781200000_created_onboarding.js: two collections with authenticated-only rules and unique indexes; TEXT team_member_id (no relation) per the post-#18/#27 convention. Mirrored in scripts/setup-pb-collections.mjs. - src/lib/onboardingService.js: pure helpers (orderThemes, distributeThemesIntoDays, computeTopicsFingerprint, computeOnboardingProgress, buildOnboardingPlan) + generation + I/O. - db.js onboarding helpers use pb.filter() bindings (theme is free text). - LLM tool + Zod schema + registry + simulation stub. Frontend: - src/pages/OnboardingTrack.jsx (day list, per-theme overview, completion banner, progress ring/day bar). - Dashboard "New here?" card CTA + X/5-days progress chip (hidden when the KB has no themes). Docs: data-model, generation-spec (§D), frontend-spec updated. Verified: 22 new unit tests (npm test 134/134), eslint clean on changed files, npm run build OK, PocketBase v0.30.4 boot applies the migration (collections + unique indexes + authed rules confirmed), and a backend contract check (upsert idempotency, unique-index guard, special-char theme filtering). Closes #30 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
110 lines
4.8 KiB
Markdown
110 lines
4.8 KiB
Markdown
# 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 (enrollment page) |
|
|
| `/` | `Dashboard.jsx` | enrolled user |
|
|
| `/onboarding-track` | `OnboardingTrack.jsx` | any logged-in user, **any enrollment** (`skipEnrollmentGate`) |
|
|
| `/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, and routes passing `skipEnrollmentGate` (the onboarding
|
|
track), which are exempt;
|
|
- enforces `requireAdmin` for `/admin`.
|
|
|
|
> `/onboarding` (enrollment) and `/onboarding-track` (the 5-day theme intro) are
|
|
> distinct. The track is decoupled from enrollment on purpose so it also works as a
|
|
> refresher for existing staff.
|
|
|
|
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. The dismissible
|
|
"New here?" explainer card also carries the **onboarding-track CTA** (a progress
|
|
chip `X/5 days` + a Start/Continue/Review button linking to `/onboarding-track`),
|
|
shown only when the KB has themes to introduce.
|
|
- **Onboarding Track (`/onboarding-track`)** — a self-paced, breadth-first tour of
|
|
every theme, grouped into ≤5 day cards (`OnboardingTrack.jsx`). Opening a theme
|
|
lazily generates a short overview (what it is / why it matters for daily & weekly
|
|
work / key points / topics) and offers "Mark as done"; a progress ring + day bar
|
|
track completion, and a completion banner shows when every theme is done. Available
|
|
to any logged-in user regardless of enrollment; completion is stored per theme in
|
|
`onboarding_completions`. See `docs/generation-spec.md §D`.
|
|
- **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/`.
|