282 lines
9.0 KiB
Dart
Executable File
282 lines
9.0 KiB
Dart
Executable File
import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales
|
|
import 'package:flutter/material.dart';
|
|
import 'package:hive_flutter/hive_flutter.dart';
|
|
import 'package:geosector_app/core/constants/app_keys.dart';
|
|
import 'package:geosector_app/presentation/widgets/dashboard_layout.dart';
|
|
import 'package:geosector_app/presentation/widgets/badged_navigation_destination.dart';
|
|
|
|
// Import des pages utilisateur
|
|
import 'user_dashboard_home_page.dart';
|
|
import 'user_statistics_page.dart';
|
|
import 'user_history_page.dart';
|
|
import 'user_communication_page.dart';
|
|
import 'user_map_page.dart';
|
|
import 'user_field_mode_page.dart';
|
|
|
|
class UserDashboardPage extends StatefulWidget {
|
|
const UserDashboardPage({super.key});
|
|
|
|
@override
|
|
State<UserDashboardPage> createState() => _UserDashboardPageState();
|
|
}
|
|
|
|
class _UserDashboardPageState extends State<UserDashboardPage> {
|
|
int _selectedIndex = 0;
|
|
|
|
// Liste des pages à afficher
|
|
late final List<Widget> _pages;
|
|
|
|
// Référence à la boîte Hive pour les paramètres
|
|
late Box _settingsBox;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_pages = [
|
|
const UserDashboardHomePage(),
|
|
const UserStatisticsPage(),
|
|
const UserHistoryPage(),
|
|
const UserCommunicationPage(),
|
|
const UserMapPage(),
|
|
const UserFieldModePage(),
|
|
];
|
|
|
|
// Initialiser et charger les paramètres
|
|
_initSettings();
|
|
}
|
|
|
|
// Initialiser la boîte de paramètres et charger les préférences
|
|
Future<void> _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('selectedPageIndex');
|
|
if (savedIndex != null &&
|
|
savedIndex is int &&
|
|
savedIndex >= 0 &&
|
|
savedIndex < _pages.length) {
|
|
setState(() {
|
|
_selectedIndex = savedIndex;
|
|
});
|
|
}
|
|
} 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('selectedPageIndex', _selectedIndex);
|
|
} catch (e) {
|
|
debugPrint('Erreur lors de la sauvegarde des paramètres: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// Utiliser l'instance globale définie dans app.dart
|
|
final hasOperation = userRepository.getCurrentOperation() != null;
|
|
final hasSectors = userRepository.getUserSectors().isNotEmpty;
|
|
final isStandardUser = userRepository.currentUser != null &&
|
|
userRepository.currentUser!.role ==
|
|
'1'; // Rôle 1 = utilisateur standard
|
|
|
|
// Si l'utilisateur est standard et n'a pas d'opération assignée ou n'a pas de secteur, afficher un message spécial
|
|
final bool shouldShowNoOperationMessage = isStandardUser && !hasOperation;
|
|
final bool shouldShowNoSectorMessage = isStandardUser && !hasSectors;
|
|
|
|
// Si l'utilisateur n'a pas d'opération ou de secteur, utiliser DashboardLayout avec un body spécial
|
|
if (shouldShowNoOperationMessage) {
|
|
return DashboardLayout(
|
|
title: 'GEOSECTOR',
|
|
selectedIndex: 0, // Index par défaut
|
|
onDestinationSelected: (index) {
|
|
// Ne rien faire car l'utilisateur ne peut pas naviguer
|
|
},
|
|
destinations: const [
|
|
NavigationDestination(
|
|
icon: Icon(Icons.warning_outlined),
|
|
selectedIcon: Icon(Icons.warning),
|
|
label: 'Accès restreint',
|
|
),
|
|
],
|
|
body: _buildNoOperationMessage(context),
|
|
);
|
|
}
|
|
|
|
if (shouldShowNoSectorMessage) {
|
|
return DashboardLayout(
|
|
title: 'GEOSECTOR',
|
|
selectedIndex: 0, // Index par défaut
|
|
onDestinationSelected: (index) {
|
|
// Ne rien faire car l'utilisateur ne peut pas naviguer
|
|
},
|
|
destinations: const [
|
|
NavigationDestination(
|
|
icon: Icon(Icons.warning_outlined),
|
|
selectedIcon: Icon(Icons.warning),
|
|
label: 'Accès restreint',
|
|
),
|
|
],
|
|
body: _buildNoSectorMessage(context),
|
|
);
|
|
}
|
|
|
|
// Utilisateur normal avec accès complet
|
|
return DashboardLayout(
|
|
title: 'GEOSECTOR',
|
|
selectedIndex: _selectedIndex,
|
|
onDestinationSelected: (index) {
|
|
setState(() {
|
|
_selectedIndex = index;
|
|
_saveSettings(); // Sauvegarder l'index de page sélectionné
|
|
});
|
|
},
|
|
destinations: [
|
|
const NavigationDestination(
|
|
icon: Icon(Icons.dashboard_outlined),
|
|
selectedIcon: Icon(Icons.dashboard),
|
|
label: 'Tableau de bord',
|
|
),
|
|
const NavigationDestination(
|
|
icon: Icon(Icons.bar_chart_outlined),
|
|
selectedIcon: Icon(Icons.bar_chart),
|
|
label: 'Stats',
|
|
),
|
|
const NavigationDestination(
|
|
icon: Icon(Icons.history_outlined),
|
|
selectedIcon: Icon(Icons.history),
|
|
label: 'Historique',
|
|
),
|
|
createBadgedNavigationDestination(
|
|
icon: const Icon(Icons.chat_outlined),
|
|
selectedIcon: const Icon(Icons.chat),
|
|
label: 'Messages',
|
|
showBadge: true,
|
|
),
|
|
const NavigationDestination(
|
|
icon: Icon(Icons.map_outlined),
|
|
selectedIcon: Icon(Icons.map),
|
|
label: 'Carte',
|
|
),
|
|
const NavigationDestination(
|
|
icon: Icon(Icons.explore_outlined),
|
|
selectedIcon: Icon(Icons.explore),
|
|
label: 'Terrain',
|
|
),
|
|
],
|
|
body: _pages[_selectedIndex],
|
|
);
|
|
}
|
|
|
|
// Message pour les utilisateurs sans opération assignée
|
|
Widget _buildNoOperationMessage(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
|
|
return Center(
|
|
child: Container(
|
|
padding: const EdgeInsets.all(24),
|
|
constraints: const BoxConstraints(maxWidth: 500),
|
|
decoration: BoxDecoration(
|
|
color: theme.colorScheme.surface,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: theme.shadowColor.withOpacity(0.1),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(
|
|
Icons.warning_amber_rounded,
|
|
size: 80,
|
|
color: theme.colorScheme.error,
|
|
),
|
|
const SizedBox(height: 24),
|
|
Text(
|
|
'Aucune opération assignée',
|
|
style: theme.textTheme.headlineSmall?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
color: theme.colorScheme.primary,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
'Vous n\'avez pas encore été affecté à une opération. Veuillez contacter votre administrateur pour obtenir un accès.',
|
|
style: theme.textTheme.bodyLarge?.copyWith(
|
|
color: theme.colorScheme.onSurface.withOpacity(0.7),
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Message pour les utilisateurs sans secteur assigné
|
|
Widget _buildNoSectorMessage(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
|
|
return Center(
|
|
child: Container(
|
|
padding: const EdgeInsets.all(24),
|
|
constraints: const BoxConstraints(maxWidth: 500),
|
|
decoration: BoxDecoration(
|
|
color: theme.colorScheme.surface,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: theme.shadowColor.withOpacity(0.1),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(
|
|
Icons.map_outlined,
|
|
size: 80,
|
|
color: theme.colorScheme.error,
|
|
),
|
|
const SizedBox(height: 24),
|
|
Text(
|
|
'Aucun secteur assigné',
|
|
style: theme.textTheme.headlineSmall?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
color: theme.colorScheme.primary,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
'Vous n\'êtes affecté sur aucun secteur. Contactez votre administrateur pour qu\'il vous en affecte au moins un.',
|
|
style: theme.textTheme.bodyLarge?.copyWith(
|
|
color: theme.colorScheme.onSurface.withOpacity(0.7),
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Affiche le formulaire de passage
|
|
}
|