feat(frontend): inscription — UI cartes enfant, formatage noms, focus Tab

- Formulaire infos perso : ordre de tabulation explicite, Checkbox Material
  pour le consentement photo, formatage nom/prénom/ville à la perte de focus
  et à la soumission (name_format_utils).
- Carte enfant : cadre photo, croix, ombres, consentement ; formatage
  prénom/nom enfant ; normalisation avant passage étape 4.
- Asset photo_frame.png ; HoverReliefWidget clipBehavior.
- Ajustements payload / modèle / étapes inscription liés au parcours.

Made-with: Cursor
This commit is contained in:
2026-03-28 20:40:27 +01:00
parent a723412043
commit 110240b682
10 changed files with 740 additions and 264 deletions
+54 -33
View File
@@ -8,6 +8,8 @@ class AppCustomCheckbox extends StatelessWidget {
final double checkboxSize;
final double checkmarkSizeFactor;
final double fontSize;
/// Survol (desktop) ou appui long (mobile) pour afficher un texte daide.
final String? tooltip;
const AppCustomCheckbox({
super.key,
@@ -17,48 +19,67 @@ class AppCustomCheckbox extends StatelessWidget {
this.checkboxSize = 20.0,
this.checkmarkSizeFactor = 1.4,
this.fontSize = 16.0,
this.tooltip,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onChanged(!value), // Inverse la valeur au clic
behavior: HitTestBehavior.opaque, // Pour s'assurer que toute la zone du Row est cliquable
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: checkboxSize,
height: checkboxSize,
child: Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Image.asset(
'assets/images/square.png',
height: checkboxSize,
width: checkboxSize,
return Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () => onChanged(!value),
behavior: HitTestBehavior.opaque,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: checkboxSize,
height: checkboxSize,
child: Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Image.asset(
'assets/images/square.png',
height: checkboxSize,
width: checkboxSize,
),
if (value)
Image.asset(
'assets/images/coche.png',
height: checkboxSize * checkmarkSizeFactor,
width: checkboxSize * checkmarkSizeFactor,
),
],
),
if (value)
Image.asset(
'assets/images/coche.png',
height: checkboxSize * checkmarkSizeFactor,
width: checkboxSize * checkmarkSizeFactor,
),
],
),
),
const SizedBox(width: 10),
Flexible(
child: Text(
label,
style: GoogleFonts.merienda(fontSize: fontSize),
overflow: TextOverflow.ellipsis,
),
),
],
),
const SizedBox(width: 10),
// Utiliser Flexible pour que le texte ne cause pas d'overflow si trop long
Flexible(
child: Text(
label,
style: GoogleFonts.merienda(fontSize: fontSize),
overflow: TextOverflow.ellipsis, // Gérer le texte long
),
if (tooltip != null && tooltip!.trim().isNotEmpty) ...[
const SizedBox(width: 6),
Tooltip(
message: tooltip!.trim(),
waitDuration: const Duration(milliseconds: 300),
triggerMode: TooltipTriggerMode.tap,
showDuration: const Duration(seconds: 6),
child: Icon(
Icons.info_outline,
size: fontSize * 1.2,
color: Colors.black54,
),
),
],
),
],
);
}
}