- Nouveau service `frontend` (build ./frontend, Vite --host sur 5173, bind mount + volume nommé frontend_node_modules, depends_on backend). - VITE_API_MODE=mock par défaut (aucun backend requis) ; VITE_API_TARGET pointe sur le service backend pour le mode http. - .env.example : VITE_API_MODE / VITE_EDITION_ID. - frontend/.dockerignore ; README : URL http://localhost:5173. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AwswqSChc3Rwtu61pRXiY2
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.
É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 |
PATCH /assignments/{id} (confirmer) |
| 05 | /mobile-referent |
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. |
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
│ ├── types.ts # interface PlanningApi + ApiError
│ ├── http-client.ts # implémentation HTTP
│ ├── mock/ # implémentation mémoire (dataset + client + moteur)
│ ├── index.ts # sélection mock / http, EDITION_ID
│ └── hooks.ts # hooks React Query (lectures + mutations)
├── app/ AppShell (onglets) · router
├── pages/ un fichier par écran (+ 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