Créateur de badges refait d'après la maquette : champs sur le recto et le verso (BadgeField.face, verso placé en miroir dans le PDF pour le recto-verso), fond de zone, réduction automatique du texte, photo ovale, initiales sans photo, nom sur deux lignes (migration 0026) ; éditeur en trois colonnes (champs, aperçu recto/verso avec de vrais bénévoles, inspecteur), formats prédéfinis, annuler, flèches, zoom, repères de découpe, dépôt d'image sur l'aperçu, contrôle de tous les badges avant génération. Nombre de badges par bénévole (Volunteer.badge_count, 1 par défaut, migration 0027) : champ sur la fiche, autant d'exemplaires sur les planches, total affiché à la génération, colonne dans l'export Excel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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_IDdésigne l'édition ; en dev Vite proxifie/apiversVITE_API_TARGET(défauthttp://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-linkpuis…/auth/verify). L'email étant stubé, le modemockaffiche directement le lien de démo à cliquer. - Le jeton JWT est stocké en
localStorage, envoyé enAuthorization: Bearersur chaque requête ; une réponse 401 déconnecte. - Comptes de démo (mode
mock) : coordinationcoordination@lessonsdautomne.fr/demo; référentsreferent1..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 · 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)
Depuis l'Étape 9 back-end, une affectation n'a plus de statut : elle est valide dès sa création, la retirer = supprimer la ligne. Il n'y a donc plus d'écran « Confirmations » (ancien onglet 03).
| # | Route | Source de données | Actions |
|---|---|---|---|
| 01 | /grille |
GET /matrix (assigned / ideal) |
clic cellule → panneau : GET /assignments?shift_id, POST /assignments/validate par candidat, POST / DELETE /assignments |
| 02 | /benevoles |
volunteers + shifts + assignments |
lecture (surcharge / oubliés calculés côté client) |
| 04 | /mobile-benevole |
assignments?volunteer_id (du compte) |
lecture¹ |
| 05 | /mobile-referent |
poste du référent → assignments?shift_id |
pointage local (hors périmètre) |
| 06 | /configuration |
positions · shifts · volunteers |
CRUD postes / créneaux (min/idéal) / bénévoles (dont suppression RGPD) ; onglet Messages → POST /notifications/planning (récapitulatif + lien de connexion) |
¹ En mode http, l'API n'expose pas encore aux bénévoles le détail des
créneaux : 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.tsest le miroir debackend/app/api/schemas.py— à garder synchrone.violationText()(src/lib/planning.ts) rend les violations du moteur ; lesparamssuivent le contrat debackend/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