feat(#131): fiche AM éditable en 3 onglets et widgets admin partagés.

Modale admin AM (identité, dossier pro, enfants), API front avec repli, note back affiliation, et extraction gélule statut / liste enfants pour la fiche parent.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 17:33:41 +02:00
co-authored by Cursor
parent 2fd97ddecb
commit 479a32b4bf
10 changed files with 1417 additions and 181 deletions
@@ -48,6 +48,7 @@ class ValidationFormGrid extends StatelessWidget {
final List<ValidationLabeledField> fields;
final List<int>? rowLayout;
final Map<int, List<int>>? rowFlex;
final bool compact;
const ValidationFormGrid({
super.key,
@@ -55,6 +56,7 @@ class ValidationFormGrid extends StatelessWidget {
required this.fields,
this.rowLayout,
this.rowFlex,
this.compact = false,
});
@override
@@ -72,17 +74,17 @@ class ValidationFormGrid extends StatelessWidget {
rowIndex++;
if (count == 1) {
rows.add(Padding(
padding: const EdgeInsets.only(bottom: 12),
padding: EdgeInsets.only(bottom: compact ? 8 : 12),
child: rowFields.first,
));
} else {
rows.add(Padding(
padding: const EdgeInsets.only(bottom: 12),
padding: EdgeInsets.only(bottom: compact ? 8 : 12),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (int i = 0; i < rowFields.length; i++) ...[
if (i > 0) const SizedBox(width: 16),
if (i > 0) SizedBox(width: compact ? 12 : 16),
Expanded(
flex: (flexForRow != null && i < flexForRow.length)
? flexForRow[i]
@@ -103,13 +105,13 @@ class ValidationFormGrid extends StatelessWidget {
if (showTitle) ...[
Text(
title!.trim(),
style: const TextStyle(
fontSize: 16,
style: TextStyle(
fontSize: compact ? 15 : 16,
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
const SizedBox(height: 12),
SizedBox(height: compact ? 8 : 12),
],
...rows,
],
@@ -121,13 +123,16 @@ class ValidationFormGrid extends StatelessWidget {
class ValidationFieldDecoration {
ValidationFieldDecoration._();
static InputDecoration input({String? hint}) {
static InputDecoration input({String? hint, bool compact = false}) {
return InputDecoration(
isDense: true,
filled: true,
fillColor: Colors.grey.shade50,
hintText: hint,
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
contentPadding: EdgeInsets.symmetric(
horizontal: compact ? 10 : 12,
vertical: compact ? 7 : 10,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(color: Colors.grey.shade300),
@@ -191,6 +196,7 @@ class ValidationEditableField extends StatelessWidget {
final List<TextInputFormatter>? inputFormatters;
final String? hintText;
final int maxLines;
final bool compact;
const ValidationEditableField({
super.key,
@@ -199,17 +205,44 @@ class ValidationEditableField extends StatelessWidget {
this.inputFormatters,
this.hintText,
this.maxLines = 1,
this.compact = false,
});
static const double _compactFieldHeight = 34;
@override
Widget build(BuildContext context) {
return TextField(
controller: controller,
keyboardType: keyboardType,
inputFormatters: inputFormatters,
maxLines: maxLines,
style: const TextStyle(color: Colors.black87, fontSize: 14),
decoration: ValidationFieldDecoration.input(hint: hintText),
if (!compact || maxLines > 1) {
return TextField(
controller: controller,
keyboardType: keyboardType,
inputFormatters: inputFormatters,
maxLines: maxLines,
style: TextStyle(
color: Colors.black87,
fontSize: compact ? 13 : 14,
),
decoration: ValidationFieldDecoration.input(
hint: hintText,
compact: compact,
),
);
}
return SizedBox(
height: _compactFieldHeight,
child: TextField(
controller: controller,
keyboardType: keyboardType,
inputFormatters: inputFormatters,
maxLines: 1,
style: const TextStyle(color: Colors.black87, fontSize: 13, height: 1.15),
decoration: ValidationFieldDecoration.input(
hint: hintText,
compact: true,
).copyWith(
contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 9),
),
),
);
}
}
@@ -219,12 +252,14 @@ class ValidationEditableSection extends StatelessWidget {
final List<ValidationLabeledField> fields;
final List<int>? rowLayout;
final Map<int, List<int>>? rowFlex;
final bool compact;
const ValidationEditableSection({
super.key,
required this.fields,
this.rowLayout,
this.rowFlex,
this.compact = false,
});
@override
@@ -232,6 +267,7 @@ class ValidationEditableSection extends StatelessWidget {
return ValidationFormGrid(
rowLayout: rowLayout,
rowFlex: rowFlex,
compact: compact,
fields: fields,
);
}
@@ -241,22 +277,35 @@ class ValidationEditableSection extends StatelessWidget {
class ValidationReadOnlyField extends StatelessWidget {
final String value;
final int? maxLines;
final bool compact;
const ValidationReadOnlyField({
super.key,
required this.value,
this.maxLines = 1,
this.compact = false,
});
static const double _compactFieldHeight = 34;
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
height: compact && maxLines == 1 ? _compactFieldHeight : null,
alignment: compact ? Alignment.centerLeft : null,
padding: EdgeInsets.symmetric(
horizontal: compact ? 10 : 12,
vertical: compact ? 7 : 10,
),
decoration: ValidationFieldDecoration.container(),
child: Text(
value,
style: const TextStyle(color: Colors.black87, fontSize: 14),
style: TextStyle(
color: Colors.black87,
fontSize: compact ? 13 : 14,
height: compact ? 1.2 : null,
),
maxLines: maxLines,
overflow: TextOverflow.ellipsis,
),