docs: add onboarding theme persistence & progress bar fix spec

This commit is contained in:
Théo LAGACHE
2026-06-19 11:21:54 +02:00
parent 0e780113de
commit 86d32f3d6a
@@ -0,0 +1,98 @@
# Onboarding — Theme Persistence & Progress Bar Fix
**Date:** 2026-06-19
**Scope:** `src/features/onboarding`
**Status:** Approved
---
## Problem Statement
Two independent bugs in the onboarding flow:
1. **Theme not persisted to DB** — selecting a theme in `StepPreferences` applies it visually via `next-themes` but never calls `authClient.updateUser({ theme })`, so the preference is lost on page reload unless the user also saves an avatar.
2. **Progress bar starts from current step, not from the beginning**`OnboardingStepper` uses `state.progressPercentage`, `state.currentStepNumber`, and `state.totalSteps` from OnboardJS. When onboarding resumes mid-flow (e.g. at step `invite-members`), OnboardJS recalculates these values relative to the remaining steps in the current session, not relative to the full 15-step flow. This makes the bar start at 0% even though the user is already 40%+ through.
---
## Fix 1 — Theme Persistence
**File:** `src/features/onboarding/steps/step-preferences.tsx`
### Current behaviour
```ts
const selectTheme = async (theme: ThemeKey) => {
setTheme(theme); // ✅ updates next-themes (UI)
// mettre à jour aussi en db! ← comment acknowledging the bug
await updateContext({ ... });
};
```
### Target behaviour
```ts
const selectTheme = async (theme: ThemeKey) => {
setTheme(theme);
await authClient.updateUser({ theme }); // ← add this line
await updateContext({ ... });
};
```
**Reference:** `src/features/profile/profile-appearance.tsx` already does this correctly.
**Error handling:** No change — if `updateUser` fails, the UI theme is still applied and the user can continue. No toast/error needed at this stage.
---
## Fix 2 — Progress Bar Recalculation
**File:** `src/features/onboarding/onboarding-stepper.tsx`
### Root cause
OnboardJS computes `progressPercentage` and `currentStepNumber` relative to the steps it was initialised with in the current session. When resuming mid-flow, the step list seen by OnboardJS starts at the resume step, not at `login`.
### Solution
Replace all OnboardJS progress values with a manual calculation based on `STEP_ORDER` (the canonical ordered list of all 15 steps, already defined in `src/features/onboarding/constants/steps.ts`).
```ts
import { STEP_ORDER } from "@/features/onboarding/constants/steps";
const currentId = String(state?.currentStep?.id ?? "");
const currentIndex = Math.max(0, STEP_ORDER.indexOf(currentId)); // guard: -1 → 0
const totalSteps = STEP_ORDER.length; // 15
const stepNumber = currentIndex + 1; // 1-based
const progress = Math.round((currentIndex / (totalSteps - 1)) * 100);
```
| Step | Index | stepNumber | progress |
|------------------|-------|------------|----------|
| login | 0 | 1 of 15 | 0% |
| preferences | 3 | 4 of 15 | 21% |
| invite-members | 5 | 6 of 15 | 36% |
| storage | 7 | 8 of 15 | 50% |
| finish | 14 | 15 of 15 | 100% |
**Edge case:** If `currentId` is not found in `STEP_ORDER`, `indexOf` returns `-1`, clamped to `0` by `Math.max` → shows step 1 of 15 at 0%. Safe degradation.
---
## Files Changed
| File | Change |
|------|--------|
| `src/features/onboarding/steps/step-preferences.tsx` | Add `authClient.updateUser({ theme })` in `selectTheme` |
| `src/features/onboarding/onboarding-stepper.tsx` | Replace OnboardJS progress values with `STEP_ORDER`-based calculation |
No new files, no schema changes, no API changes.
---
## Out of Scope
- Adding a toast/error on failed theme save
- Persisting the avatar selection to DB during selection (only on "Continue" — existing behaviour unchanged)
- Refactoring OnboardJS step initialisation