import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get_it/get_it.dart'; import '../../bloc/admin_users_bloc.dart'; import '../../data/models/admin_user_model.dart'; import '../../../../shared/design_system/unionflow_design_system.dart'; import '../../../../shared/widgets/core_card.dart'; import '../../../../shared/widgets/mini_avatar.dart'; import '../../../../shared/design_system/components/uf_app_bar.dart'; import 'user_management_detail_page.dart'; /// Page de gestion des utilisateurs (SUPER_ADMIN) - liste paginée class UserManagementPage extends StatelessWidget { const UserManagementPage({super.key}); @override Widget build(BuildContext context) { return BlocProvider( create: (_) => GetIt.I()..add(AdminUsersLoadRequested()), child: const _UserManagementView(), ); } } class _UserManagementView extends StatefulWidget { const _UserManagementView(); @override State<_UserManagementView> createState() => _UserManagementViewState(); } class _UserManagementViewState extends State<_UserManagementView> { final _searchController = TextEditingController(); @override void dispose() { _searchController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.background, appBar: UFAppBar( title: 'Gestion des utilisateurs', actions: [ IconButton( icon: const Icon(Icons.refresh, size: 20), onPressed: () => context.read().add(AdminUsersLoadRequested()), ), ], ), body: Column( children: [ Padding( padding: const EdgeInsets.all(12), child: TextField( controller: _searchController, decoration: InputDecoration( hintText: 'Rechercher (email, nom...)', hintStyle: AppTypography.subtitleSmall, prefixIcon: const Icon(Icons.search, size: 18), border: OutlineInputBorder( borderRadius: BorderRadius.circular(RadiusTokens.md), borderSide: const BorderSide(color: AppColors.lightBorder), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(RadiusTokens.md), borderSide: const BorderSide(color: AppColors.lightBorder), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(RadiusTokens.md), borderSide: const BorderSide(color: AppColors.primaryGreen), ), filled: true, fillColor: AppColors.lightSurface, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), ), onSubmitted: (v) => context.read().add( AdminUsersLoadRequested(search: v.isEmpty ? null : v), ), ), ), Expanded( child: BlocBuilder( builder: (context, state) { if (state is AdminUsersLoading) { return const Center(child: CircularProgressIndicator()); } if (state is AdminUsersError) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(state.message, textAlign: TextAlign.center), const SizedBox(height: 16), ElevatedButton( onPressed: () => context.read().add(AdminUsersLoadRequested()), child: const Text('Réessayer'), ), ], ), ); } if (state is AdminUsersLoaded) { if (state.users.isEmpty) { return const Center(child: Text('Aucun utilisateur')); } return RefreshIndicator( onRefresh: () async { context.read().add(AdminUsersLoadRequested( search: _searchController.text.isEmpty ? null : _searchController.text, )); }, child: ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 12), itemCount: state.users.length + 1, itemBuilder: (context, i) { if (i == state.users.length) { return _buildPagination(context, state); } return _buildUserTile(context, state.users[i]); }, ), ); } return const SizedBox(); }, ), ), ], ), ); } Widget _buildUserTile(BuildContext context, AdminUserModel user) { return CoreCard( margin: const EdgeInsets.only(bottom: 8), onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (context) => BlocProvider( create: (_) => GetIt.I()..add(AdminUserDetailWithRolesRequested(user.id)), child: UserManagementDetailPage(userId: user.id), ), ), ), child: Row( children: [ MiniAvatar( imageUrl: null, // AdminUserModel n'a pas de champ avatar fallbackText: (user.prenom?.substring(0, 1) ?? user.username?.substring(0, 1) ?? '?').toUpperCase(), size: 36, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( user.displayName, style: AppTypography.actionText, ), Text( user.email ?? user.username ?? user.id, style: AppTypography.subtitleSmall, ), ], ), ), const Icon( Icons.chevron_right, size: 16, color: AppColors.textSecondaryLight, ), ], ), ); } Widget _buildPagination(BuildContext context, AdminUsersLoaded state) { if (state.totalPages <= 1) return const SizedBox(height: 24); return Padding( padding: const EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( icon: const Icon(Icons.arrow_back), onPressed: state.currentPage > 0 ? () => context.read().add(AdminUsersLoadRequested( page: state.currentPage - 1, size: state.pageSize, search: _searchController.text.isEmpty ? null : _searchController.text, )) : null, ), Text('${state.currentPage + 1} / ${state.totalPages}'), IconButton( icon: const Icon(Icons.arrow_forward), onPressed: state.currentPage < state.totalPages - 1 ? () => context.read().add(AdminUsersLoadRequested( page: state.currentPage + 1, size: state.pageSize, search: _searchController.text.isEmpty ? null : _searchController.text, )) : null, ), ], ), ); } }