petitspas/frontend/lib/widgets/admin/gestionnaire_management_widget.dart
Julien Martin bc8362bdb7 refactor(#93): extraire un widget UserList réutilisable
Centralise le pattern d'affichage des listes utilisateurs pour garantir une UI homogène entre gestionnaires, parents, assistantes maternelles et administrateurs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 17:59:03 +01:00

189 lines
5.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:p_tits_pas/models/relais_model.dart';
import 'package:p_tits_pas/models/user.dart';
import 'package:p_tits_pas/services/relais_service.dart';
import 'package:p_tits_pas/services/user_service.dart';
import 'package:p_tits_pas/widgets/admin/common/admin_user_card.dart';
import 'package:p_tits_pas/widgets/admin/common/user_list.dart';
class GestionnaireManagementWidget extends StatefulWidget {
final String searchQuery;
const GestionnaireManagementWidget({
Key? key,
required this.searchQuery,
}) : super(key: key);
@override
State<GestionnaireManagementWidget> createState() =>
_GestionnaireManagementWidgetState();
}
class _GestionnaireManagementWidgetState
extends State<GestionnaireManagementWidget> {
bool _isLoading = false;
String? _error;
List<AppUser> _gestionnaires = [];
List<RelaisModel> _relais = [];
@override
void initState() {
super.initState();
_loadGestionnaires();
}
@override
void dispose() => super.dispose();
Future<void> _loadGestionnaires() async {
setState(() {
_isLoading = true;
_error = null;
});
try {
final gestionnaires = await UserService.getGestionnaires();
List<RelaisModel> relais = [];
try {
relais = await RelaisService.getRelais();
} catch (_) {
// L'ecran reste utilisable meme si la route Relais n'est pas disponible.
}
if (!mounted) return;
setState(() {
_gestionnaires = gestionnaires;
_relais = relais;
_isLoading = false;
});
} catch (e) {
if (!mounted) return;
setState(() {
_error = e.toString();
_isLoading = false;
});
}
}
Future<void> _openRelaisAssignmentDialog(AppUser user) async {
String? selectedRelaisId = user.relaisId;
final saved = await showDialog<bool>(
context: context,
builder: (ctx) {
return StatefulBuilder(
builder: (context, setStateDialog) {
return AlertDialog(
title: Text(
'Rattacher ${user.fullName.isEmpty ? user.email : user.fullName}',
),
content: DropdownButtonFormField<String?>(
value: selectedRelaisId,
isExpanded: true,
decoration: const InputDecoration(
labelText: 'Relais principal',
border: OutlineInputBorder(),
),
items: [
const DropdownMenuItem<String?>(
value: null,
child: Text('Aucun relais'),
),
..._relais.map(
(relais) => DropdownMenuItem<String?>(
value: relais.id,
child: Text(relais.nom),
),
),
],
onChanged: (value) {
setStateDialog(() {
selectedRelaisId = value;
});
},
),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(false),
child: const Text('Annuler'),
),
FilledButton(
onPressed: () => Navigator.of(ctx).pop(true),
child: const Text('Enregistrer'),
),
],
);
},
);
},
);
if (saved != true) return;
try {
await UserService.updateGestionnaireRelais(
gestionnaireId: user.id,
relaisId: selectedRelaisId,
);
if (!mounted) return;
await _loadGestionnaires();
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Rattachement relais mis a jour.')),
);
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
e.toString().replaceAll('Exception: ', ''),
),
backgroundColor: Colors.red.shade600,
),
);
}
}
@override
Widget build(BuildContext context) {
final query = widget.searchQuery.toLowerCase();
final filteredGestionnaires = _gestionnaires.where((u) {
final name = u.fullName.toLowerCase();
final email = u.email.toLowerCase();
return name.contains(query) || email.contains(query);
}).toList();
return UserList(
isLoading: _isLoading,
error: _error,
isEmpty: filteredGestionnaires.isEmpty,
emptyMessage: 'Aucun gestionnaire trouvé.',
itemCount: filteredGestionnaires.length,
itemBuilder: (context, index) {
final user = filteredGestionnaires[index];
return AdminUserCard(
title: user.fullName,
avatarUrl: user.photoUrl,
subtitleLines: [
user.email,
'Statut : ${user.statut ?? 'Inconnu'}',
'Relais : ${user.relaisNom ?? 'Non rattaché'}',
],
actions: [
IconButton(
icon: const Icon(Icons.location_city_outlined),
tooltip: 'Rattacher un relais',
onPressed: () => _openRelaisAssignmentDialog(user),
),
IconButton(
icon: const Icon(Icons.edit),
tooltip: 'Modifier',
onPressed: () {
// TODO: Modifier gestionnaire.
},
),
],
);
},
);
}
}