Files
benevoles/frontend
AdamThomasandClaude Sonnet 5 6e16db4b7e Frontend : connexion (mot de passe + lien magique) et onglets par rôle
Authentification alignée sur le back-end (Étapes 7/8) :
- src/api : schema auth (AccountRead, TokenResponse…), session.ts (jeton
  Bearer partagé + callback 401), méthodes auth du client HTTP
  (POST .../auth/login, .../auth/magic-link, .../auth/verify, GET /auth/me)
  et du mock (comptes coordination + référents + bénévoles, tokens magiques,
  sessions).
- src/auth : AuthProvider/useAuth (jeton en localStorage, réhydratation via
  /auth/me, déconnexion sur 401), RequireAuth (garde + contrôle de rôle),
  HomeRedirect, table ROUTE_ROLES.
- Pages : /connexion (lien magique, avec lien de démo affiché en mode mock),
  /connexion/coordination (email + mot de passe).
- Router : toutes les routes métier passées derrière <RequireAuth> ;
  redirection vers l'accueil du rôle.
- AppShell : onglets filtrés par rôle (01/02/03/06 coordination, 04 bénévole,
  05 référent), email + rôle + bouton Déconnexion.
- Mobile bénévole : cible le bénévole du compte connecté ; dégradation
  propre quand l'API refuse le détail des créneaux à un bénévole.
- Mobile référent : cible le poste dont le compte est référent.
- i18n : clés auth / rôles.
- Vérifs : build tsc + vite, eslint (0 problème), npm run smoke (flux
  login / lien magique + rendu des 6 écrans par rôle et des pages publiques).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwswqSChc3Rwtu61pRXiY2
2026-09-10 07:43:00 +02:00
..

Frontend — Gestion des bénévoles

React + Vite + TypeScript + Tailwind. Interface en français, code en anglais.

Intègre le design Claude Design « Bénévoles Festival » et consomme l'API back-end (editions/{id}/volunteers · positions · shifts · assignments · assignments/validate · matrix).

Modes de données

VITE_API_MODE (voir .env.example) :

  • mock (défaut) — jeu de démonstration déterministe en mémoire, implémenté avec exactement la même surface que l'API (src/api/mock/). Aucun back-end requis ; utile tant que le seed serveur n'existe pas.
  • http — API réelle. VITE_EDITION_ID désigne l'édition ; en dev Vite proxifie /api vers VITE_API_TARGET (défaut http://localhost:8000).

Le passage d'un mode à l'autre ne change aucun écran : tout passe par src/api/ (client HTTP ou mock) et les hooks React Query de src/api/hooks.ts.

Authentification & rôles

Toutes les pages métier sont derrière <RequireAuth> (src/auth/).

  • Coordination → /connexion/coordination : email + mot de passe (POST /editions/{id}/auth/login).
  • Référents / bénévoles → /connexion : lien magique (POST …/auth/magic-link puis …/auth/verify). L'email étant stubé, le mode mock affiche directement le lien de démo à cliquer.
  • Le jeton JWT est stocké en localStorage, envoyé en Authorization: Bearer sur chaque requête ; une réponse 401 déconnecte.
  • Comptes de démo (mode mock) : coordination coordination@lessonsdautomne.fr / demo ; référents referent1..3@lessonsdautomne.fr ; chaque bénévole ayant un email.

Visibilité des onglets par rôle :

Onglet Coordination Référent Bénévole
01 Grille · 02 Vue bénévole · 03 Confirmations · 06 Configuration ✅ — —
04 Bénévole · mobile — — ✅
05 Référent · mobile — ✅ —

L'accueil après connexion dépend du rôle (homePath).

Écrans (onglets)

# Route Source de données Actions
01 /grille GET /matrix clic cellule → panneau : GET /assignments?shift_id, POST /assignments/validate par candidat, POST / PATCH / DELETE /assignments
02 /benevoles volunteers + shifts + assignments lecture (surcharge / oubliés calculés côté client)
03 /publication assignments (statut PROPOSED) lecture — publication versionnée & emails hors périmètre (CLAUDE.md §4)
04 /mobile-benevole assignments?volunteer_id (du compte) PATCH /assignments/{id} (confirmer)¹
05 /mobile-referent poste du référent → assignments?shift_id pointage local (hors périmètre)
06 /configuration positions CRUD, shifts CRUD (min/idéal, ajout/retrait), volunteers CRUD (dont suppression RGPD). Messages = maquette locale.

¹ En mode http, l'API n'expose pas encore aux bénévoles le détail des créneaux ni l'auto-confirmation : l'écran dégrade proprement (créneaux sans détail, message d'info). Fonctionne intégralement en mode mock.

Commandes

Action Commande
Installer npm install
Dev npm run dev → http://localhost:5173
Build npm run build
Lint npm run lint
Types npm run typecheck
Rendu headless + vérifs API mock npm run smoke

Conventions

  • Aucun texte d'interface en dur : src/i18n (t(key, params)) + locales/fr.json.
  • Les libellés de données (nom de poste, etc.) viennent de l'API.
  • src/api/schema.ts est le miroir de backend/app/api/schemas.py — à garder synchrone.
  • violationText() (src/lib/planning.ts) rend les violations du moteur ; les params suivent le contrat de backend/app/validation/engine.py.
  • Alias @/ → src/.

Arborescence

src/
├── main.tsx
├── api/
│   ├── schema.ts            # types miroir du back-end (dont auth)
│   ├── types.ts             # interface PlanningApi + ApiError
│   ├── session.ts           # jeton Bearer partagé + callback 401
│   ├── http-client.ts       # implémentation HTTP
│   ├── mock/                # implémentation mémoire (dataset + client + comptes + moteur)
│   ├── index.ts             # sélection mock / http, EDITION_ID
│   └── hooks.ts             # hooks React Query (lectures + mutations)
├── auth/           auth-context (AuthProvider/useAuth) · RequireAuth · roles
├── app/            AppShell (onglets filtrés par rôle) · router
├── pages/          un fichier par écran (+ auth/, grille/, config/, mobile/)
├── components/     ui.tsx (primitives) · state.tsx (Loading / ErrorNote)
├── lib/            time.ts · planning.ts (treillis, heures, surcharge, violationText) · env.ts · cx.ts
└── i18n/           t() + locales/fr.json