Compare commits

...

7 Commits

Author SHA1 Message Date
930097f87d Merge develop: fix auth connexion admin (#84)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 22:37:48 +01:00
18af5c9034 fix(auth): connexion admin - token snake_case, routes GoRouter, profil (Closes #84)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-09 22:36:52 +01:00
480f4a9396 fix(login): position formulaire sous slogan par ratio image (river_logo_mobile)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 18:53:37 +01:00
813fdb8449 fix(#83): Corriger le style du bouton Précédent et ajuster les tailles d'icônes
Utilise CustomNavigationButton avec HoverReliefWidget pour le bouton Précédent en mode mobile, assurant la cohérence visuelle avec les autres écrans. Augmente également la taille des icônes de choix (140px mobile, 170px desktop).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 12:33:48 +01:00
155c6ca4d5 chore(deps): Update pubspec.lock
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 11:44:47 +01:00
030ef81038 feat(frontend): Adapt RegisterChoiceScreen for mobile (Closes #83)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 17:43:17 +01:00
0d88597bb6 test
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-07 17:42:09 +01:00
5 changed files with 64 additions and 16 deletions

View File

@ -33,6 +33,31 @@ Correspondance entre les numéros dissues Gitea et les tickets de ce document
--- ---
## 🔗 Liste des tickets Gitea
Correspondance entre les numéros dissues Gitea et les tickets de ce document.
| Gitea # | Titre court | Priorité | Statut | Section doc |
|--------|--------------|----------|--------|-------------|
| 1 | BDD - Champs manquants CDC | P0 | Ouvert | § Ticket #1 |
| 2 | BDD - Table présentation dossier parent | P0 | Ouvert | § Ticket #2 |
| 3 | BDD - Tokens création MDP | P0 | ✅ Fermé | § Ticket #3 |
| 4 | BDD - Champ genre enfants | P0 | ✅ Fermé | § Ticket #4 |
| 5 | BDD - Supprimer champs obsolètes | P0 | Ouvert | § Ticket #5 |
| 6 | BDD - Table configuration système | P0 | Ouvert | § Ticket #6 |
| 68 | BDD - Documents légaux & acceptations | P0 | ✅ Fermé | § Ticket #7 |
| 73 | Frontend - Inscription Parent Étape 1 | P3 | ✅ Fermé (PR) | § Ticket #36 |
| 78 | Frontend - Infrastructure formulaires multi-modes | P3 | ✅ Fermé | § Ticket #78 |
| 79 | Frontend - Renommer Nanny en AM | P3 | ✅ Fermé | § Ticket #79 |
| 81 | Frontend - Corrections refactoring widgets | P3 | ✅ Fermé | § Ticket #81 |
| 83 | Frontend - RegisterChoiceScreen mobile | P3 | ✅ Fermé | § Ticket #83 |
*Les autres tickets (sans numéro Gitea dans ce tableau) sont décrits dans les sections par priorité cidessous ; les numéros de section (#1 à #83) sont les références internes du document.*
**Point API (tickets frontend)** 27/01/2026 : 20 issues avec le label `frontend` dans Gitea (12 ouvertes, 8 fermées). Numéros concernés : 3542, 4351, 54, 82, 83. Les #73, #78, #79, #81 sont fermés mais sans label dans lAPI. Détail : `docs/POINT_TICKETS_FRONT_API.txt`.
---
## 📊 Vue d'ensemble ## 📊 Vue d'ensemble
### Répartition par priorité ### Répartition par priorité

View File

@ -19,6 +19,8 @@ import '../screens/auth/am_register_step2_screen.dart';
import '../screens/auth/am_register_step3_screen.dart'; import '../screens/auth/am_register_step3_screen.dart';
import '../screens/auth/am_register_step4_screen.dart'; import '../screens/auth/am_register_step4_screen.dart';
import '../screens/home/home_screen.dart'; import '../screens/home/home_screen.dart';
import '../screens/administrateurs/admin_dashboardScreen.dart';
import '../screens/home/parent_screen/ParentDashboardScreen.dart';
import '../screens/unknown_screen.dart'; import '../screens/unknown_screen.dart';
// --- Provider Instances --- // --- Provider Instances ---
@ -47,6 +49,18 @@ class AppRouter {
path: '/home', path: '/home',
builder: (BuildContext context, GoRouterState state) => const HomeScreen(), builder: (BuildContext context, GoRouterState state) => const HomeScreen(),
), ),
GoRoute(
path: '/admin-dashboard',
builder: (BuildContext context, GoRouterState state) => const AdminDashboardScreen(),
),
GoRoute(
path: '/parent-dashboard',
builder: (BuildContext context, GoRouterState state) => const ParentDashboardScreen(),
),
GoRoute(
path: '/am-dashboard',
builder: (BuildContext context, GoRouterState state) => const HomeScreen(),
),
// --- Parent Registration Flow --- // --- Parent Registration Flow ---
ShellRoute( ShellRoute(

View File

@ -20,8 +20,12 @@ class AppUser {
id: json['id'] as String, id: json['id'] as String,
email: json['email'] as String, email: json['email'] as String,
role: json['role'] as String, role: json['role'] as String,
createdAt: DateTime.parse(json['createdAt'] as String), createdAt: json['createdAt'] != null
updatedAt: DateTime.parse(json['updatedAt'] as String), ? DateTime.parse(json['createdAt'] as String)
: DateTime.now(),
updatedAt: json['updatedAt'] != null
? DateTime.parse(json['updatedAt'] as String)
: DateTime.now(),
changementMdpObligatoire: json['changement_mdp_obligatoire'] as bool? ?? false, changementMdpObligatoire: json['changement_mdp_obligatoire'] as bool? ?? false,
); );
} }

View File

@ -116,21 +116,23 @@ class _LoginPageState extends State<LoginScreen> with WidgetsBindingObserver {
} }
} }
/// Redirige l'utilisateur selon son rôle /// Redirige l'utilisateur selon son rôle (GoRouter : context.go).
void _redirectUserByRole(String role) { void _redirectUserByRole(String role) {
setState(() => _isLoading = false);
switch (role.toLowerCase()) { switch (role.toLowerCase()) {
case 'super_admin': case 'super_admin':
case 'administrateur':
case 'gestionnaire': case 'gestionnaire':
Navigator.pushReplacementNamed(context, '/admin-dashboard'); context.go('/admin-dashboard');
break; break;
case 'parent': case 'parent':
Navigator.pushReplacementNamed(context, '/parent-dashboard'); context.go('/parent-dashboard');
break; break;
case 'assistante_maternelle': case 'assistante_maternelle':
Navigator.pushReplacementNamed(context, '/am-dashboard'); context.go('/am-dashboard');
break; break;
default: default:
Navigator.pushReplacementNamed(context, '/home'); context.go('/home');
} }
} }

View File

@ -23,13 +23,15 @@ class AuthService {
if (response.statusCode == 200 || response.statusCode == 201) { if (response.statusCode == 200 || response.statusCode == 201) {
final data = jsonDecode(response.body); final data = jsonDecode(response.body);
// API renvoie access_token / refresh_token (snake_case)
// Stocker les tokens final accessToken = data['access_token'] as String? ?? data['accessToken'] as String?;
await TokenService.saveToken(data['accessToken']); final refreshToken = data['refresh_token'] as String? ?? data['refreshToken'] as String?;
await TokenService.saveRefreshToken(data['refreshToken']); if (accessToken == null) throw Exception('Token absent dans la réponse serveur');
// Récupérer le profil utilisateur pour avoir toutes les infos await TokenService.saveToken(accessToken);
final user = await _fetchUserProfile(data['accessToken']); await TokenService.saveRefreshToken(refreshToken ?? '');
final user = await _fetchUserProfile(accessToken);
// Stocker l'utilisateur en cache // Stocker l'utilisateur en cache
await _saveCurrentUser(user); await _saveCurrentUser(user);
@ -80,8 +82,9 @@ class AuthService {
Uri.parse('${ApiConfig.baseUrl}${ApiConfig.changePasswordRequired}'), Uri.parse('${ApiConfig.baseUrl}${ApiConfig.changePasswordRequired}'),
headers: ApiConfig.authHeaders(token), headers: ApiConfig.authHeaders(token),
body: jsonEncode({ body: jsonEncode({
'currentPassword': currentPassword, 'mot_de_passe_actuel': currentPassword,
'newPassword': newPassword, 'nouveau_mot_de_passe': newPassword,
'confirmation_mot_de_passe': newPassword,
}), }),
); );