fix(#112): préremplissage AM complet en reprise + lien login repositionné
Parse dates/places/consentement de façon robuste, rafraîchit l'étape 2 AM et place « J'ai un numéro de dossier » sous « Créer un compte ». Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
9d54d9b19b
commit
c26ed00374
@ -1,4 +1,5 @@
|
||||
import 'package:p_tits_pas/models/dossier_unifie.dart';
|
||||
import 'package:p_tits_pas/utils/reprise_mapper.dart';
|
||||
|
||||
/// Réponse GET /auth/reprise-dossier. Tickets #111, #112.
|
||||
class RepriseDossier {
|
||||
@ -20,7 +21,7 @@ class RepriseDossier {
|
||||
final List<EnfantDossier> enfants;
|
||||
final String? texteMotivation;
|
||||
|
||||
final bool? consentementPhoto;
|
||||
final bool consentementPhoto;
|
||||
final String? dateNaissance;
|
||||
final String? lieuNaissanceVille;
|
||||
final String? lieuNaissancePays;
|
||||
@ -48,7 +49,7 @@ class RepriseDossier {
|
||||
this.parents = const [],
|
||||
this.enfants = const [],
|
||||
this.texteMotivation,
|
||||
this.consentementPhoto,
|
||||
this.consentementPhoto = false,
|
||||
this.dateNaissance,
|
||||
this.lieuNaissanceVille,
|
||||
this.lieuNaissancePays,
|
||||
@ -80,9 +81,6 @@ class RepriseDossier {
|
||||
.toList()
|
||||
: <EnfantDossier>[];
|
||||
|
||||
final nbMax = json['nb_max_enfants'];
|
||||
final places = json['place_disponible'];
|
||||
|
||||
return RepriseDossier(
|
||||
id: json['id']?.toString() ?? '',
|
||||
email: json['email']?.toString() ?? '',
|
||||
@ -101,17 +99,22 @@ class RepriseDossier {
|
||||
enfants: enfantsList,
|
||||
texteMotivation: (json['texte_motivation'] ?? json['presentation_dossier'])
|
||||
?.toString(),
|
||||
consentementPhoto: json['consentement_photo'] == true,
|
||||
dateNaissance: json['date_naissance']?.toString(),
|
||||
consentementPhoto: RepriseMapper.optionalBool(json['consentement_photo']) ||
|
||||
RepriseMapper.optionalBool(json['consent_photo']),
|
||||
dateNaissance: RepriseMapper.optionalDateString(json['date_naissance']),
|
||||
lieuNaissanceVille: json['lieu_naissance_ville']?.toString(),
|
||||
lieuNaissancePays: json['lieu_naissance_pays']?.toString(),
|
||||
numeroAgrement: json['numero_agrement']?.toString(),
|
||||
numeroAgrement: (json['numero_agrement'] ?? json['numero_agrement_am'])
|
||||
?.toString(),
|
||||
nir: json['nir']?.toString(),
|
||||
dateAgrement: json['date_agrement']?.toString(),
|
||||
nbMaxEnfants: nbMax is int ? nbMax : (nbMax is num ? nbMax.toInt() : null),
|
||||
placeDisponible:
|
||||
places is int ? places : (places is num ? places.toInt() : null),
|
||||
biographie: json['biographie']?.toString(),
|
||||
dateAgrement: RepriseMapper.optionalDateString(json['date_agrement']),
|
||||
nbMaxEnfants: RepriseMapper.optionalInt(
|
||||
json['nb_max_enfants'] ?? json['capacite_accueil'],
|
||||
),
|
||||
placeDisponible: RepriseMapper.optionalInt(
|
||||
json['place_disponible'] ?? json['places_disponibles'],
|
||||
),
|
||||
biographie: (json['biographie'] ?? json['presentation'])?.toString(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,12 @@ class AmRegisterStep2Screen extends StatelessWidget {
|
||||
);
|
||||
|
||||
return ProfessionalInfoFormScreen(
|
||||
key: ValueKey(
|
||||
'am-pro-${registrationData.dateOfBirth?.millisecondsSinceEpoch}'
|
||||
'-${registrationData.agreementDate?.millisecondsSinceEpoch}'
|
||||
'-${registrationData.placesAvailable}'
|
||||
'-${registrationData.nir}',
|
||||
),
|
||||
stepText: 'Étape 2/4',
|
||||
title: 'Vos informations professionnelles',
|
||||
cardColor: CardColorHorizontal.green,
|
||||
|
||||
@ -377,8 +377,6 @@ class _LoginPageState extends State<LoginScreen> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Center(child: _buildRepriseDossierLink()),
|
||||
const SizedBox(height: 10),
|
||||
// Lien mot de passe oublié
|
||||
Center(
|
||||
child: TextButton(
|
||||
@ -412,6 +410,7 @@ class _LoginPageState extends State<LoginScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
Center(child: _buildRepriseDossierLink()),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -645,7 +644,6 @@ class _LoginPageState extends State<LoginScreen> {
|
||||
onPressed: _handleLogin,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildRepriseDossierLink(),
|
||||
TextButton(
|
||||
onPressed: () => context.go('/forgot-password'),
|
||||
child: Text(
|
||||
@ -669,6 +667,7 @@ class _LoginPageState extends State<LoginScreen> {
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildRepriseDossierLink(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -53,26 +53,6 @@ class RepriseSession {
|
||||
}
|
||||
|
||||
static void applyToAm(AmRegistrationData data, RepriseDossier dossier) {
|
||||
final displayPhoto = _photoUrl;
|
||||
data.resetForReprise(
|
||||
firstName: dossier.prenom ?? '',
|
||||
lastName: dossier.nom ?? '',
|
||||
phone: dossier.telephone ?? '',
|
||||
email: dossier.email,
|
||||
streetAddress: dossier.adresse ?? '',
|
||||
postalCode: dossier.codePostal ?? '',
|
||||
city: dossier.ville ?? '',
|
||||
existingPhotoUrl: displayPhoto,
|
||||
consentementPhoto: dossier.consentementPhoto ?? false,
|
||||
dateOfBirth: RepriseMapper.parseIsoDate(dossier.dateNaissance),
|
||||
birthCity: dossier.lieuNaissanceVille ?? '',
|
||||
birthCountry: dossier.lieuNaissancePays ?? '',
|
||||
nir: dossier.nir ?? '',
|
||||
agrementNumber: dossier.numeroAgrement ?? '',
|
||||
agreementDate: RepriseMapper.parseIsoDate(dossier.dateAgrement),
|
||||
capacity: dossier.nbMaxEnfants,
|
||||
placesAvailable: dossier.placeDisponible,
|
||||
presentationText: dossier.biographie ?? '',
|
||||
);
|
||||
RepriseMapper.applyAmDossier(data, dossier);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'package:p_tits_pas/models/am_registration_data.dart';
|
||||
import 'package:p_tits_pas/models/card_assets.dart';
|
||||
import 'package:p_tits_pas/models/dossier_unifie.dart';
|
||||
import 'package:p_tits_pas/models/reprise_dossier.dart';
|
||||
@ -106,13 +107,79 @@ class RepriseMapper {
|
||||
|
||||
static DateTime? parseIsoDate(String? raw) {
|
||||
if (raw == null || raw.trim().isEmpty) return null;
|
||||
final s = raw.trim();
|
||||
try {
|
||||
return DateTime.parse(raw.trim());
|
||||
return DateTime.parse(s);
|
||||
} catch (_) {
|
||||
final parts = s.split('/');
|
||||
if (parts.length == 3) {
|
||||
final day = int.tryParse(parts[0]);
|
||||
final month = int.tryParse(parts[1]);
|
||||
final year = int.tryParse(parts[2]);
|
||||
if (day != null && month != null && year != null) {
|
||||
return DateTime(year, month, day);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static String? optionalDateString(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is String) {
|
||||
final s = value.trim();
|
||||
return s.isEmpty ? null : s;
|
||||
}
|
||||
if (value is DateTime) return value.toIso8601String();
|
||||
return null;
|
||||
}
|
||||
|
||||
static int? optionalInt(dynamic value) {
|
||||
if (value == null) return null;
|
||||
if (value is int) return value;
|
||||
if (value is num) return value.toInt();
|
||||
if (value is String) {
|
||||
final s = value.trim();
|
||||
if (s.isEmpty) return null;
|
||||
return int.tryParse(s);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool optionalBool(dynamic value) {
|
||||
if (value == true) return true;
|
||||
if (value is String && value.toLowerCase() == 'true') return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void applyAmDossier(AmRegistrationData data, RepriseDossier dossier) {
|
||||
final rawPhoto = dossier.photoUrl?.trim();
|
||||
final hasPhoto = rawPhoto != null && rawPhoto.isNotEmpty;
|
||||
final displayPhoto =
|
||||
hasPhoto ? ApiConfig.absoluteMediaUrl(rawPhoto) : null;
|
||||
|
||||
data.resetForReprise(
|
||||
firstName: dossier.prenom ?? '',
|
||||
lastName: dossier.nom ?? '',
|
||||
phone: dossier.telephone ?? '',
|
||||
email: dossier.email,
|
||||
streetAddress: dossier.adresse ?? '',
|
||||
postalCode: dossier.codePostal ?? '',
|
||||
city: dossier.ville ?? '',
|
||||
existingPhotoUrl: displayPhoto,
|
||||
consentementPhoto: dossier.consentementPhoto || hasPhoto,
|
||||
dateOfBirth: parseIsoDate(dossier.dateNaissance),
|
||||
birthCity: dossier.lieuNaissanceVille ?? '',
|
||||
birthCountry: dossier.lieuNaissancePays ?? '',
|
||||
nir: dossier.nir ?? '',
|
||||
agrementNumber: dossier.numeroAgrement ?? '',
|
||||
agreementDate: parseIsoDate(dossier.dateAgrement),
|
||||
capacity: dossier.nbMaxEnfants,
|
||||
placesAvailable: dossier.placeDisponible,
|
||||
presentationText: dossier.biographie ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
static String isoToDdMmYyyy(String? iso) {
|
||||
final dt = parseIsoDate(iso);
|
||||
if (dt == null) return '';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user