feat(#140): liste enfants unifiée — cartes, âge précis et cadre scrollable

Partage AdminEnfantUserCard entre fiche parent et onglet Enfants, enrichit ParentChildSummary (photo, dates) et compacte la modale parent.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-24 23:06:38 +02:00
co-authored by Cursor
parent 8494341b56
commit 966f4a9c9c
6 changed files with 435 additions and 129 deletions
@@ -1,15 +1,23 @@
import 'package:p_tits_pas/models/enfant_admin_model.dart';
/// Résumé enfant affiché dans la fiche parent (dashboard admin).
class ParentChildSummary {
final String id;
final String? firstName;
final String? lastName;
final String status;
final String? photoUrl;
final String? birthDate;
final String? dueDate;
ParentChildSummary({
required this.id,
this.firstName,
this.lastName,
required this.status,
this.photoUrl,
this.birthDate,
this.dueDate,
});
String get fullName {
@@ -26,9 +34,30 @@ class ParentChildSummary {
firstName: (json['first_name'] ?? json['prenom'])?.toString(),
lastName: (json['last_name'] ?? json['nom'])?.toString(),
status: (json['status'] ?? json['statut'] ?? '').toString(),
photoUrl: json['photo_url']?.toString(),
birthDate: _dateString(json['birth_date']),
dueDate: _dateString(json['due_date']),
);
}
factory ParentChildSummary.fromEnfant(EnfantAdminModel enfant) {
return ParentChildSummary(
id: enfant.id,
firstName: enfant.firstName,
lastName: enfant.lastName,
status: enfant.status,
photoUrl: enfant.photoUrl,
birthDate: enfant.birthDate,
dueDate: enfant.dueDate,
);
}
static String? _dateString(dynamic v) {
if (v == null) return null;
if (v is String) return v.split('T').first;
return v.toString().split('T').first;
}
/// Parse un lien `parentChildren` (objet enfant imbriqué ou id seul).
static ParentChildSummary? fromParentChildLink(Map<String, dynamic> link) {
final childRaw = link['child'] ?? link['enfant'];