refactor: Simplifier DashboardLayout/AppScaffold (tâche #74)
Centralisation et simplification de l'architecture de navigation : CRÉATIONS : - navigation_config.dart : Configuration centralisée de la navigation * Toutes les destinations (admin/user) * Logique de navigation (index → route) * Résolution inverse (route → index) * Titres et utilitaires - backgrounds/dots_painter.dart : Painter de points décoratifs * Extrait depuis AppScaffold et AdminScaffold * Paramétrable (opacité, densité, seed) * Réutilisable - backgrounds/gradient_background.dart : Fond dégradé * Gère les couleurs admin (rouge) / user (vert) * Option pour afficher/masquer les points * Widget indépendant SIMPLIFICATIONS : - app_scaffold.dart : 426 → 192 lignes (-55%) * Utilise NavigationConfig au lieu de NavigationHelper * Utilise GradientBackground au lieu de code dupliqué * Suppression de DotsPainter local - dashboard_layout.dart : 140 → 77 lignes (-45%) * Suppression validations excessives (try/catch, vérifications) * Code épuré et plus lisible SUPPRESSIONS : - admin_scaffold.dart : Supprimé (207 lignes) * Obsolète depuis unification avec AppScaffold * Code dupliqué avec AppScaffold * AdminNavigationHelper fusionné dans NavigationConfig RÉSULTATS : - Avant : 773 lignes (AppScaffold + AdminScaffold + DashboardLayout) - Après : 623 lignes (tout inclus) - Réduction nette : -150 lignes (-19%) - Architecture plus claire et maintenable - Aucune duplication de code - Navigation centralisée en un seul endroit Résout tâche #74 du PLANNING-2026-Q1.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
259
app/lib/core/config/navigation_config.dart
Executable file
259
app/lib/core/config/navigation_config.dart
Executable file
@@ -0,0 +1,259 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:geosector_app/presentation/widgets/badged_navigation_destination.dart';
|
||||
|
||||
/// Configuration centralisée de la navigation pour toute l'application
|
||||
/// Gère les destinations, routes et logique de navigation pour admin et user
|
||||
class NavigationConfig {
|
||||
// ========================================
|
||||
// DESTINATIONS DE NAVIGATION
|
||||
// ========================================
|
||||
|
||||
/// Destinations communes à tous les rôles
|
||||
static const List<NavigationDestination> _commonDestinations = [
|
||||
NavigationDestination(
|
||||
icon: Icon(Icons.dashboard_outlined),
|
||||
selectedIcon: Icon(Icons.dashboard),
|
||||
label: 'Tableau de bord',
|
||||
),
|
||||
NavigationDestination(
|
||||
icon: Icon(Icons.history_outlined),
|
||||
selectedIcon: Icon(Icons.history),
|
||||
label: 'Historique',
|
||||
),
|
||||
NavigationDestination(
|
||||
icon: Icon(Icons.map_outlined),
|
||||
selectedIcon: Icon(Icons.map),
|
||||
label: 'Carte',
|
||||
),
|
||||
];
|
||||
|
||||
/// Destination Messages avec badge (commune à tous)
|
||||
static NavigationDestination get _messagesDestination {
|
||||
return createBadgedNavigationDestination(
|
||||
icon: const Icon(Icons.chat_outlined),
|
||||
selectedIcon: const Icon(Icons.chat),
|
||||
label: 'Messages',
|
||||
showBadge: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// Destination Terrain (user uniquement)
|
||||
static const NavigationDestination _fieldModeDestination = NavigationDestination(
|
||||
icon: Icon(Icons.explore_outlined),
|
||||
selectedIcon: Icon(Icons.explore),
|
||||
label: 'Terrain',
|
||||
);
|
||||
|
||||
/// Destinations admin desktop uniquement
|
||||
static const List<NavigationDestination> _adminDesktopDestinations = [
|
||||
NavigationDestination(
|
||||
icon: Icon(Icons.business_outlined),
|
||||
selectedIcon: Icon(Icons.business),
|
||||
label: 'Amicale & membres',
|
||||
),
|
||||
NavigationDestination(
|
||||
icon: Icon(Icons.calendar_today_outlined),
|
||||
selectedIcon: Icon(Icons.calendar_today),
|
||||
label: 'Opérations',
|
||||
),
|
||||
NavigationDestination(
|
||||
icon: Icon(Icons.analytics_outlined),
|
||||
selectedIcon: Icon(Icons.analytics),
|
||||
label: 'Connexions',
|
||||
),
|
||||
];
|
||||
|
||||
// ========================================
|
||||
// GETTERS DE DESTINATIONS
|
||||
// ========================================
|
||||
|
||||
/// Obtenir la liste des destinations selon le rôle et le device
|
||||
static List<NavigationDestination> getDestinations({
|
||||
required bool isAdmin,
|
||||
required bool isMobile,
|
||||
}) {
|
||||
final destinations = <NavigationDestination>[];
|
||||
|
||||
// Ajouter les destinations communes
|
||||
destinations.addAll(_commonDestinations);
|
||||
|
||||
// Ajouter Messages (avec badge)
|
||||
destinations.add(_messagesDestination);
|
||||
|
||||
if (isAdmin) {
|
||||
// Admin : ajouter les pages supplémentaires sur desktop uniquement
|
||||
if (!isMobile) {
|
||||
destinations.addAll(_adminDesktopDestinations);
|
||||
}
|
||||
} else {
|
||||
// User : ajouter la page Terrain
|
||||
destinations.add(_fieldModeDestination);
|
||||
}
|
||||
|
||||
return destinations;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NAVIGATION (INDEX → ROUTE)
|
||||
// ========================================
|
||||
|
||||
/// Naviguer vers une page selon l'index et le rôle
|
||||
static void navigateToIndex(BuildContext context, int index, bool isAdmin) {
|
||||
if (isAdmin) {
|
||||
_navigateAdminIndex(context, index);
|
||||
} else {
|
||||
_navigateUserIndex(context, index);
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigation pour les admins
|
||||
static void _navigateAdminIndex(BuildContext context, int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
context.go('/admin');
|
||||
break;
|
||||
case 1:
|
||||
context.go('/admin/history');
|
||||
break;
|
||||
case 2:
|
||||
context.go('/admin/map');
|
||||
break;
|
||||
case 3:
|
||||
context.go('/admin/messages');
|
||||
break;
|
||||
case 4:
|
||||
context.go('/admin/amicale');
|
||||
break;
|
||||
case 5:
|
||||
context.go('/admin/operations');
|
||||
break;
|
||||
case 6:
|
||||
context.go('/admin/connexions');
|
||||
break;
|
||||
default:
|
||||
context.go('/admin');
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigation pour les utilisateurs standards
|
||||
static void _navigateUserIndex(BuildContext context, int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
context.go('/user/dashboard');
|
||||
break;
|
||||
case 1:
|
||||
context.go('/user/history');
|
||||
break;
|
||||
case 2:
|
||||
context.go('/user/map');
|
||||
break;
|
||||
case 3:
|
||||
context.go('/user/messages');
|
||||
break;
|
||||
case 4:
|
||||
context.go('/user/field-mode');
|
||||
break;
|
||||
default:
|
||||
context.go('/user/dashboard');
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// RÉSOLUTION (ROUTE → INDEX)
|
||||
// ========================================
|
||||
|
||||
/// Obtenir l'index selon la route actuelle et le rôle
|
||||
static int getIndexFromRoute(String route, bool isAdmin) {
|
||||
// Enlever les paramètres de query si présents
|
||||
final cleanRoute = route.split('?').first;
|
||||
|
||||
if (isAdmin) {
|
||||
return _getAdminIndexFromRoute(cleanRoute);
|
||||
} else {
|
||||
return _getUserIndexFromRoute(cleanRoute);
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtenir l'index admin depuis la route
|
||||
static int _getAdminIndexFromRoute(String route) {
|
||||
if (route.contains('/admin/history')) return 1;
|
||||
if (route.contains('/admin/map')) return 2;
|
||||
if (route.contains('/admin/messages')) return 3;
|
||||
if (route.contains('/admin/amicale')) return 4;
|
||||
if (route.contains('/admin/operations')) return 5;
|
||||
if (route.contains('/admin/connexions')) return 6;
|
||||
return 0; // Dashboard par défaut
|
||||
}
|
||||
|
||||
/// Obtenir l'index user depuis la route
|
||||
static int _getUserIndexFromRoute(String route) {
|
||||
if (route.contains('/user/history')) return 1;
|
||||
if (route.contains('/user/map')) return 2;
|
||||
if (route.contains('/user/messages')) return 3;
|
||||
if (route.contains('/user/field-mode')) return 4;
|
||||
return 0; // Dashboard par défaut
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// UTILITAIRES
|
||||
// ========================================
|
||||
|
||||
/// Obtenir le nom de la page selon l'index et le rôle
|
||||
static String getPageNameFromIndex(int index, bool isAdmin) {
|
||||
if (isAdmin) {
|
||||
return _getAdminPageName(index);
|
||||
} else {
|
||||
return _getUserPageName(index);
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtenir le nom de page admin
|
||||
static String _getAdminPageName(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return 'dashboard';
|
||||
case 1:
|
||||
return 'history';
|
||||
case 2:
|
||||
return 'map';
|
||||
case 3:
|
||||
return 'messages';
|
||||
case 4:
|
||||
return 'amicale';
|
||||
case 5:
|
||||
return 'operations';
|
||||
case 6:
|
||||
return 'connexions';
|
||||
default:
|
||||
return 'dashboard';
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtenir le nom de page user
|
||||
static String _getUserPageName(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return 'dashboard';
|
||||
case 1:
|
||||
return 'history';
|
||||
case 2:
|
||||
return 'map';
|
||||
case 3:
|
||||
return 'messages';
|
||||
case 4:
|
||||
return 'field-mode';
|
||||
default:
|
||||
return 'dashboard';
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// TITRES ET LABELS
|
||||
// ========================================
|
||||
|
||||
/// Obtenir le titre du dashboard selon le rôle
|
||||
static String getDashboardTitle(bool isAdmin) {
|
||||
return isAdmin ? 'Tableau de bord Administration' : 'GEOSECTOR';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user