feat(admin): validation AM/famille, À valider au survol, nettoyage logs

- À valider : ligne avec survol type AdminUserCard, icône Ouvrir centrée et plus grande (iconSize 34).
- Wizard AM : titres Identité et coordonnées / Dossier professionnel / Présentation ; photo à gauche, grille droite [2,2,2,2] (NIR, naissance, agrément, capacité) ; AppUser champs naissance ; dates dd/MM/yyyy via formatIsoDateFr ; ValidationDetailSection titre optionnel.
- Wizard famille : titre étape 4 « Présentation ».
- Suppression des debugPrint liés médias / images / dossier (api_config, auth_network_image, dossier_unifie, user_service, validation_family).

Made-with: Cursor
This commit is contained in:
2026-04-13 17:22:08 +02:00
parent f442c85cb6
commit 0befd4eb2a
10 changed files with 212 additions and 199 deletions
+1 -14
View File
@@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:p_tits_pas/config/env.dart';
class ApiConfig {
@@ -21,26 +20,14 @@ class ApiConfig {
/// On préfixe avec [baseUrl] (…/api/v1), pas seulement lhôte : Traefik nexpose souvent que `/api`.
static String absoluteMediaUrl(String? pathOrUrl) {
if (pathOrUrl == null || pathOrUrl.trim().isEmpty) {
if (kDebugMode) {
debugPrint('[PetitsPas/media] absoluteMediaUrl: entrée vide (null ou "")');
}
return '';
}
final u = pathOrUrl.trim();
if (u.startsWith('http://') || u.startsWith('https://')) {
if (kDebugMode) {
debugPrint('[PetitsPas/media] absoluteMediaUrl: déjà absolu → $u');
}
return u;
}
final base = baseUrl.replaceAll(RegExp(r'/+$'), '');
final out = u.startsWith('/') ? '$base$u' : '$base/$u';
if (kDebugMode) {
debugPrint(
'[PetitsPas/media] absoluteMediaUrl: base=$base | chemin brut="$u" → "$out"',
);
}
return out;
return u.startsWith('/') ? '$base$u' : '$base/$u';
}
// Auth endpoints
-17
View File
@@ -1,5 +1,4 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:p_tits_pas/models/user.dart';
import 'package:p_tits_pas/models/parent_model.dart';
@@ -94,9 +93,6 @@ class UserService {
static Future<DossierUnifie> getDossier(String numeroDossier) async {
final encoded = Uri.encodeComponent(numeroDossier);
final uri = Uri.parse('${ApiConfig.baseUrl}${ApiConfig.dossiers}/$encoded');
if (kDebugMode) {
debugPrint('[PetitsPas/dossier] GET $uri');
}
final response = await http.get(
uri,
headers: await _headers(),
@@ -119,19 +115,6 @@ class UserService {
throw FormatException('Réponse invalide');
}
final dossier = DossierUnifie.fromJson(Map<String, dynamic>.from(decoded));
if (kDebugMode) {
debugPrint(
'[PetitsPas/dossier] réponse OK type=${dossier.type} | '
'ApiConfig.baseUrl=${ApiConfig.baseUrl} | apiOrigin=${ApiConfig.apiOrigin}',
);
if (dossier.isFamily) {
final f = dossier.asFamily;
debugPrint(
'[PetitsPas/dossier] famille ${f.numeroDossier} | '
'${f.enfants.length} enfant(s)',
);
}
}
return dossier;
} catch (e) {
if (e is FormatException) rethrow;