fix(inscription-am): étape 1/2 obligatoires alignées API (min 2 car., photo)

- Étape 1 : prénom/nom min 2 caractères (minPersonNameLength sur PersonalInfoFormScreen pour AM)

- Étape 2 : ville/pays naissance min 2 ; photo réelle + consentement obligatoires ; isStep2Complete strict

- registerAM : lieu naissance trim + toujours envoyer photo_base64 ; lieu_* non null si valide

- Étape 4 : blocage envoi si isRegistrationComplete faux

Made-with: Cursor
This commit is contained in:
2026-04-13 13:32:25 +02:00
parent b4b44cb1b9
commit d550e57cb8
6 changed files with 91 additions and 20 deletions
@@ -55,6 +55,8 @@ class PersonalInfoFormScreen extends StatefulWidget {
final PersonalInfoData? referenceAddressData; // Pour pré-remplir si "même adresse"
final bool embedContentOnly; // Si true, affiche seulement la carte (sans scaffold/fond/titre)
final VoidCallback? onEdit; // Callback pour le bouton d'édition (si affiché)
/// Si non null (ex. 2 pour inscription AM), nom/prénom : trim + longueur minimale (aligné API).
final int? minPersonNameLength;
const PersonalInfoFormScreen({
super.key,
@@ -72,6 +74,7 @@ class PersonalInfoFormScreen extends StatefulWidget {
this.referenceAddressData,
this.embedContentOnly = false,
this.onEdit,
this.minPersonNameLength,
});
@override
@@ -214,6 +217,16 @@ class _PersonalInfoFormScreenState extends State<PersonalInfoFormScreen> {
return validateEmail(value, allowEmpty: true);
}
/// Prénom / nom avec longueur minimale (ex. inscription AM, aligné `MinLength` API).
String? _validatePersonNameWithMinLength(String? value) {
final min = widget.minPersonNameLength;
if (min == null) return null;
final t = (value ?? '').trim();
if (t.isEmpty) return 'Ce champ est obligatoire';
if (t.length < min) return 'Au moins $min caractères';
return null;
}
/// Téléphone / e-mail du parent 2 : pas de validation si « Ajouter Parent 2 » est désactivé.
String? _validateFrenchPhoneIfSecondParentNeeded(String? value) {
if (widget.showSecondPersonToggle && !_fieldsEnabled) {
@@ -837,6 +850,9 @@ class _PersonalInfoFormScreenState extends State<PersonalInfoFormScreen> {
enabled: _fieldsEnabled,
focusOrder: _focusLastName,
focusNode: _lastNameFocus,
fieldValidator: widget.minPersonNameLength != null
? _validatePersonNameWithMinLength
: null,
),
),
const SizedBox(width: 20),
@@ -849,6 +865,9 @@ class _PersonalInfoFormScreenState extends State<PersonalInfoFormScreen> {
enabled: _fieldsEnabled,
focusOrder: _focusFirstName,
focusNode: _firstNameFocus,
fieldValidator: widget.minPersonNameLength != null
? _validatePersonNameWithMinLength
: null,
),
),
],
@@ -1106,6 +1125,9 @@ class _PersonalInfoFormScreenState extends State<PersonalInfoFormScreen> {
enabled: _fieldsEnabled,
focusOrder: _focusLastName,
focusNode: _lastNameFocus,
fieldValidator: widget.minPersonNameLength != null
? _validatePersonNameWithMinLength
: null,
),
const SizedBox(height: 12),
@@ -1118,6 +1140,9 @@ class _PersonalInfoFormScreenState extends State<PersonalInfoFormScreen> {
enabled: _fieldsEnabled,
focusOrder: _focusFirstName,
focusNode: _firstNameFocus,
fieldValidator: widget.minPersonNameLength != null
? _validatePersonNameWithMinLength
: null,
),
const SizedBox(height: 12),