import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:geosector_app/presentation/widgets/dashboard_layout.dart'; import 'package:geosector_app/presentation/widgets/badged_navigation_destination.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; import 'dart:math' as math; // Import des pages admin import 'admin_dashboard_home_page.dart'; import 'admin_statistics_page.dart'; import 'admin_history_page.dart'; import 'admin_communication_page.dart'; import 'admin_map_page.dart'; import 'admin_amicale_page.dart'; import 'admin_operations_page.dart'; /// Class pour dessiner les petits points blancs sur le fond class DotsPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = Colors.white.withOpacity(0.5) ..style = PaintingStyle.fill; final random = math.Random(42); // Seed fixe pour consistance final numberOfDots = (size.width * size.height) ~/ 1500; for (int i = 0; i < numberOfDots; i++) { final x = random.nextDouble() * size.width; final y = random.nextDouble() * size.height; final radius = 1.0 + random.nextDouble() * 2.0; canvas.drawCircle(Offset(x, y), radius, paint); } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; } class AdminDashboardPage extends StatefulWidget { const AdminDashboardPage({super.key}); @override State createState() => _AdminDashboardPageState(); } class _AdminDashboardPageState extends State with WidgetsBindingObserver { int _selectedIndex = 0; // Pages seront construites dynamiquement dans build() // Référence à la boîte Hive pour les paramètres late Box _settingsBox; // Listener pour les changements de paramètres late ValueListenable> _settingsListenable; // Liste des éléments de navigation de base (toujours visibles) final List<_NavigationItem> _baseNavigationItems = [ const _NavigationItem( label: 'Tableau de bord', icon: Icons.dashboard_outlined, selectedIcon: Icons.dashboard, pageType: _PageType.dashboardHome, ), const _NavigationItem( label: 'Statistiques', icon: Icons.bar_chart_outlined, selectedIcon: Icons.bar_chart, pageType: _PageType.statistics, ), const _NavigationItem( label: 'Historique', icon: Icons.history_outlined, selectedIcon: Icons.history, pageType: _PageType.history, ), const _NavigationItem( label: 'Messages', icon: Icons.chat_outlined, selectedIcon: Icons.chat, pageType: _PageType.communication, ), const _NavigationItem( label: 'Carte', icon: Icons.map_outlined, selectedIcon: Icons.map, pageType: _PageType.map, ), ]; // Éléments de navigation supplémentaires pour le rôle 2 final List<_NavigationItem> _adminNavigationItems = [ const _NavigationItem( label: 'Amicale & membres', icon: Icons.business_outlined, selectedIcon: Icons.business, pageType: _PageType.amicale, requiredRole: 2, ), const _NavigationItem( label: 'Opérations', icon: Icons.calendar_today_outlined, selectedIcon: Icons.calendar_today, pageType: _PageType.operations, requiredRole: 2, ), ]; // Construire la page basée sur le type Widget _buildPage(_PageType pageType) { switch (pageType) { case _PageType.dashboardHome: return const AdminDashboardHomePage(); case _PageType.statistics: return const AdminStatisticsPage(); case _PageType.history: return const AdminHistoryPage(); case _PageType.communication: return const AdminCommunicationPage(); case _PageType.map: return const AdminMapPage(); case _PageType.amicale: return AdminAmicalePage( userRepository: userRepository, amicaleRepository: amicaleRepository, membreRepository: membreRepository, passageRepository: passageRepository, operationRepository: operationRepository, ); case _PageType.operations: return AdminOperationsPage( operationRepository: operationRepository, userRepository: userRepository, ); } } // Construire la liste des destinations de navigation en fonction du rôle List _buildNavigationDestinations() { final destinations = []; final currentUser = userRepository.getCurrentUser(); final size = MediaQuery.of(context).size; final isMobile = size.width <= 900; // Ajouter les éléments de base for (final item in _baseNavigationItems) { // Utiliser createBadgedNavigationDestination pour les messages if (item.label == 'Messages') { destinations.add( createBadgedNavigationDestination( icon: Icon(item.icon), selectedIcon: Icon(item.selectedIcon), label: item.label, showBadge: true, ), ); } else { destinations.add( NavigationDestination( icon: Icon(item.icon), selectedIcon: Icon(item.selectedIcon), label: item.label, ), ); } } // Ajouter les éléments admin si l'utilisateur a le rôle requis if (currentUser?.role == 2) { for (final item in _adminNavigationItems) { // En mobile, exclure "Amicale & membres" et "Opérations" if (isMobile && (item.label == 'Amicale & membres' || item.label == 'Opérations')) { continue; } if (item.requiredRole == null || item.requiredRole == 2) { // Utiliser createBadgedNavigationDestination pour les messages if (item.label == 'Messages') { destinations.add( createBadgedNavigationDestination( icon: Icon(item.icon), selectedIcon: Icon(item.selectedIcon), label: item.label, showBadge: true, ), ); } else { destinations.add( NavigationDestination( icon: Icon(item.icon), selectedIcon: Icon(item.selectedIcon), label: item.label, ), ); } } } } return destinations; } // Construire la liste des pages en fonction du rôle List _buildPages() { final pages = []; final currentUser = userRepository.getCurrentUser(); final size = MediaQuery.of(context).size; final isMobile = size.width <= 900; // Ajouter les pages de base for (final item in _baseNavigationItems) { pages.add(_buildPage(item.pageType)); } // Ajouter les pages admin si l'utilisateur a le rôle requis if (currentUser?.role == 2) { for (final item in _adminNavigationItems) { // En mobile, exclure "Amicale & membres" et "Opérations" if (isMobile && (item.label == 'Amicale & membres' || item.label == 'Opérations')) { continue; } if (item.requiredRole == null || item.requiredRole == 2) { pages.add(_buildPage(item.pageType)); } } } return pages; } @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); try { debugPrint('Initialisation de AdminDashboardPage'); // Vérifier que userRepository est correctement initialisé debugPrint('userRepository est correctement initialisé'); final currentUser = userRepository.getCurrentUser(); if (currentUser == null) { debugPrint('ERREUR: Aucun utilisateur connecté dans AdminDashboardPage'); } else { debugPrint('Utilisateur connecté: ${currentUser.username} (${currentUser.id})'); } userRepository.addListener(_handleUserRepositoryChanges); // Les pages seront construites dynamiquement dans build() // Initialiser et charger les paramètres _initSettings().then((_) { // Écouter les changements de la boîte de paramètres après l'initialisation _settingsListenable = _settingsBox.listenable(keys: ['adminSelectedPageIndex']); _settingsListenable.addListener(_onSettingsChanged); }); // Vérifier si des données sont en cours de chargement WidgetsBinding.instance.addPostFrameCallback((_) { _checkLoadingState(); }); } catch (e) { debugPrint('ERREUR CRITIQUE dans AdminDashboardPage.initState: $e'); } } @override void dispose() { WidgetsBinding.instance.removeObserver(this); userRepository.removeListener(_handleUserRepositoryChanges); _settingsListenable.removeListener(_onSettingsChanged); super.dispose(); } // Méthode pour gérer les changements d'état du UserRepository void _handleUserRepositoryChanges() { _checkLoadingState(); } // Méthode pour gérer les changements de paramètres void _onSettingsChanged() { final newIndex = _settingsBox.get('adminSelectedPageIndex'); if (newIndex != null && newIndex is int && newIndex != _selectedIndex) { setState(() { _selectedIndex = newIndex; }); } } // Méthode pour vérifier l'état de chargement (barre de progression désactivée) void _checkLoadingState() { // La barre de progression est désactivée, ne rien faire } // Initialiser la boîte de paramètres et charger les préférences Future _initSettings() async { try { // Ouvrir la boîte de paramètres si elle n'est pas déjà ouverte if (!Hive.isBoxOpen(AppKeys.settingsBoxName)) { _settingsBox = await Hive.openBox(AppKeys.settingsBoxName); } else { _settingsBox = Hive.box(AppKeys.settingsBoxName); } // Charger l'index de page sélectionné final savedIndex = _settingsBox.get('adminSelectedPageIndex'); // Vérifier si l'index sauvegardé est valide if (savedIndex != null && savedIndex is int) { debugPrint('Index sauvegardé trouvé: $savedIndex'); // La validation de l'index sera faite dans build() setState(() { _selectedIndex = savedIndex; }); debugPrint('Index sauvegardé utilisé: $_selectedIndex'); } else { debugPrint( 'Aucun index sauvegardé trouvé, utilisation de l\'index par défaut: 0', ); } } catch (e) { debugPrint('Erreur lors du chargement des paramètres: $e'); } } // Sauvegarder les paramètres utilisateur void _saveSettings() { try { // Sauvegarder l'index de page sélectionné _settingsBox.put('adminSelectedPageIndex', _selectedIndex); } catch (e) { debugPrint('Erreur lors de la sauvegarde des paramètres: $e'); } } @override Widget build(BuildContext context) { // Construire les pages et destinations dynamiquement final pages = _buildPages(); final destinations = _buildNavigationDestinations(); // Valider et ajuster l'index si nécessaire if (_selectedIndex >= pages.length) { _selectedIndex = 0; // Sauvegarder le nouvel index WidgetsBinding.instance.addPostFrameCallback((_) { _saveSettings(); }); } return Stack( children: [ // Fond dégradé avec petits points blancs Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.white, Colors.red.shade300], ), ), child: CustomPaint( painter: DotsPainter(), child: const SizedBox(width: double.infinity, height: double.infinity), ), ), // Contenu de la page DashboardLayout( title: 'Tableau de bord Administration', selectedIndex: _selectedIndex, onDestinationSelected: (index) { setState(() { _selectedIndex = index; _saveSettings(); // Sauvegarder l'index de page sélectionné }); }, destinations: destinations, showNewPassageButton: false, isAdmin: true, body: pages[_selectedIndex], ), ], ); } } // Enum pour les types de pages enum _PageType { dashboardHome, statistics, history, communication, map, amicale, operations, } // Classe pour représenter une destination de navigation avec sa page associée class _NavigationItem { final String label; final IconData icon; final IconData selectedIcon; final _PageType pageType; final int? requiredRole; // null si accessible à tous les rôles const _NavigationItem({ required this.label, required this.icon, required this.selectedIcon, required this.pageType, this.requiredRole, }); }