# 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`. ## É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.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 │ ├── 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 ```