import 'package:flutter/material.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/admin_management_widget.dart'; import 'package:p_tits_pas/widgets/admin/assistante_maternelle_management_widget.dart'; import 'package:p_tits_pas/widgets/admin/dashboard_admin.dart'; import 'package:p_tits_pas/widgets/admin/gestionnaire_management_widget.dart'; import 'package:p_tits_pas/widgets/admin/parent_managmant_widget.dart'; import 'package:p_tits_pas/widgets/admin/pending_validation_widget.dart'; class UserManagementPanel extends StatefulWidget { /// Afficher l'onglet Administrateurs (sinon 3 onglets : Gestionnaires, Parents, AM). final bool showAdministrateursTab; const UserManagementPanel({ super.key, this.showAdministrateursTab = true, }); @override State createState() => _UserManagementPanelState(); } class _UserManagementPanelState extends State { int _subIndex = 0; int _gestionnaireRefreshTick = 0; int _adminRefreshTick = 0; final TextEditingController _searchController = TextEditingController(); final TextEditingController _amCapacityController = TextEditingController(); String? _parentStatus; bool _hasPending = false; bool _pendingLoading = true; @override void initState() { super.initState(); _searchController.addListener(_onFilterChanged); _amCapacityController.addListener(_onFilterChanged); _loadPending(); } Future _loadPending() async { try { final am = await UserService.getPendingUsers(role: 'assistante_maternelle'); final families = await UserService.getPendingFamilies(); if (!mounted) return; final hasPending = am.isNotEmpty || families.isNotEmpty; setState(() { final hadPending = _hasPending; _hasPending = hasPending; _pendingLoading = false; // Si on passe à "plus de dossiers", recaler l'index (onglet À valider disparaît). if (hadPending && !hasPending) { _subIndex = (_subIndex > 0 ? _subIndex - 1 : 0).clamp(0, _tabLabels.length - 1); } else if (!hadPending && hasPending) { _subIndex = 0; // Afficher l'onglet À valider } }); } catch (_) { if (!mounted) return; setState(() { _hasPending = false; _pendingLoading = false; }); } } @override void dispose() { _searchController.removeListener(_onFilterChanged); _amCapacityController.removeListener(_onFilterChanged); _searchController.dispose(); _amCapacityController.dispose(); super.dispose(); } void _onFilterChanged() { if (!mounted) return; setState(() {}); } List get _tabLabels { const base = ['Parents', 'Assistantes maternelles', 'Gestionnaires']; final withAdmin = [...base, 'Administrateurs']; final list = widget.showAdministrateursTab ? withAdmin : base; // Onglet « À valider » visible seulement s'il y a des dossiers en attente (ticket #107). if (!_pendingLoading && _hasPending) return ['À valider', ...list]; return list; } void _onSubTabChange(int index) { final maxIndex = _tabLabels.length - 1; setState(() { _subIndex = index.clamp(0, maxIndex); _searchController.clear(); _parentStatus = null; _amCapacityController.clear(); }); } /// Index du contenu : -1 = À valider (si visible), 0 = Parents, 1 = AM, 2 = Gestionnaires, 3 = Admin. int get _contentIndexOffset => (_hasPending && !_pendingLoading) ? 1 : 0; String _searchHintForTab() { final contentIndex = _subIndex - _contentIndexOffset; switch (contentIndex) { case -1: return 'À valider (pas de recherche)'; case 0: return 'Rechercher un parent...'; case 1: return 'Rechercher une assistante...'; case 2: return 'Rechercher un gestionnaire...'; case 3: return 'Rechercher un administrateur...'; default: return 'Rechercher...'; } } Widget? _subBarFilterControl() { if (_subIndex == _contentIndexOffset + 0) { return DropdownButtonHideUnderline( child: DropdownButton( value: _parentStatus, isExpanded: true, hint: const Padding( padding: EdgeInsets.only(left: 10), child: Text('Statut', style: TextStyle(fontSize: 12)), ), items: const [ DropdownMenuItem( value: null, child: Padding( padding: EdgeInsets.only(left: 10), child: Text('Tous', style: TextStyle(fontSize: 12)), ), ), DropdownMenuItem( value: 'actif', child: Padding( padding: EdgeInsets.only(left: 10), child: Text('Actif', style: TextStyle(fontSize: 12)), ), ), DropdownMenuItem( value: 'en_attente', child: Padding( padding: EdgeInsets.only(left: 10), child: Text('En attente', style: TextStyle(fontSize: 12)), ), ), DropdownMenuItem( value: 'suspendu', child: Padding( padding: EdgeInsets.only(left: 10), child: Text('Suspendu', style: TextStyle(fontSize: 12)), ), ), ], onChanged: (value) { setState(() { _parentStatus = value; }); }, ), ); } if (_subIndex == _contentIndexOffset + 1) { return TextField( controller: _amCapacityController, decoration: const InputDecoration( hintText: 'Capacité min', hintStyle: TextStyle(fontSize: 12), border: InputBorder.none, isDense: true, contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), ), keyboardType: TextInputType.number, ); } return null; } Widget _buildBody() { final contentIndex = _subIndex - _contentIndexOffset; if (_hasPending && !_pendingLoading && contentIndex == -1) { return PendingValidationWidget(onRefresh: _loadPending); } switch (contentIndex) { case 0: return ParentManagementWidget( searchQuery: _searchController.text, statusFilter: _parentStatus, ); case 1: return AssistanteMaternelleManagementWidget( searchQuery: _searchController.text, capacityMin: int.tryParse(_amCapacityController.text), ); case 2: return GestionnaireManagementWidget( key: ValueKey('gestionnaires-$_gestionnaireRefreshTick'), searchQuery: _searchController.text, ); case 3: return AdminManagementWidget( key: ValueKey('admins-$_adminRefreshTick'), searchQuery: _searchController.text, ); default: return const Center(child: Text('Page non trouvée')); } } @override Widget build(BuildContext context) { final labels = _tabLabels; final isAValiderTab = _hasPending && !_pendingLoading && _subIndex == 0; return Column( children: [ DashboardUserManagementSubBar( selectedSubIndex: _subIndex, onSubTabChange: _onSubTabChange, searchController: _searchController, searchHint: _searchHintForTab(), filterControl: _subBarFilterControl(), onAddPressed: isAValiderTab ? null : _handleAddPressed, addLabel: 'Ajouter', subTabCount: labels.length, tabLabels: labels, ), Expanded(child: _buildBody()), ], ); } Future _handleAddPressed() async { final contentIndex = _subIndex - _contentIndexOffset; if (contentIndex == 2) { final created = await showDialog( context: context, barrierDismissible: false, builder: (dialogContext) { return const AdminUserFormDialog(); }, ); if (!mounted) return; if (created == true) { setState(() { _gestionnaireRefreshTick++; }); } return; } if (contentIndex == 3) { final created = await showDialog( 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; ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( 'La création est disponible pour les gestionnaires et administrateurs.', ), ), ); } }