Onboarding : état vide du tableau de bord, liste de démarrage et bouton de réaffichage dans Paramètres #352

Closed
opened 2026-09-26 12:24:30 +00:00 by maximus · 0 comments
Owner

Vague planned-2026-10-03-onboarding-phase1 (séance /plan-run du 2026-10-03, spec + /review-spec du 2026-09-25, verdict APPROUVÉ après intégration). Les fichiers spec-decisions-onboarding-phase1.md / spec-plan-onboarding-phase1.md sont ignorés par git : ce corps est auto-suffisant, ne pas chercher le spec. Analyse d'origine : docs/analyse-onboarding-2026-09.md.

Règles de la vague : pile linéaire (chaque PR part de la précédente) ; ne pas toucher CHANGELOG.md / CHANGELOG.fr.md avant #357 qui les centralise ; FR + EN pour toute clé i18n (.claude/rules/i18n.md) ; aucune migration DB ; aucune chaîne en dur dans les composants.

Objectif

Un profil sans transaction ouvre un tableau de bord qui dit quoi faire : état vide + liste de démarrage à la place des widgets à 0 $. Avec des transactions, la liste reste en tête en mode compact jusqu'à complète ou masquée.

Tâches

  • src/components/shared/EmptyState.tsx (composant pur, aucun hook) : props { icon, title, description, primaryAction?: { label, to } | { label, onClick, disabled? }, secondaryAction?, children? } ; la variante to rend un <Link> react-router, jamais useNavigate ; style repris de l'état vide actuel de SourceList.tsx:21-33 (carte en pointillés, icône centrée)
  • src/components/dashboard/OnboardingChecklist.tsx (pur, seul hook useTranslation) : props { items, done, total, mode: "expanded" | "compact", budgetReady, onHide } ; titre « Liste de démarrage », compteur « 3 / 6 » (ou « 3 / 5 ») ; six lignes case + libellé ; <Link> sur chaque case non cochée vers son to ; case budget.locked → cadenas + libellé « Base et plus » + lien /settings/users ; tant que budgetReady est faux : case budget neutre (ni cochée ni cadenassée) et compteur masqué ; bouton texte « Masquer » ; mode compact = cases sur une ligne horizontale avec compteur, sans phrases
  • src/components/dashboard/DashboardEmptyState.tsx : titre « Bienvenue dans Simpl'Résultat », phrase sur ce que la page montrera après import, OnboardingChecklist en mode étendu, bouton primaire « Choisir un dossier d'import » (<Link to="/import">)
  • DashboardPage.tsx : monter useOnboardingChecklist ; brancher sur status : loading → titre + PageHelp + CategoriesV1DiscoveryBanner seuls ; error → page v0.15.0 sans liste + logWarn(error) ; ready et counters.transactions === 0 → DashboardEmptyState rendu hors du <div className={isLoading ? "opacity-50 pointer-events-none" : ""}> de DashboardPage.tsx:62 ; ready et > 0 → page actuelle avec OnboardingChecklist compact entre le titre et le FilterPanel, seulement si ni hidden ni complete
  • src/pages/settings/UsersSettingsPage.tsx : dans la section Guide (:37-42), au-dessus de DocsContent, une ligne « Liste de démarrage sur le tableau de bord » + bouton « Afficher la liste de démarrage », visible seulement si la préférence vaut "1" (lecture au montage) ; clic → showChecklist() + confirmation inline « La liste réapparaîtra sur le tableau de bord »
  • Clés i18n FR + EN : dashboard.empty.*, onboarding.checklist.* (title, counter, hide, items.profile/importFolder/source/import/manualCategory/budget, lockedBudget), settings.users.onboarding.*

Fichiers concernés

  • src/components/shared/EmptyState.tsx (nouveau) + EmptyState.test.tsx (nouveau)
  • src/components/dashboard/OnboardingChecklist.tsx (nouveau) + OnboardingChecklist.test.tsx (nouveau)
  • src/components/dashboard/DashboardEmptyState.tsx (nouveau)
  • src/pages/DashboardPage.tsx
  • src/pages/settings/UsersSettingsPage.tsx
  • src/i18n/locales/fr.json, src/i18n/locales/en.json

Pattern de test des composants : src/components/reports/FilterPanel.test.tsx (appel direct de la fonction, react-i18next et lucide-react mockés, aucun hook React dans le composant testé). Vitest tourne en node, sans jsdom ni testing-library.

Depends on

Critères d'acceptation

  • Profil neuf : tableau de bord sans KPI ni graphique, liste 1/6 (1/5 en Free), bouton vers /import cliquable (pas de voile opacity-50)
  • Pendant status="loading", ni les widgets ni l'état vide ne sont rendus (pas de flash) ; en status="error", le tableau de bord actuel s'affiche sans liste
  • Avec des transactions et liste masquée ou complète : rendu identique à v0.15.0 (aucune carte supplémentaire)
  • OnboardingChecklist.test.tsx : cadenas en Free, case neutre et compteur absent quand budgetReady=false, mode compact, liens par case
  • EmptyState.test.tsx : variantes to (rend un Link) et onClick (bouton, disabled)
  • Bouton « Afficher la liste de démarrage » absent quand la préférence n'est pas posée, présent et fonctionnel sinon
  • npm test, npm run build verts ; grep sans chaîne en dur dans les nouveaux composants

Review caveats

  • (SECURITE + ARCHITECTURE + TECHNIQUE, résolu) Branche sur status, pas sur un compteur seul ; état vide hors du voile isLoading.
  • (TECHNIQUE, résolu) OnboardingChecklist et EmptyState sont purs pour rester testables par appel direct.

Décisions prises en planification

  • Case 5 de la liste = « une transaction classée à la main » (is_manually_categorized = 1) et non « règle créée » ni « transactions catégorisées » : le seed IPC met 180 mots-clés dans tout profil neuf et le wizard catégorise pendant l'import (useImportWizard.ts:1016).
  • Ordre des vagues : planned-2026-09-24-paiements s'exécute avant celle-ci (fichiers partagés : fr.json, en.json, CHANGELOG, architecture.md, guide-utilisateur.md) ; partir d'un main qui contient déjà ses clés.
  • Le tableau de bord ne consomme que counters.transactions du hook (une requête d'onboarding par montage) ; getTransactionCount est réservé aux pages sans liste.
  • useDashboard continue de lancer ses requêtes à base vide (coût accepté).

Spec source

spec-plan-onboarding-phase1.md (local, ignoré par git)

Vague `planned-2026-10-03-onboarding-phase1` (séance `/plan-run` du 2026-10-03, spec + `/review-spec` du 2026-09-25, verdict APPROUVÉ après intégration). Les fichiers `spec-decisions-onboarding-phase1.md` / `spec-plan-onboarding-phase1.md` sont **ignorés par git** : ce corps est auto-suffisant, ne pas chercher le spec. Analyse d'origine : `docs/analyse-onboarding-2026-09.md`. Règles de la vague : pile linéaire (chaque PR part de la précédente) ; **ne pas toucher `CHANGELOG.md` / `CHANGELOG.fr.md`** avant #357 qui les centralise ; FR + EN pour toute clé i18n (`.claude/rules/i18n.md`) ; aucune migration DB ; aucune chaîne en dur dans les composants. ## Objectif Un profil sans transaction ouvre un tableau de bord qui dit quoi faire : état vide + liste de démarrage à la place des widgets à 0 $. Avec des transactions, la liste reste en tête en mode compact jusqu'à complète ou masquée. ## Tâches - [ ] `src/components/shared/EmptyState.tsx` (composant **pur**, aucun hook) : props `{ icon, title, description, primaryAction?: { label, to } | { label, onClick, disabled? }, secondaryAction?, children? }` ; la variante `to` rend un `<Link>` react-router, jamais `useNavigate` ; style repris de l'état vide actuel de `SourceList.tsx:21-33` (carte en pointillés, icône centrée) - [ ] `src/components/dashboard/OnboardingChecklist.tsx` (pur, seul hook `useTranslation`) : props `{ items, done, total, mode: "expanded" | "compact", budgetReady, onHide }` ; titre « Liste de démarrage », compteur « 3 / 6 » (ou « 3 / 5 ») ; six lignes case + libellé ; `<Link>` sur chaque case non cochée vers son `to` ; case `budget.locked` → cadenas + libellé « Base et plus » + lien `/settings/users` ; tant que `budgetReady` est faux : case budget neutre (ni cochée ni cadenassée) et compteur masqué ; bouton texte « Masquer » ; mode compact = cases sur une ligne horizontale avec compteur, sans phrases - [ ] `src/components/dashboard/DashboardEmptyState.tsx` : titre « Bienvenue dans Simpl'Résultat », phrase sur ce que la page montrera après import, `OnboardingChecklist` en mode étendu, bouton primaire « Choisir un dossier d'import » (`<Link to="/import">`) - [ ] `DashboardPage.tsx` : monter `useOnboardingChecklist` ; brancher sur `status` : `loading` → titre + `PageHelp` + `CategoriesV1DiscoveryBanner` seuls ; `error` → page v0.15.0 sans liste + `logWarn(error)` ; `ready` et `counters.transactions === 0` → `DashboardEmptyState` rendu **hors** du `<div className={isLoading ? "opacity-50 pointer-events-none" : ""}>` de `DashboardPage.tsx:62` ; `ready` et `> 0` → page actuelle avec `OnboardingChecklist` compact entre le titre et le `FilterPanel`, seulement si ni `hidden` ni `complete` - [ ] `src/pages/settings/UsersSettingsPage.tsx` : dans la section Guide (`:37-42`), au-dessus de `DocsContent`, une ligne « Liste de démarrage sur le tableau de bord » + bouton « Afficher la liste de démarrage », visible seulement si la préférence vaut `"1"` (lecture au montage) ; clic → `showChecklist()` + confirmation inline « La liste réapparaîtra sur le tableau de bord » - [ ] Clés i18n FR + EN : `dashboard.empty.*`, `onboarding.checklist.*` (title, counter, hide, items.profile/importFolder/source/import/manualCategory/budget, lockedBudget), `settings.users.onboarding.*` ## Fichiers concernés - `src/components/shared/EmptyState.tsx` (nouveau) + `EmptyState.test.tsx` (nouveau) - `src/components/dashboard/OnboardingChecklist.tsx` (nouveau) + `OnboardingChecklist.test.tsx` (nouveau) - `src/components/dashboard/DashboardEmptyState.tsx` (nouveau) - `src/pages/DashboardPage.tsx` - `src/pages/settings/UsersSettingsPage.tsx` - `src/i18n/locales/fr.json`, `src/i18n/locales/en.json` Pattern de test des composants : `src/components/reports/FilterPanel.test.tsx` (appel direct de la fonction, `react-i18next` et `lucide-react` mockés, aucun hook React dans le composant testé). Vitest tourne en node, sans jsdom ni testing-library. ## Depends on - #351 ## Critères d'acceptation - [ ] Profil neuf : tableau de bord sans KPI ni graphique, liste 1/6 (1/5 en Free), bouton vers `/import` cliquable (pas de voile `opacity-50`) - [ ] Pendant `status="loading"`, ni les widgets ni l'état vide ne sont rendus (pas de flash) ; en `status="error"`, le tableau de bord actuel s'affiche sans liste - [ ] Avec des transactions et liste masquée ou complète : rendu identique à v0.15.0 (aucune carte supplémentaire) - [ ] `OnboardingChecklist.test.tsx` : cadenas en Free, case neutre et compteur absent quand `budgetReady=false`, mode compact, liens par case - [ ] `EmptyState.test.tsx` : variantes `to` (rend un `Link`) et `onClick` (bouton, `disabled`) - [ ] Bouton « Afficher la liste de démarrage » absent quand la préférence n'est pas posée, présent et fonctionnel sinon - [ ] `npm test`, `npm run build` verts ; `grep` sans chaîne en dur dans les nouveaux composants ## Review caveats - (SECURITE + ARCHITECTURE + TECHNIQUE, résolu) Branche sur `status`, pas sur un compteur seul ; état vide hors du voile `isLoading`. - (TECHNIQUE, résolu) `OnboardingChecklist` et `EmptyState` sont purs pour rester testables par appel direct. ## Décisions prises en planification - Case 5 de la liste = « une transaction classée à la main » (`is_manually_categorized = 1`) et non « règle créée » ni « transactions catégorisées » : le seed IPC met 180 mots-clés dans tout profil neuf et le wizard catégorise pendant l'import (`useImportWizard.ts:1016`). - Ordre des vagues : `planned-2026-09-24-paiements` s'exécute **avant** celle-ci (fichiers partagés : `fr.json`, `en.json`, CHANGELOG, `architecture.md`, `guide-utilisateur.md`) ; partir d'un `main` qui contient déjà ses clés. - Le tableau de bord ne consomme que `counters.transactions` du hook (une requête d'onboarding par montage) ; `getTransactionCount` est réservé aux pages sans liste. - `useDashboard` continue de lancer ses requêtes à base vide (coût accepté). ## Spec source spec-plan-onboarding-phase1.md (local, ignoré par git)
maximus added this to the planned-2026-10-03-onboarding-phase1 milestone 2026-09-26 12:24:30 +00:00
maximus added the
status:ready
type:feature
source:human
labels 2026-09-26 12:24:30 +00:00
maximus changed title from Onboarding: dashboard empty state, getting-started checklist and re-show button in Settings to Onboarding : état vide du tableau de bord, liste de démarrage et bouton de réaffichage dans Paramètres 2026-10-03 14:09:44 +00:00
maximus added
status:in-progress
and removed
status:ready
labels 2026-10-03 23:27:39 +00:00
maximus added
status:review
and removed
status:in-progress
labels 2026-10-03 23:33:31 +00:00
maximus added
status:approved
and removed
status:review
labels 2026-10-03 23:35:09 +00:00
maximus removed the
status:approved
label 2026-10-04 12:52:51 +00:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#352
No description provided.