107 lines
3.0 KiB
Dart
107 lines
3.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:p_tits_pas/utils/enfant_status_utils.dart';
|
|
import 'package:p_tits_pas/models/enfant_admin_model.dart';
|
|
import 'package:p_tits_pas/services/user_service.dart';
|
|
import 'package:p_tits_pas/widgets/admin/common/admin_child_detail_modal.dart';
|
|
import 'package:p_tits_pas/widgets/admin/common/admin_enfant_user_card.dart';
|
|
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
|
|
|
|
/// Onglet liste globale des enfants (doc 28 §6.2, ticket #137).
|
|
class EnfantManagementWidget extends StatefulWidget {
|
|
final String searchQuery;
|
|
final String? statusFilter;
|
|
|
|
const EnfantManagementWidget({
|
|
super.key,
|
|
required this.searchQuery,
|
|
this.statusFilter,
|
|
});
|
|
|
|
@override
|
|
State<EnfantManagementWidget> createState() => _EnfantManagementWidgetState();
|
|
}
|
|
|
|
class _EnfantManagementWidgetState extends State<EnfantManagementWidget> {
|
|
bool _isLoading = false;
|
|
String? _error;
|
|
List<EnfantAdminModel> _enfants = [];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadEnfants();
|
|
}
|
|
|
|
Future<void> _loadEnfants() async {
|
|
setState(() {
|
|
_isLoading = true;
|
|
_error = null;
|
|
});
|
|
try {
|
|
final list = await UserService.getEnfants();
|
|
if (!mounted) return;
|
|
setState(() {
|
|
_enfants = list;
|
|
_isLoading = false;
|
|
});
|
|
} catch (e) {
|
|
if (!mounted) return;
|
|
setState(() {
|
|
_error = e.toString();
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> _openEnfant(EnfantAdminModel enfant) async {
|
|
await showDialog<void>(
|
|
context: context,
|
|
builder: (ctx) => AdminChildDetailModal(
|
|
enfant: enfant,
|
|
onSaved: _loadEnfants,
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final query = widget.searchQuery.toLowerCase();
|
|
final filtered = _enfants.where((e) {
|
|
final matchesName = e.fullName.toLowerCase().contains(query);
|
|
final matchesStatus = widget.statusFilter == null ||
|
|
normalizeEnfantStatus(e.status) ==
|
|
normalizeEnfantStatus(widget.statusFilter);
|
|
return matchesName && matchesStatus;
|
|
}).toList()
|
|
..sort((a, b) {
|
|
// Orphelins (#157) en tête, puis ordre alphabétique.
|
|
final ao = a.hasNoResponsable ? 0 : 1;
|
|
final bo = b.hasNoResponsable ? 0 : 1;
|
|
if (ao != bo) return ao.compareTo(bo);
|
|
return a.fullName.toLowerCase().compareTo(b.fullName.toLowerCase());
|
|
});
|
|
|
|
return UserList(
|
|
isLoading: _isLoading,
|
|
error: _error,
|
|
isEmpty: filtered.isEmpty,
|
|
emptyMessage: 'Aucun enfant trouvé.',
|
|
itemCount: filtered.length,
|
|
itemBuilder: (context, index) {
|
|
final enfant = filtered[index];
|
|
return AdminEnfantUserCard.fromEnfant(
|
|
enfant,
|
|
onCardTap: () => _openEnfant(enfant),
|
|
actions: [
|
|
IconButton(
|
|
icon: const Icon(Icons.visibility_outlined),
|
|
tooltip: 'Voir / modifier',
|
|
onPressed: () => _openEnfant(enfant),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|