feat(auth): Amélioration UI/UX étape 3 inscription enfants

- Corrige le débordement visuel (RenderFlex overflow) dans les cartes enfants.

- Augmente les marges latérales du sélecteur d'enfants pour un meilleur centrage.

- Ajoute un défilement automatique vers la droite lors de l'ajout d'un enfant.

- Intègre une barre de défilement horizontale et un effet de fondu dynamique (fading edges) au sélecteur d'enfants.

- Ajuste le padding vertical dans CustomAppTextField pour un meilleur centrage du hintText.

- Met à jour index.html :

  - Utilise le token {{flutter_service_worker_version}}.

  - Ajoute la balise meta mobile-web-app-capable.

  - Rétablit temporairement loadEntrypoint pour éviter un écran blanc (avertissement de dépréciation en attente de correction).
This commit is contained in:
Julien Martin
2025-05-07 10:42:52 +02:00
parent df56ba11df
commit 42d147c273
4 changed files with 485 additions and 333 deletions
@@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class AppCustomCheckbox extends StatelessWidget {
final String label;
final bool value;
final ValueChanged<bool> onChanged;
final double checkboxSize;
final double checkmarkSizeFactor;
const AppCustomCheckbox({
super.key,
required this.label,
required this.value,
required this.onChanged,
this.checkboxSize = 20.0,
this.checkmarkSizeFactor = 1.4,
});
@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,
),
if (value)
Image.asset(
'assets/images/coche.png',
height: checkboxSize * checkmarkSizeFactor,
width: checkboxSize * checkmarkSizeFactor,
),
],
),
),
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: 14),
overflow: TextOverflow.ellipsis, // Gérer le texte long
),
),
],
),
);
}
}
@@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class CustomAppTextField extends StatelessWidget {
final TextEditingController controller;
final String label;
final String? hintText;
final TextInputType? keyboardType;
final bool obscureText;
final bool enabled;
final bool readOnly;
final VoidCallback? onTap;
final IconData? suffixIcon;
final bool isRequired;
final String? Function(String?)? validator; // Permettre un validateur personnalisé
const CustomAppTextField({
super.key,
required this.controller,
required this.label,
this.hintText,
this.keyboardType,
this.obscureText = false,
this.enabled = true,
this.readOnly = false,
this.onTap,
this.suffixIcon,
this.isRequired = true,
this.validator,
});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: GoogleFonts.merienda(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black87),
),
const SizedBox(height: 4),
Container(
height: 45,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/input_field_bg.png'),
fit: BoxFit.fill,
),
),
child: TextFormField(
controller: controller,
keyboardType: keyboardType,
obscureText: obscureText,
enabled: enabled,
readOnly: readOnly,
onTap: onTap,
style: GoogleFonts.merienda(fontSize: 15, color: enabled ? Colors.black87 : Colors.grey),
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: const EdgeInsets.fromLTRB(15, 13, 15, 11),
hintText: hintText,
hintStyle: GoogleFonts.merienda(fontSize: 15, color: Colors.black38),
suffixIcon: suffixIcon != null ? Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(suffixIcon, color: Colors.black54, size: 20),
) : null,
isDense: true,
),
validator: validator ?? // Utilise le validateur fourni, ou celui par défaut
(value) {
if (!enabled) return null;
if (readOnly) return null;
if (isRequired && (value == null || value.isEmpty)) {
return 'Ce champ est obligatoire';
}
return null;
},
),
),
],
);
}
}