[#101] [Frontend] Inscription parent — API, soumission et validation
Squash merge de develop vers master. Livrables principaux (ticket #101 et mise au point associée) : - Branchement du formulaire d'inscription parent sur POST /api/v1/auth/register/parent - Payload DTO (parents, enfants, photos base64, CGU) et services Auth - Parcours gestionnaire : cartes dossiers, wizard validation famille, images authentifiées - Scripts d'inscription test (Martin, Durand/Rousseau, Lecomte) ; .gitignore .cursor/ Inclut également les ajustements develop fusionnés dans ce lot (inscription AM, champs relais, etc.). Closes #101 Made-with: Cursor
This commit is contained in:
@@ -32,6 +32,9 @@ class CustomAppTextField extends StatefulWidget {
|
||||
final TextInputAction? textInputAction;
|
||||
final ValueChanged<String>? onFieldSubmitted;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
final bool autocorrect;
|
||||
final bool enableSuggestions;
|
||||
final GlobalKey<FormFieldState<String>>? formFieldKey;
|
||||
|
||||
const CustomAppTextField({
|
||||
super.key,
|
||||
@@ -57,6 +60,9 @@ class CustomAppTextField extends StatefulWidget {
|
||||
this.textInputAction,
|
||||
this.onFieldSubmitted,
|
||||
this.inputFormatters,
|
||||
this.autocorrect = true,
|
||||
this.enableSuggestions = true,
|
||||
this.formFieldKey,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -78,9 +84,13 @@ class _CustomAppTextFieldState extends State<CustomAppTextField> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const double fontHeightMultiplier = 1.2;
|
||||
const double internalVerticalPadding = 16.0;
|
||||
final double dynamicFieldHeight = widget.fieldHeight;
|
||||
// Indication « non éditable » : libellé + hint en gris.
|
||||
final Color labelColor =
|
||||
widget.enabled ? Colors.black87 : Colors.grey;
|
||||
final Color hintColor = widget.enabled
|
||||
? Colors.black54.withValues(alpha: 0.7)
|
||||
: Colors.grey;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -91,16 +101,18 @@ class _CustomAppTextFieldState extends State<CustomAppTextField> {
|
||||
widget.labelText,
|
||||
style: GoogleFonts.merienda(
|
||||
fontSize: widget.labelFontSize,
|
||||
color: Colors.black87,
|
||||
color: labelColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
],
|
||||
// Pas de hauteur fixe sur le TextFormField : le message d’erreur du
|
||||
// validateur s’affiche en dessous ; un SizedBox fixe le masquait.
|
||||
SizedBox(
|
||||
width: widget.fieldWidth,
|
||||
height: dynamicFieldHeight,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: Alignment.centerLeft,
|
||||
children: [
|
||||
Positioned.fill(
|
||||
@@ -112,48 +124,63 @@ class _CustomAppTextFieldState extends State<CustomAppTextField> {
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 18.0, vertical: 8.0),
|
||||
child: TextFormField(
|
||||
controller: widget.controller,
|
||||
focusNode: widget.focusNode,
|
||||
obscureText: widget.obscureText,
|
||||
keyboardType: widget.keyboardType,
|
||||
inputFormatters: widget.inputFormatters,
|
||||
autofillHints: widget.autofillHints,
|
||||
textInputAction: widget.textInputAction,
|
||||
onFieldSubmitted: widget.onFieldSubmitted,
|
||||
enabled: widget.enabled,
|
||||
readOnly: widget.readOnly,
|
||||
onTap: widget.onTap,
|
||||
style: GoogleFonts.merienda(
|
||||
fontSize: widget.inputFontSize,
|
||||
color: widget.enabled ? Colors.black87 : Colors.grey),
|
||||
validator: widget.validator ??
|
||||
(value) {
|
||||
if (!widget.enabled || widget.readOnly) return null;
|
||||
if (widget.isRequired &&
|
||||
(value == null || value.isEmpty)) {
|
||||
return 'Ce champ est obligatoire';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.hintText,
|
||||
hintStyle: GoogleFonts.merienda(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight:
|
||||
(dynamicFieldHeight - 16.0).clamp(24.0, double.infinity),
|
||||
),
|
||||
child: TextFormField(
|
||||
key: widget.formFieldKey,
|
||||
controller: widget.controller,
|
||||
focusNode: widget.focusNode,
|
||||
obscureText: widget.obscureText,
|
||||
keyboardType: widget.keyboardType,
|
||||
autocorrect: widget.autocorrect,
|
||||
enableSuggestions: widget.enableSuggestions,
|
||||
inputFormatters: widget.inputFormatters,
|
||||
autofillHints: widget.autofillHints,
|
||||
textInputAction: widget.textInputAction,
|
||||
onFieldSubmitted: widget.onFieldSubmitted,
|
||||
enabled: widget.enabled,
|
||||
readOnly: widget.readOnly,
|
||||
onTap: widget.onTap,
|
||||
style: GoogleFonts.merienda(
|
||||
fontSize: widget.inputFontSize,
|
||||
color: Colors.black54.withOpacity(0.7)),
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
suffixIcon: widget.suffixIcon != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(right: 0.0),
|
||||
child: Icon(widget.suffixIcon,
|
||||
color: Colors.black54,
|
||||
size: widget.inputFontSize * 1.1),
|
||||
)
|
||||
: null,
|
||||
isDense: true,
|
||||
color: Colors.black87),
|
||||
validator: widget.validator ??
|
||||
(value) {
|
||||
if (!widget.enabled || widget.readOnly) return null;
|
||||
if (widget.isRequired &&
|
||||
(value == null || value.isEmpty)) {
|
||||
return 'Ce champ est obligatoire';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: widget.hintText,
|
||||
hintStyle: GoogleFonts.merienda(
|
||||
fontSize: widget.inputFontSize,
|
||||
color: hintColor),
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
isDense: true,
|
||||
errorStyle: GoogleFonts.merienda(
|
||||
fontSize: widget.inputFontSize * 0.75,
|
||||
color: Colors.red.shade800,
|
||||
height: 1.2,
|
||||
),
|
||||
errorMaxLines: 3,
|
||||
suffixIcon: widget.suffixIcon != null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(right: 0.0),
|
||||
child: Icon(widget.suffixIcon,
|
||||
color: Colors.black54,
|
||||
size: widget.inputFontSize * 1.1),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
),
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user