feat(#96): finaliser la modale admin/gestionnaire et les règles d’édition

Unifie la modale utilisateur pour création/édition admin et gestionnaire, fiabilise la saisie/normalisation (téléphone, nom/prénom) et corrige la mise à jour backend pour accepter le rattachement relais sans erreur 400.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-24 17:25:15 +01:00
co-authored by Cursor
parent 222d7c702f
commit d8572e7fd6
6 changed files with 352 additions and 70 deletions
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:p_tits_pas/models/user.dart';
import 'package:p_tits_pas/screens/administrateurs/creation/gestionnaires_create.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';
@@ -51,6 +52,23 @@ class _AdminManagementWidgetState extends State<AdminManagementWidget> {
}
}
Future<void> _openAdminEditDialog(AppUser user) async {
final changed = await showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (dialogContext) {
return AdminUserFormDialog(
initialUser: user,
adminMode: true,
withRelais: false,
);
},
);
if (changed == true) {
await _loadAdmins();
}
}
@override
Widget build(BuildContext context) {
final query = widget.searchQuery.toLowerCase();
@@ -80,7 +98,7 @@ class _AdminManagementWidgetState extends State<AdminManagementWidget> {
icon: const Icon(Icons.edit),
tooltip: 'Modifier',
onPressed: () {
// TODO: Modifier admin
_openAdminEditDialog(user);
},
),
],
@@ -59,7 +59,7 @@ class _GestionnaireManagementWidgetState
context: context,
barrierDismissible: false,
builder: (dialogContext) {
return GestionnaireCreateDialog(initialUser: user);
return AdminUserFormDialog(initialUser: user);
},
);
if (changed == true) {
@@ -17,6 +17,7 @@ class AdminUserManagementPanel extends StatefulWidget {
class _AdminUserManagementPanelState extends State<AdminUserManagementPanel> {
int _subIndex = 0;
int _gestionnaireRefreshTick = 0;
int _adminRefreshTick = 0;
final TextEditingController _searchController = TextEditingController();
final TextEditingController _amCapacityController = TextEditingController();
String? _parentStatus;
@@ -150,6 +151,7 @@ class _AdminUserManagementPanelState extends State<AdminUserManagementPanel> {
);
case 3:
return AdminManagementWidget(
key: ValueKey('admins-$_adminRefreshTick'),
searchQuery: _searchController.text,
);
default:
@@ -176,31 +178,52 @@ class _AdminUserManagementPanelState extends State<AdminUserManagementPanel> {
}
Future<void> _handleAddPressed() async {
if (_subIndex != 0) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'La création est disponible uniquement pour les gestionnaires.',
),
),
if (_subIndex == 0) {
final created = await showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (dialogContext) {
return const AdminUserFormDialog();
},
);
if (!mounted) return;
if (created == true) {
setState(() {
_gestionnaireRefreshTick++;
});
}
return;
}
final created = await showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (dialogContext) {
return const GestionnaireCreateDialog();
},
);
if (_subIndex == 3) {
final created = await showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (dialogContext) {
return const AdminUserFormDialog(
adminMode: true,
withRelais: false,
);
},
);
if (!mounted) return;
if (created == true) {
setState(() {
_adminRefreshTick++;
});
}
return;
}
if (!mounted) return;
if (created == true) {
setState(() {
_gestionnaireRefreshTick++;
});
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'La création est disponible pour les gestionnaires et administrateurs.',
),
),
);
}
}