/// Système de navigation adaptatif basé sur les rôles /// Navigation qui s'adapte selon les permissions et rôles utilisateurs library adaptive_navigation; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../auth/bloc/auth_bloc.dart'; import '../auth/models/user_role.dart'; import '../auth/models/permission_matrix.dart'; import '../widgets/adaptive_widget.dart'; /// Élément de navigation adaptatif class AdaptiveNavigationItem { /// Icône de l'élément final IconData icon; /// Icône sélectionnée (optionnelle) final IconData? selectedIcon; /// Libellé de l'élément final String label; /// Route de destination final String route; /// Permissions requises pour afficher cet élément final List requiredPermissions; /// Rôles minimum requis final UserRole? minimumRole; /// Badge de notification (optionnel) final String? badge; /// Couleur personnalisée (optionnelle) final Color? color; const AdaptiveNavigationItem({ required this.icon, this.selectedIcon, required this.label, required this.route, this.requiredPermissions = const [], this.minimumRole, this.badge, this.color, }); } /// Drawer de navigation adaptatif class AdaptiveNavigationDrawer extends StatelessWidget { /// Callback de navigation final Function(String route) onNavigate; /// Callback de déconnexion final VoidCallback onLogout; /// Éléments de navigation personnalisés final List? customItems; const AdaptiveNavigationDrawer({ super.key, required this.onNavigate, required this.onLogout, this.customItems, }); @override Widget build(BuildContext context) { return AdaptiveWidget( roleWidgets: { UserRole.superAdmin: () => _buildSuperAdminDrawer(context), UserRole.orgAdmin: () => _buildOrgAdminDrawer(context), UserRole.moderator: () => _buildModeratorDrawer(context), UserRole.activeMember: () => _buildActiveMemberDrawer(context), UserRole.simpleMember: () => _buildSimpleMemberDrawer(context), UserRole.visitor: () => _buildVisitorDrawer(context), }, fallbackWidget: _buildBasicDrawer(context), loadingWidget: _buildLoadingDrawer(context), ); } /// Drawer pour Super Admin Widget _buildSuperAdminDrawer(BuildContext context) { final items = [ const AdaptiveNavigationItem( icon: Icons.dashboard, label: 'Command Center', route: '/dashboard', requiredPermissions: [PermissionMatrix.SYSTEM_ADMIN], ), const AdaptiveNavigationItem( icon: Icons.business, label: 'Organisations', route: '/organizations', requiredPermissions: [PermissionMatrix.ORG_CREATE], ), const AdaptiveNavigationItem( icon: Icons.people, label: 'Utilisateurs Globaux', route: '/global-users', requiredPermissions: [PermissionMatrix.MEMBERS_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.settings, label: 'Administration', route: '/system-admin', requiredPermissions: [PermissionMatrix.SYSTEM_CONFIG], ), const AdaptiveNavigationItem( icon: Icons.analytics, label: 'Analytics', route: '/analytics', requiredPermissions: [PermissionMatrix.DASHBOARD_ANALYTICS], ), const AdaptiveNavigationItem( icon: Icons.security, label: 'Sécurité', route: '/security', requiredPermissions: [PermissionMatrix.SYSTEM_SECURITY], ), ]; return _buildDrawer( context, 'Super Administrateur', const Color(0xFF6C5CE7), Icons.admin_panel_settings, items, ); } /// Drawer pour Org Admin Widget _buildOrgAdminDrawer(BuildContext context) { final items = [ const AdaptiveNavigationItem( icon: Icons.dashboard, label: 'Control Panel', route: '/dashboard', requiredPermissions: [PermissionMatrix.DASHBOARD_VIEW], ), const AdaptiveNavigationItem( icon: Icons.people, label: 'Membres', route: '/members', requiredPermissions: [PermissionMatrix.MEMBERS_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.account_balance_wallet, label: 'Finances', route: '/finances', requiredPermissions: [PermissionMatrix.FINANCES_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.event, label: 'Événements', route: '/events', requiredPermissions: [PermissionMatrix.EVENTS_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.volunteer_activism, label: 'Solidarité', route: '/solidarity', requiredPermissions: [PermissionMatrix.SOLIDARITY_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.assessment, label: 'Rapports', route: '/reports', requiredPermissions: [PermissionMatrix.REPORTS_GENERATE], ), const AdaptiveNavigationItem( icon: Icons.settings, label: 'Configuration', route: '/org-settings', requiredPermissions: [PermissionMatrix.ORG_CONFIG], ), ]; return _buildDrawer( context, 'Administrateur', const Color(0xFF0984E3), Icons.business_center, items, ); } /// Drawer pour Modérateur Widget _buildModeratorDrawer(BuildContext context) { final items = [ const AdaptiveNavigationItem( icon: Icons.dashboard, label: 'Management Hub', route: '/dashboard', requiredPermissions: [PermissionMatrix.DASHBOARD_VIEW], ), const AdaptiveNavigationItem( icon: Icons.gavel, label: 'Modération', route: '/moderation', requiredPermissions: [PermissionMatrix.MODERATION_CONTENT], ), const AdaptiveNavigationItem( icon: Icons.people, label: 'Membres', route: '/members', requiredPermissions: [PermissionMatrix.MEMBERS_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.event, label: 'Événements', route: '/events', requiredPermissions: [PermissionMatrix.EVENTS_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.message, label: 'Communication', route: '/communication', requiredPermissions: [PermissionMatrix.COMM_MODERATE], ), ]; return _buildDrawer( context, 'Modérateur', const Color(0xFFE17055), Icons.manage_accounts, items, ); } /// Drawer pour Membre Actif Widget _buildActiveMemberDrawer(BuildContext context) { final items = [ const AdaptiveNavigationItem( icon: Icons.dashboard, label: 'Activity Center', route: '/dashboard', requiredPermissions: [PermissionMatrix.DASHBOARD_VIEW], ), const AdaptiveNavigationItem( icon: Icons.person, label: 'Mon Profil', route: '/profile', requiredPermissions: [PermissionMatrix.MEMBERS_VIEW_OWN], ), const AdaptiveNavigationItem( icon: Icons.event, label: 'Événements', route: '/events', requiredPermissions: [PermissionMatrix.EVENTS_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.volunteer_activism, label: 'Solidarité', route: '/solidarity', requiredPermissions: [PermissionMatrix.SOLIDARITY_VIEW_ALL], ), const AdaptiveNavigationItem( icon: Icons.payment, label: 'Mes Cotisations', route: '/my-finances', requiredPermissions: [PermissionMatrix.FINANCES_VIEW_OWN], ), const AdaptiveNavigationItem( icon: Icons.message, label: 'Messages', route: '/messages', requiredPermissions: [PermissionMatrix.DASHBOARD_VIEW], ), ]; return _buildDrawer( context, 'Membre Actif', const Color(0xFF00B894), Icons.groups, items, ); } /// Drawer pour Membre Simple Widget _buildSimpleMemberDrawer(BuildContext context) { final items = [ const AdaptiveNavigationItem( icon: Icons.dashboard, label: 'Mon Espace', route: '/dashboard', requiredPermissions: [PermissionMatrix.DASHBOARD_VIEW], ), const AdaptiveNavigationItem( icon: Icons.person, label: 'Mon Profil', route: '/profile', requiredPermissions: [PermissionMatrix.MEMBERS_VIEW_OWN], ), const AdaptiveNavigationItem( icon: Icons.event, label: 'Événements', route: '/events', requiredPermissions: [PermissionMatrix.EVENTS_VIEW_PUBLIC], ), const AdaptiveNavigationItem( icon: Icons.payment, label: 'Mes Cotisations', route: '/my-finances', requiredPermissions: [PermissionMatrix.FINANCES_VIEW_OWN], ), const AdaptiveNavigationItem( icon: Icons.help, label: 'Aide', route: '/help', requiredPermissions: [], ), ]; return _buildDrawer( context, 'Membre', const Color(0xFF00CEC9), Icons.person, items, ); } /// Drawer pour Visiteur Widget _buildVisitorDrawer(BuildContext context) { final items = [ const AdaptiveNavigationItem( icon: Icons.home, label: 'Accueil', route: '/dashboard', requiredPermissions: [], ), const AdaptiveNavigationItem( icon: Icons.info, label: 'À Propos', route: '/about', requiredPermissions: [], ), const AdaptiveNavigationItem( icon: Icons.event, label: 'Événements Publics', route: '/public-events', requiredPermissions: [PermissionMatrix.EVENTS_VIEW_PUBLIC], ), const AdaptiveNavigationItem( icon: Icons.contact_mail, label: 'Contact', route: '/contact', requiredPermissions: [], ), const AdaptiveNavigationItem( icon: Icons.login, label: 'Se Connecter', route: '/login', requiredPermissions: [], ), ]; return _buildDrawer( context, 'Visiteur', const Color(0xFF6C5CE7), Icons.waving_hand, items, ); } /// Drawer basique de fallback Widget _buildBasicDrawer(BuildContext context) { return _buildDrawer( context, 'UnionFlow', Colors.grey, Icons.dashboard, [ const AdaptiveNavigationItem( icon: Icons.home, label: 'Accueil', route: '/dashboard', ), ], ); } /// Drawer de chargement Widget _buildLoadingDrawer(BuildContext context) { return Drawer( child: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0xFF6C5CE7), Color(0xFF5A4FCF)], ), ), child: const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Colors.white), ), ), ), ); } /// Construit un drawer avec les éléments spécifiés Widget _buildDrawer( BuildContext context, String title, Color color, IconData icon, List items, ) { return Drawer( child: Column( children: [ // En-tête du drawer _buildDrawerHeader(context, title, color, icon), // Éléments de navigation Expanded( child: ListView( padding: EdgeInsets.zero, children: [ ...items.map((item) => _buildNavigationItem(context, item)), const Divider(), _buildLogoutItem(context), ], ), ), ], ), ); } /// Construit l'en-tête du drawer Widget _buildDrawerHeader( BuildContext context, String title, Color color, IconData icon, ) { return DrawerHeader( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [color, color.withOpacity(0.8)], ), ), child: BlocBuilder( builder: (context, state) { if (state is AuthAuthenticated) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, color: Colors.white, size: 32), const SizedBox(width: 12), Text( title, style: const TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 16), Text( state.user.fullName, style: const TextStyle( color: Colors.white, fontSize: 16, ), ), Text( state.user.email, style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 14, ), ), ], ); } return Row( children: [ Icon(icon, color: Colors.white, size: 32), const SizedBox(width: 12), Text( title, style: const TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold, ), ), ], ); }, ), ); } /// Construit un élément de navigation Widget _buildNavigationItem( BuildContext context, AdaptiveNavigationItem item, ) { return SecureWidget( requiredPermissions: item.requiredPermissions, child: ListTile( leading: Icon(item.icon, color: item.color), title: Text(item.label), trailing: item.badge != null ? Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(12), ), child: Text( item.badge!, style: const TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold, ), ), ) : null, onTap: () { Navigator.of(context).pop(); onNavigate(item.route); }, ), ); } /// Construit l'élément de déconnexion Widget _buildLogoutItem(BuildContext context) { return ListTile( leading: const Icon(Icons.logout, color: Colors.red), title: const Text( 'Déconnexion', style: TextStyle(color: Colors.red), ), onTap: () { Navigator.of(context).pop(); onLogout(); }, ); } }