Amélioration de la splash_page et du login
This commit is contained in:
384
app/lib/app.dart
384
app/lib/app.dart
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:geosector_app/core/theme/app_theme.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:geosector_app/core/services/api_service.dart';
|
||||
import 'package:geosector_app/core/repositories/user_repository.dart';
|
||||
import 'package:geosector_app/core/repositories/operation_repository.dart';
|
||||
@@ -13,7 +13,6 @@ import 'package:geosector_app/core/services/sync_service.dart';
|
||||
import 'package:geosector_app/core/services/connectivity_service.dart';
|
||||
import 'package:geosector_app/presentation/auth/splash_page.dart';
|
||||
import 'package:geosector_app/presentation/auth/login_page.dart';
|
||||
import 'package:geosector_app/presentation/auth/register_page.dart';
|
||||
import 'package:geosector_app/presentation/admin/admin_dashboard_page.dart';
|
||||
import 'package:geosector_app/presentation/user/user_dashboard_page.dart';
|
||||
|
||||
@@ -28,239 +27,202 @@ final amicaleRepository = AmicaleRepository(apiService);
|
||||
final syncService = SyncService(userRepository: userRepository);
|
||||
final connectivityService = ConnectivityService();
|
||||
|
||||
class GeoSectorApp extends StatelessWidget {
|
||||
const GeoSectorApp({super.key});
|
||||
class GeosectorApp extends StatelessWidget {
|
||||
const GeosectorApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Utiliser directement le router sans provider
|
||||
final router = GoRouter(
|
||||
return MaterialApp.router(
|
||||
title: 'GeoSector',
|
||||
theme: AppTheme.lightTheme,
|
||||
darkTheme: AppTheme.darkTheme,
|
||||
themeMode: ThemeMode.system,
|
||||
routerConfig: _createRouter(),
|
||||
debugShowCheckedModeBanner: false,
|
||||
);
|
||||
}
|
||||
|
||||
/// Création du routeur avec configuration pour URLs propres
|
||||
GoRouter _createRouter() {
|
||||
return GoRouter(
|
||||
initialLocation: '/',
|
||||
debugLogDiagnostics: true,
|
||||
refreshListenable:
|
||||
userRepository, // Écouter les changements d'état d'authentification
|
||||
// Gestionnaire de redirection global - intercepte toutes les navigations
|
||||
redirect: (context, state) {
|
||||
// Détection manuelle des paramètres d'URL pour le Web
|
||||
if (kIsWeb && state.uri.path == '/login') {
|
||||
try {
|
||||
// Obtenir le paramètre 'type' de l'URL actuelle
|
||||
final typeParam = state.uri.queryParameters['type'];
|
||||
|
||||
// Obtenir l'URL brute du navigateur pour comparer
|
||||
final rawUri = Uri.parse(Uri.base.toString());
|
||||
final rawTypeParam = rawUri.queryParameters['type'];
|
||||
|
||||
print('APP ROUTER: state.uri = ${state.uri}, type = $typeParam');
|
||||
print('APP ROUTER: rawUri = $rawUri, type = $rawTypeParam');
|
||||
|
||||
// Pas de redirection si on a déjà le paramètre type
|
||||
if (typeParam != null) {
|
||||
print('APP ROUTER: Param type déjà présent, pas de redirection');
|
||||
return null; // Pas de redirection
|
||||
}
|
||||
|
||||
// Si un paramètre type=user est présent dans l'URL brute mais pas dans l'état
|
||||
if (rawTypeParam == 'user' && typeParam == null) {
|
||||
print(
|
||||
'APP ROUTER: Paramètre détecté dans l\'URL brute, redirection vers /login?type=user');
|
||||
return '/login?type=user';
|
||||
}
|
||||
} catch (e) {
|
||||
print('Erreur lors de la récupération des paramètres d\'URL: $e');
|
||||
}
|
||||
}
|
||||
// Sauvegarder le chemin actuel pour l'utilisateur connecté, sauf pour la page de splash
|
||||
if (state.uri.toString() != '/' && userRepository.isLoggedIn) {
|
||||
// Ne pas sauvegarder les chemins de login/register
|
||||
if (!state.uri.toString().startsWith('/login') &&
|
||||
!state.uri.toString().startsWith('/register')) {
|
||||
userRepository.updateLastPath(state.uri.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Vérifier si l'utilisateur est sur la page de splash
|
||||
if (state.uri.toString() == '/') {
|
||||
// Laisser l'utilisateur sur la page de splash, la redirection sera gérée par SplashPage
|
||||
return null;
|
||||
}
|
||||
|
||||
// Vérifier si l'utilisateur est sur une page d'authentification
|
||||
final isLoggedIn = userRepository.isLoggedIn;
|
||||
final isOnLoginPage = state.uri.toString().startsWith('/login');
|
||||
final isOnRegisterPage = state.uri.toString() == '/register';
|
||||
final isOnAdminRegisterPage = state.uri.toString() == '/admin-register';
|
||||
|
||||
// Si l'utilisateur n'est pas connecté et n'est pas sur une page d'authentification, rediriger vers la page de connexion
|
||||
if (!isLoggedIn &&
|
||||
!isOnLoginPage &&
|
||||
!isOnRegisterPage &&
|
||||
!isOnAdminRegisterPage) {
|
||||
return '/login';
|
||||
}
|
||||
|
||||
// Si l'utilisateur est connecté et se trouve sur une page d'authentification, rediriger vers le tableau de bord approprié
|
||||
if (isLoggedIn &&
|
||||
(isOnLoginPage || isOnRegisterPage || isOnAdminRegisterPage)) {
|
||||
// Récupérer le rôle de l'utilisateur directement
|
||||
final user = userRepository.getCurrentUser();
|
||||
if (user != null) {
|
||||
// Convertir le rôle en int si nécessaire
|
||||
int roleValue;
|
||||
if (user.role is String) {
|
||||
roleValue = int.tryParse(user.role as String) ?? 1;
|
||||
} else {
|
||||
roleValue = user.role as int;
|
||||
}
|
||||
|
||||
// Redirection simple basée sur le rôle
|
||||
if (roleValue > 1) {
|
||||
debugPrint(
|
||||
'Router: Redirection vers /admin (rôle $roleValue > 1)');
|
||||
return '/admin';
|
||||
} else {
|
||||
debugPrint(
|
||||
'Router: Redirection vers /user (rôle $roleValue = 1)');
|
||||
return '/user';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Si l'utilisateur est connecté mais essaie d'accéder à la mauvaise page selon son rôle
|
||||
if (isLoggedIn) {
|
||||
final user = userRepository.getCurrentUser();
|
||||
if (user != null) {
|
||||
// Convertir le rôle en int si nécessaire
|
||||
int roleValue;
|
||||
if (user.role is String) {
|
||||
roleValue = int.tryParse(user.role as String) ?? 1;
|
||||
} else {
|
||||
roleValue = user.role as int;
|
||||
}
|
||||
|
||||
// Vérifier si l'utilisateur est sur la bonne page en fonction de son rôle
|
||||
final isOnUserPage = state.uri.toString().startsWith('/user');
|
||||
final isOnAdminPage = state.uri.toString().startsWith('/admin');
|
||||
|
||||
// Admin (rôle > 1) essayant d'accéder à une page utilisateur
|
||||
if (roleValue > 1 && isOnUserPage) {
|
||||
debugPrint(
|
||||
'Router: Redirection d\'admin (rôle $roleValue) vers /admin');
|
||||
return '/admin';
|
||||
}
|
||||
|
||||
// Utilisateur standard (rôle = 1) essayant d'accéder à une page admin
|
||||
if (roleValue == 1 && isOnAdminPage) {
|
||||
debugPrint(
|
||||
'Router: Redirection d\'utilisateur (rôle $roleValue) vers /user');
|
||||
return '/user';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
routes: [
|
||||
// Splash screen
|
||||
GoRoute(
|
||||
path: '/',
|
||||
builder: (context, state) => const SplashPage(),
|
||||
),
|
||||
|
||||
// Page de connexion utilisateur dédiée
|
||||
GoRoute(
|
||||
path: '/login/user',
|
||||
name: 'splash',
|
||||
builder: (context, state) {
|
||||
print('ROUTER: Accès direct à la route login user');
|
||||
return const LoginPage(
|
||||
key: Key('login_page_user'),
|
||||
loginType: 'user',
|
||||
);
|
||||
debugPrint('GoRoute: Affichage de SplashPage');
|
||||
return const SplashPage();
|
||||
},
|
||||
),
|
||||
|
||||
// Pages d'authentification standard
|
||||
GoRoute(
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
builder: (context, state) {
|
||||
// Ajouter des logs de débogage détaillés pour comprendre les paramètres
|
||||
print('ROUTER DEBUG: Uri complète = ${state.uri}');
|
||||
print('ROUTER DEBUG: Path = ${state.uri.path}');
|
||||
print('ROUTER DEBUG: Query params = ${state.uri.queryParameters}');
|
||||
print(
|
||||
'ROUTER DEBUG: Has type? ${state.uri.queryParameters.containsKey("type")}');
|
||||
// Récupérer le type depuis les query parameters ou extra data
|
||||
final type = state.uri.queryParameters['type'] ??
|
||||
(state.extra as Map<String, dynamic>?)?['type'] as String?;
|
||||
|
||||
// Donner la priorité aux paramètres d'URL puis aux extras
|
||||
String? loginType;
|
||||
|
||||
// 1. Essayer d'abord les paramètres d'URL (pour les liens externes)
|
||||
final queryParams = state.uri.queryParameters;
|
||||
loginType = queryParams['type'];
|
||||
print('ROUTER DEBUG: Type from query params = $loginType');
|
||||
|
||||
// 2. Si aucun type dans les paramètres d'URL, vérifier les extras (pour la navigation interne)
|
||||
if (loginType == null &&
|
||||
state.extra != null &&
|
||||
state.extra is Map<String, dynamic>) {
|
||||
final extras = state.extra as Map<String, dynamic>;
|
||||
loginType = extras['type']?.toString();
|
||||
print('ROUTER DEBUG: Type from extras = $loginType');
|
||||
}
|
||||
|
||||
// 3. Normaliser et valider le type
|
||||
if (loginType != null) {
|
||||
loginType = loginType.trim().toLowerCase();
|
||||
// Vérifier explicitement que c'est 'user', sinon mettre 'admin'
|
||||
if (loginType != 'user') {
|
||||
loginType = 'admin';
|
||||
}
|
||||
} else {
|
||||
// Si aucun type n'est spécifié, retourner la page de splash
|
||||
print(
|
||||
'ROUTER: Aucun type spécifié, utilisation de la page splash');
|
||||
return const SplashPage();
|
||||
}
|
||||
|
||||
print('ROUTER: Type de connexion final: $loginType');
|
||||
|
||||
return LoginPage(
|
||||
key: Key('login_page_${loginType}'),
|
||||
loginType: loginType,
|
||||
);
|
||||
debugPrint('GoRoute: Affichage de LoginPage avec type: $type');
|
||||
return LoginPage(loginType: type);
|
||||
},
|
||||
),
|
||||
// Routes spécifiques pour chaque type de login
|
||||
GoRoute(
|
||||
path: '/login/user',
|
||||
name: 'login-user',
|
||||
builder: (context, state) {
|
||||
debugPrint('GoRoute: Affichage de LoginPage pour utilisateur');
|
||||
return const LoginPage(loginType: 'user');
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/login/admin',
|
||||
name: 'login-admin',
|
||||
builder: (context, state) {
|
||||
debugPrint('GoRoute: Affichage de LoginPage pour admin');
|
||||
return const LoginPage(loginType: 'admin');
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/register',
|
||||
builder: (context, state) => const RegisterPage(),
|
||||
name: 'register',
|
||||
builder: (context, state) {
|
||||
debugPrint('GoRoute: Affichage de RegisterPage');
|
||||
// Retournez votre page d'inscription ici
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: Text('Page d\'inscription - À implémenter'),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
// Pages administrateur
|
||||
GoRoute(
|
||||
path: '/admin',
|
||||
builder: (context, state) => const AdminDashboardPage(),
|
||||
routes: [
|
||||
// Ajouter d'autres routes admin ici
|
||||
],
|
||||
),
|
||||
|
||||
// Pages utilisateur
|
||||
GoRoute(
|
||||
path: '/user',
|
||||
builder: (context, state) => const UserDashboardPage(),
|
||||
routes: [
|
||||
// Ajouter d'autres routes utilisateur ici
|
||||
],
|
||||
name: 'user',
|
||||
builder: (context, state) {
|
||||
debugPrint('GoRoute: Affichage de UserDashboardPage');
|
||||
return const UserDashboardPage();
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/admin',
|
||||
name: 'admin',
|
||||
builder: (context, state) {
|
||||
debugPrint('GoRoute: Affichage de AdminDashboardPage');
|
||||
return const AdminDashboardPage();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
redirect: (context, state) {
|
||||
final currentPath = state.uri.path;
|
||||
debugPrint('GoRouter.redirect: currentPath = $currentPath');
|
||||
|
||||
return MaterialApp.router(
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'GEOSECTOR',
|
||||
theme: AppTheme.lightTheme,
|
||||
darkTheme: AppTheme.darkTheme,
|
||||
themeMode: ThemeMode.system,
|
||||
routerConfig: router,
|
||||
// Pour la page racine, toujours autoriser l'affichage de la splash page
|
||||
if (currentPath == '/') {
|
||||
debugPrint('GoRouter.redirect: Autorisation splash page');
|
||||
return null;
|
||||
}
|
||||
|
||||
// Pages publiques qui ne nécessitent pas d'authentification
|
||||
final publicPaths = [
|
||||
'/login',
|
||||
'/login/user',
|
||||
'/login/admin',
|
||||
'/register'
|
||||
];
|
||||
if (publicPaths.any((path) => currentPath.startsWith(path))) {
|
||||
debugPrint(
|
||||
'GoRouter.redirect: Page publique autorisée: $currentPath');
|
||||
return null;
|
||||
}
|
||||
|
||||
// Vérifier l'authentification pour les pages protégées
|
||||
try {
|
||||
final isAuthenticated = userRepository.isLoggedIn;
|
||||
final currentUser = userRepository.currentUser;
|
||||
|
||||
debugPrint('GoRouter.redirect: isAuthenticated = $isAuthenticated');
|
||||
debugPrint('GoRouter.redirect: currentUser = ${currentUser?.email}');
|
||||
|
||||
// Si pas authentifié, rediriger vers la splash page
|
||||
if (!isAuthenticated) {
|
||||
debugPrint(
|
||||
'GoRouter.redirect: Non authentifié, redirection vers /');
|
||||
return '/';
|
||||
}
|
||||
|
||||
// Vérifier les permissions pour les pages admin
|
||||
if (currentPath.startsWith('/admin')) {
|
||||
final userRole = userRepository.getUserRole();
|
||||
final isAdmin = userRole > 1; // Admin = rôle 2 ou plus
|
||||
|
||||
debugPrint(
|
||||
'GoRouter.redirect: userRole = $userRole, isAdmin = $isAdmin');
|
||||
|
||||
if (!isAdmin) {
|
||||
debugPrint(
|
||||
'GoRouter.redirect: Pas admin, redirection vers /user');
|
||||
return '/user';
|
||||
}
|
||||
}
|
||||
|
||||
// Si on arrive ici, l'utilisateur a les permissions nécessaires
|
||||
debugPrint('GoRouter.redirect: Accès autorisé à $currentPath');
|
||||
return null;
|
||||
} catch (e) {
|
||||
debugPrint(
|
||||
'GoRouter.redirect: Erreur lors de la vérification auth: $e');
|
||||
// En cas d'erreur, rediriger vers la splash page pour sécurité
|
||||
return '/';
|
||||
}
|
||||
},
|
||||
// Listener pour déboguer les changements de route
|
||||
refreshListenable:
|
||||
userRepository, // Écouter les changements dans userRepository
|
||||
debugLogDiagnostics: true, // Activer les logs de débogage
|
||||
errorBuilder: (context, state) {
|
||||
debugPrint('GoRouter.errorBuilder: Erreur pour ${state.uri.path}');
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Erreur de navigation'),
|
||||
backgroundColor: Colors.red,
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.error_outline, size: 64, color: Colors.red),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Page non trouvée',
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Chemin: ${state.uri.path}',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
debugPrint('GoRouter.errorBuilder: Retour vers /');
|
||||
context.go('/');
|
||||
},
|
||||
icon: const Icon(Icons.home),
|
||||
label: const Text('Retour à l\'accueil'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user