- Panneau AM : validation NIR alignée API, date d’agrément requise côté app, capacité 1–10, n° agrément + date sur une ligne, ville/pays formatés au blur. - Widget RegistrationPhotoSlot (cadre, croix) partagé avec les cartes enfant. - AuthService : MIME PNG/JPEG pour la photo ; payload date_agrement. - Scripts register-am-dubois / mansouri ; chemins tests/ressources/photos ; doc test-data + seed ; smoke curl inscription AM. Made-with: Cursor
150 lines
5.5 KiB
Dart
150 lines
5.5 KiB
Dart
import 'package:flutter/foundation.dart';
|
||
|
||
class AmRegistrationData extends ChangeNotifier {
|
||
// Step 1: Identity Info
|
||
String firstName = '';
|
||
String lastName = '';
|
||
String streetAddress = ''; // Nouveau pour N° et Rue
|
||
String postalCode = ''; // Nouveau
|
||
String city = ''; // Nouveau
|
||
String phone = '';
|
||
String email = '';
|
||
String password = '';
|
||
// String? photoPath; // Déplacé ou géré à l'étape 2
|
||
// bool photoConsent = false; // Déplacé ou géré à l'étape 2
|
||
|
||
// Step 2: Professional Info
|
||
String? photoPath; // Chemin fichier local (hors web) si pas d’octets en mémoire
|
||
Uint8List? photoBytes; // Galerie / web (ImagePicker)
|
||
String? photoFilename; // Nom pour l’API (ex. image.jpg)
|
||
bool photoConsent = false; // Ajouté pour l'étape 2
|
||
DateTime? dateOfBirth;
|
||
String birthCity = ''; // Nouveau
|
||
String birthCountry = ''; // Nouveau
|
||
// String placeOfBirth = ''; // Remplacé par birthCity et birthCountry
|
||
String nir = ''; // Numéro de Sécurité Sociale
|
||
String agrementNumber = ''; // Numéro d'agrément
|
||
/// Date d'obtention de l'agrément — obligatoire (API `date_agrement`).
|
||
DateTime? agreementDate;
|
||
int? capacity; // Number of children the AM can look after
|
||
|
||
// Step 3: Presentation & CGU
|
||
String presentationText = '';
|
||
bool cguAccepted = false;
|
||
|
||
// --- Methods to update data and notify listeners ---
|
||
|
||
void updateIdentityInfo({
|
||
String? firstName,
|
||
String? lastName,
|
||
String? streetAddress, // Modifié
|
||
String? postalCode, // Nouveau
|
||
String? city, // Nouveau
|
||
String? phone,
|
||
String? email,
|
||
String? password,
|
||
}) {
|
||
this.firstName = firstName ?? this.firstName;
|
||
this.lastName = lastName ?? this.lastName;
|
||
this.streetAddress = streetAddress ?? this.streetAddress; // Modifié
|
||
this.postalCode = postalCode ?? this.postalCode; // Nouveau
|
||
this.city = city ?? this.city; // Nouveau
|
||
this.phone = phone ?? this.phone;
|
||
this.email = email ?? this.email;
|
||
this.password = password ?? this.password;
|
||
// if (photoPath != null || this.photoPath != null) { // Supprimé de l'étape 1
|
||
// this.photoPath = photoPath;
|
||
// }
|
||
// this.photoConsent = photoConsent ?? this.photoConsent; // Supprimé de l'étape 1
|
||
notifyListeners();
|
||
}
|
||
|
||
void updateProfessionalInfo({
|
||
String? photoPath,
|
||
Uint8List? photoBytes,
|
||
String? photoFilename,
|
||
bool? photoConsent,
|
||
DateTime? dateOfBirth,
|
||
String? birthCity, // Nouveau
|
||
String? birthCountry, // Nouveau
|
||
// String? placeOfBirth, // Remplacé
|
||
String? nir,
|
||
String? agrementNumber,
|
||
DateTime? agreementDate,
|
||
int? capacity,
|
||
}) {
|
||
this.photoPath = photoPath;
|
||
this.photoBytes = photoBytes;
|
||
this.photoFilename = photoFilename;
|
||
this.photoConsent = photoConsent ?? this.photoConsent;
|
||
this.dateOfBirth = dateOfBirth ?? this.dateOfBirth;
|
||
this.birthCity = birthCity ?? this.birthCity; // Nouveau
|
||
this.birthCountry = birthCountry ?? this.birthCountry; // Nouveau
|
||
// this.placeOfBirth = placeOfBirth ?? this.placeOfBirth; // Remplacé
|
||
this.nir = nir ?? this.nir;
|
||
this.agrementNumber = agrementNumber ?? this.agrementNumber;
|
||
this.agreementDate = agreementDate ?? this.agreementDate;
|
||
this.capacity = capacity ?? this.capacity;
|
||
notifyListeners();
|
||
}
|
||
|
||
void updatePresentationAndCgu({
|
||
String? presentationText,
|
||
bool? cguAccepted,
|
||
}) {
|
||
this.presentationText = presentationText ?? this.presentationText;
|
||
this.cguAccepted = cguAccepted ?? this.cguAccepted;
|
||
notifyListeners();
|
||
}
|
||
|
||
// --- Getters for validation or display ---
|
||
bool get isStep1Complete =>
|
||
firstName.isNotEmpty &&
|
||
lastName.isNotEmpty &&
|
||
streetAddress.isNotEmpty && // Modifié
|
||
postalCode.isNotEmpty && // Nouveau
|
||
city.isNotEmpty && // Nouveau
|
||
phone.isNotEmpty &&
|
||
email.isNotEmpty;
|
||
// password n'est pas requis à l'inscription (défini après validation par lien email)
|
||
|
||
/// Photo réelle (pas seulement un placeholder asset).
|
||
bool get _hasUserPhoto =>
|
||
(photoBytes != null && photoBytes!.isNotEmpty) ||
|
||
(photoPath != null &&
|
||
photoPath!.isNotEmpty &&
|
||
!photoPath!.startsWith('assets/'));
|
||
|
||
bool get isStep2Complete =>
|
||
(_hasUserPhoto ? photoConsent == true : true) &&
|
||
dateOfBirth != null &&
|
||
birthCity.isNotEmpty &&
|
||
birthCountry.isNotEmpty &&
|
||
nir.isNotEmpty && // Basic check, could add validation
|
||
agrementNumber.isNotEmpty &&
|
||
agreementDate != null &&
|
||
capacity != null &&
|
||
capacity! >= 1 &&
|
||
capacity! <= 10;
|
||
|
||
bool get isStep3Complete =>
|
||
// presentationText is optional as per CDC (message au gestionnaire)
|
||
cguAccepted;
|
||
|
||
bool get isRegistrationComplete =>
|
||
isStep1Complete && isStep2Complete && isStep3Complete;
|
||
|
||
@override
|
||
String toString() {
|
||
return 'AmRegistrationData('
|
||
'firstName: $firstName, lastName: $lastName, '
|
||
'streetAddress: $streetAddress, postalCode: $postalCode, city: $city, '
|
||
'phone: $phone, email: $email, '
|
||
// 'photoPath: $photoPath, photoConsent: $photoConsent, ' // Commenté car déplacé/modifié
|
||
'dateOfBirth: $dateOfBirth, birthCity: $birthCity, birthCountry: $birthCountry, '
|
||
'nir: $nir, agrementNumber: $agrementNumber, agreementDate: $agreementDate, capacity: $capacity, '
|
||
'photoPath (step2): $photoPath, photoConsent (step2): $photoConsent, '
|
||
'presentationText: $presentationText, cguAccepted: $cguAccepted)';
|
||
}
|
||
}
|