import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'more_page.dart'; import '../../features/authentication/presentation/bloc/auth_bloc.dart'; import '../../features/authentication/data/models/user_role.dart'; import '../../shared/design_system/unionflow_design_system.dart'; import '../../features/dashboard/presentation/pages/role_dashboards/role_dashboards.dart'; import '../../features/dashboard/presentation/pages/role_dashboards/org_admin_dashboard_loader.dart'; import '../../features/members/presentation/pages/members_page_wrapper.dart'; import '../../features/events/presentation/pages/events_page_wrapper.dart'; import '../../features/dashboard/presentation/bloc/dashboard_bloc.dart'; import '../di/injection.dart'; /// Layout principal avec navigation hybride /// Bottom Navigation pour les sections principales + Drawer pour fonctions avancées class MainNavigationLayout extends StatefulWidget { const MainNavigationLayout({super.key}); @override State createState() => _MainNavigationLayoutState(); } class _MainNavigationLayoutState extends State { int _selectedIndex = 0; List? _cachedPages; UserRole? _lastRole; String? _lastUserId; /// Obtient le dashboard approprié selon le rôle de l'utilisateur Widget _getDashboardForRole(UserRole role, String userId, String? orgId) { // Admin d'organisation sans orgId (organizationContexts vide) : charger /mes puis dashboard if (role == UserRole.orgAdmin && (orgId == null || orgId.isEmpty)) { return OrgAdminDashboardLoader(userId: userId); } return BlocProvider( create: (context) => getIt() ..add(LoadDashboardData( organizationId: orgId ?? '', userId: userId, )), child: _buildDashboardView(role), ); } Widget _buildDashboardView(UserRole role) { switch (role) { case UserRole.superAdmin: return const SuperAdminDashboard(); case UserRole.orgAdmin: return const OrgAdminDashboard(); case UserRole.moderator: return const ModeratorDashboard(); case UserRole.consultant: return const ConsultantDashboard(); case UserRole.hrManager: return const HRManagerDashboard(); case UserRole.activeMember: return const ActiveMemberDashboard(); case UserRole.simpleMember: return const SimpleMemberDashboard(); case UserRole.visitor: return const VisitorDashboard(); } } /// Obtient les pages et les met en cache pour éviter les rebuilds inutiles List _getPages(UserRole role, String userId, String? orgId) { if (_cachedPages != null && _lastRole == role && _lastUserId == userId) { return _cachedPages!; } debugPrint('🔄 [MainNavigationLayout] Initialisation des pages (Role: $role, User: $userId)'); _lastRole = role; _lastUserId = userId; final canManageMembers = role.hasLevelOrAbove(UserRole.hrManager); _cachedPages = [ _getDashboardForRole(role, userId, orgId), if (canManageMembers) const MembersPageWrapper(), const EventsPageWrapper(), const MorePage(), ]; return _cachedPages!; } @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { if (state is! AuthAuthenticated) { return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } final orgId = state.user.organizationContexts.isNotEmpty ? state.user.organizationContexts.first.organizationId : null; final pages = _getPages(state.effectiveRole, state.user.id, orgId); final safeIndex = _selectedIndex >= pages.length ? 0 : _selectedIndex; return Scaffold( backgroundColor: ColorTokens.background, body: SafeArea( top: true, // Respecte le StatusBar bottom: false, // Le BottomNavigationBar gère son propre SafeArea child: IndexedStack( index: safeIndex, children: pages, ), ), bottomNavigationBar: SafeArea( top: false, child: Container( decoration: const BoxDecoration( color: ColorTokens.surface, boxShadow: [ BoxShadow( color: ColorTokens.shadow, blurRadius: 8, offset: Offset(0, -2), ), ], ), child: BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: safeIndex, onTap: (index) { setState(() { _selectedIndex = index; }); }, backgroundColor: ColorTokens.surface, selectedItemColor: ColorTokens.primary, unselectedItemColor: ColorTokens.onSurfaceVariant, selectedLabelStyle: TypographyTokens.labelSmall.copyWith( fontWeight: FontWeight.w600, ), unselectedLabelStyle: TypographyTokens.labelSmall, elevation: 0, // Géré par le Container items: [ const BottomNavigationBarItem( icon: Icon(Icons.dashboard_outlined), activeIcon: Icon(Icons.dashboard), label: 'Dashboard', ), if (state.effectiveRole.hasLevelOrAbove(UserRole.hrManager)) const BottomNavigationBarItem( icon: Icon(Icons.people_outline), activeIcon: Icon(Icons.people), label: 'Membres', ), const BottomNavigationBarItem( icon: Icon(Icons.event_outlined), activeIcon: Icon(Icons.event), label: 'Événements', ), const BottomNavigationBarItem( icon: Icon(Icons.more_horiz_outlined), activeIcon: Icon(Icons.more_horiz), label: 'Plus', ), ], ), ), ), ); }, ); } }