175 lines
6.3 KiB
Dart
175 lines
6.3 KiB
Dart
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<MainNavigationLayout> createState() => _MainNavigationLayoutState();
|
|
}
|
|
|
|
class _MainNavigationLayoutState extends State<MainNavigationLayout> {
|
|
int _selectedIndex = 0;
|
|
List<Widget>? _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<DashboardBloc>(
|
|
create: (context) => getIt<DashboardBloc>()
|
|
..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<Widget> _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<AuthBloc, AuthState>(
|
|
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',
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|