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
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
464635656a
commit
6e16db4b7e
+37
-6
@@ -19,6 +19,31 @@ assignments/validate · matrix`).
|
||||
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 |
|
||||
@@ -26,10 +51,14 @@ Le passage d'un mode à l'autre ne change **aucun** écran : tout passe par
|
||||
| 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) |
|
||||
| 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 |
|
||||
@@ -56,14 +85,16 @@ Le passage d'un mode à l'autre ne change **aucun** écran : tout passe par
|
||||
src/
|
||||
├── main.tsx
|
||||
├── api/
|
||||
│ ├── schema.ts # types miroir du back-end
|
||||
│ ├── 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 + moteur)
|
||||
│ ├── mock/ # implémentation mémoire (dataset + client + comptes + 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/)
|
||||
├── 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
|
||||
|
||||
Reference in New Issue
Block a user