140 lines
4.4 KiB
Dart
140 lines
4.4 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:p_tits_pas/models/parent_model.dart';
|
||
import 'package:p_tits_pas/services/user_service.dart';
|
||
import 'package:p_tits_pas/widgets/admin/common/admin_select_list_modal.dart';
|
||
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
|
||
|
||
/// Foyer / famille sélectionnable pour rattacher un nouvel enfant (#132 / #157).
|
||
class AdminFamilleFoyer {
|
||
/// Parent pivot pour `POST /enfants` (`parent_user_id`).
|
||
final String pivotParentUserId;
|
||
/// Co-parent éventuel (rattachement foyer #157).
|
||
final String? coParentUserId;
|
||
final String? numeroDossier;
|
||
final String displayTitle;
|
||
final List<String> parentNames;
|
||
|
||
const AdminFamilleFoyer({
|
||
required this.pivotParentUserId,
|
||
required this.displayTitle,
|
||
required this.parentNames,
|
||
this.coParentUserId,
|
||
this.numeroDossier,
|
||
});
|
||
|
||
/// Parents du foyer à lier à l’enfant (pivot puis co-parent).
|
||
List<String> get parentUserIds {
|
||
final ids = <String>[pivotParentUserId];
|
||
final co = (coParentUserId ?? '').trim();
|
||
if (co.isNotEmpty && co != pivotParentUserId) ids.add(co);
|
||
return ids;
|
||
}
|
||
|
||
String get subtitle {
|
||
final parts = <String>[];
|
||
final dossier = (numeroDossier ?? '').trim();
|
||
if (dossier.isNotEmpty) parts.add('Dossier $dossier');
|
||
if (parentNames.isNotEmpty) {
|
||
parts.add('Responsables : ${parentNames.join(', ')}');
|
||
}
|
||
return parts.join(' ');
|
||
}
|
||
}
|
||
|
||
/// Construit la liste des foyers uniques à partir de `GET /parents`.
|
||
List<AdminFamilleFoyer> buildFamilleFoyers(List<ParentModel> parents) {
|
||
final seenDossiers = <String>{};
|
||
final seenUserIds = <String>{};
|
||
final foyers = <AdminFamilleFoyer>[];
|
||
|
||
for (final p in parents) {
|
||
final dossier = (p.user.numeroDossier ?? '').trim();
|
||
if (dossier.isNotEmpty) {
|
||
if (seenDossiers.contains(dossier)) continue;
|
||
seenDossiers.add(dossier);
|
||
} else if (seenUserIds.contains(p.user.id)) {
|
||
continue;
|
||
}
|
||
|
||
seenUserIds.add(p.user.id);
|
||
final co = p.coParent;
|
||
if (co != null) seenUserIds.add(co.id);
|
||
|
||
final names = <String>[
|
||
if (p.user.fullName.trim().isNotEmpty) p.user.fullName.trim(),
|
||
if (co != null && co.fullName.trim().isNotEmpty) co.fullName.trim(),
|
||
];
|
||
|
||
final title = dossier.isNotEmpty
|
||
? 'Dossier $dossier'
|
||
: (names.isNotEmpty ? names.first : 'Famille');
|
||
|
||
foyers.add(
|
||
AdminFamilleFoyer(
|
||
pivotParentUserId: p.user.id,
|
||
coParentUserId: co?.id,
|
||
numeroDossier: dossier.isNotEmpty ? dossier : null,
|
||
displayTitle: title,
|
||
parentNames: names,
|
||
),
|
||
);
|
||
}
|
||
|
||
foyers.sort(
|
||
(a, b) => a.displayTitle.toLowerCase().compareTo(b.displayTitle.toLowerCase()),
|
||
);
|
||
return foyers;
|
||
}
|
||
|
||
/// Sélection d'une famille / dossier pour créer un enfant — ticket #132.
|
||
class AdminSelectFamilleModal {
|
||
AdminSelectFamilleModal._();
|
||
|
||
static Future<AdminFamilleFoyer?> show(
|
||
BuildContext context, {
|
||
String title = 'Choisir une famille',
|
||
}) {
|
||
return AdminSelectListModal.show<AdminFamilleFoyer>(
|
||
context,
|
||
title: title,
|
||
searchHint: 'Rechercher par dossier, nom…',
|
||
emptyMessage: 'Aucune famille disponible',
|
||
noResultsMessage: 'Aucun résultat pour cette recherche',
|
||
loadItems: () async {
|
||
final parents = await UserService.getParents();
|
||
return buildFamilleFoyers(parents);
|
||
},
|
||
matchesQuery: (f, q) {
|
||
final dossier = (f.numeroDossier ?? '').toLowerCase();
|
||
final title = f.displayTitle.toLowerCase();
|
||
final names = f.parentNames.join(' ').toLowerCase();
|
||
return dossier.contains(q) || title.contains(q) || names.contains(q);
|
||
},
|
||
itemBuilder: (context, f, onSelect) {
|
||
return AdminUserCard(
|
||
title: f.displayTitle,
|
||
fallbackIcon: Icons.family_restroom,
|
||
subtitleLines: [
|
||
if (f.parentNames.isNotEmpty) f.parentNames.join(', '),
|
||
if ((f.numeroDossier ?? '').isNotEmpty)
|
||
'Dossier ${f.numeroDossier}',
|
||
],
|
||
onCardTap: onSelect,
|
||
margin: const EdgeInsets.only(bottom: 4),
|
||
contentPadding: const EdgeInsets.symmetric(
|
||
horizontal: 10,
|
||
vertical: 5,
|
||
),
|
||
actions: [
|
||
IconButton(
|
||
icon: const Icon(Icons.check_circle_outline),
|
||
tooltip: 'Choisir',
|
||
onPressed: onSelect,
|
||
),
|
||
],
|
||
);
|
||
},
|
||
);
|
||
}
|
||
}
|