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
@@ -1,6 +1,7 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { useAssignments, usePositions, useShifts, useVolunteers } from '@/api/hooks';
|
||||
import { useAuth } from '@/auth/auth-context';
|
||||
import { ErrorNote, Loading } from '@/components/state';
|
||||
import { DesignNote, PhoneFrame } from '@/pages/mobile/PhoneFrame';
|
||||
import { hourRangeLabel } from '@/lib/time';
|
||||
@@ -11,13 +12,17 @@ import { cx } from '@/lib/cx';
|
||||
type Presence = Record<string, 'present' | 'absent'>;
|
||||
|
||||
export function MobileLeadPage() {
|
||||
const { account } = useAuth();
|
||||
const positions = usePositions();
|
||||
const shifts = useShifts();
|
||||
const volunteers = useVolunteers();
|
||||
const [presence, setPresence] = useState<Presence>({});
|
||||
|
||||
// Poste de démonstration : le premier ; créneau le plus fourni.
|
||||
const position = (positions.data ?? [])[0];
|
||||
// Poste du référent connecté (repli : le premier, pour la démo coordination).
|
||||
const myPositions = (positions.data ?? []).filter(
|
||||
(p) => account && p.lead_account_id === account.id,
|
||||
);
|
||||
const position = myPositions[0] ?? (positions.data ?? [])[0];
|
||||
const positionShifts = useMemo(
|
||||
() => (shifts.data ?? []).filter((s) => s.position_id === position?.id),
|
||||
[shifts.data, position?.id],
|
||||
|
||||
Reference in New Issue
Block a user