Amélioration de la splash_page et du login
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode;
|
||||
import 'dart:js' as js;
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:go_router/src/state.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:geosector_app/core/repositories/user_repository.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:geosector_app/core/services/app_info_service.dart';
|
||||
import 'package:geosector_app/presentation/widgets/custom_button.dart';
|
||||
import 'package:geosector_app/presentation/widgets/custom_text_field.dart';
|
||||
import 'package:geosector_app/core/services/location_service.dart';
|
||||
import 'package:geosector_app/core/services/connectivity_service.dart';
|
||||
import 'package:geosector_app/presentation/widgets/connectivity_indicator.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
@@ -51,6 +52,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
final _passwordController = TextEditingController();
|
||||
final _usernameFocusNode = FocusNode();
|
||||
bool _obscurePassword = true;
|
||||
String _appVersion = '';
|
||||
|
||||
// Type de connexion (utilisateur ou administrateur)
|
||||
late String _loginType;
|
||||
@@ -63,6 +65,37 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// État de la connexion Internet
|
||||
bool _isConnected = false;
|
||||
|
||||
Future<void> _getAppVersion() async {
|
||||
try {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_appVersion = packageInfo.version;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération de la version: $e');
|
||||
// Fallback sur la version du AppInfoService si elle existe
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_appVersion = AppInfoService.fullVersion
|
||||
.split(' ')
|
||||
.last; // Extraire juste le numéro
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _checkConnectivity() async {
|
||||
await connectivityService.checkConnectivity();
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isConnected = connectivityService.isConnected;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -163,6 +196,12 @@ class _LoginPageState extends State<LoginPage> {
|
||||
}
|
||||
});
|
||||
|
||||
// Récupérer la version de l'application
|
||||
_getAppVersion();
|
||||
|
||||
// Vérification de connectivité au démarrage
|
||||
_checkConnectivity();
|
||||
|
||||
// Pré-remplir le champ username avec l'identifiant du dernier utilisateur connecté
|
||||
// seulement si le rôle correspond au type de login
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@@ -538,6 +577,14 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
AppInfoService.fullVersion,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.primary.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
// Ajouter un texte de débogage uniquement en mode développement
|
||||
if (kDebugMode)
|
||||
Text(
|
||||
@@ -558,7 +605,38 @@ class _LoginPageState extends State<LoginPage> {
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Indicateur de connectivité
|
||||
ConnectivityIndicator(),
|
||||
const ConnectivityIndicator(),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (!kIsWeb && !_isConnected)
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 16),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.error.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color:
|
||||
theme.colorScheme.error.withOpacity(0.3),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Icons.signal_wifi_off,
|
||||
color: theme.colorScheme.error, size: 32),
|
||||
const SizedBox(height: 8),
|
||||
Text('Connexion Internet requise',
|
||||
style: theme.textTheme.titleMedium
|
||||
?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: theme.colorScheme.error)),
|
||||
const SizedBox(height: 8),
|
||||
const Text(
|
||||
'Veuillez vous connecter à Internet (WiFi ou données mobiles) pour pouvoir vous connecter.'),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Formulaire de connexion
|
||||
@@ -689,7 +767,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
alignment: Alignment.centerRight,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
// Naviguer vers la page de récupération de mot de passe
|
||||
_showForgotPasswordDialog(context);
|
||||
},
|
||||
child: Text(
|
||||
'Mot de passe oublié ?',
|
||||
@@ -863,10 +941,10 @@ class _LoginPageState extends State<LoginPage> {
|
||||
onPressed: () {
|
||||
context.go('/register');
|
||||
},
|
||||
child: Text(
|
||||
child: const Text(
|
||||
'Inscription Administrateur',
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.tertiary,
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@@ -897,8 +975,255 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Badge de version en bas à droite
|
||||
if (_appVersion.isNotEmpty)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
right: 16,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary.withOpacity(0.3),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'v$_appVersion',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.primary.withOpacity(0.8),
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Affiche la boîte de dialogue pour la récupération de mot de passe
|
||||
void _showForgotPasswordDialog(BuildContext context) {
|
||||
final emailController = TextEditingController();
|
||||
final formKey = GlobalKey<FormState>();
|
||||
bool isLoading = false;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(builder: (context, setState) {
|
||||
return AlertDialog(
|
||||
title: const Row(
|
||||
children: [
|
||||
Icon(Icons.lock_reset, color: Colors.blue),
|
||||
SizedBox(width: 10),
|
||||
Text('Récupération de mot de passe'),
|
||||
],
|
||||
),
|
||||
content: Form(
|
||||
key: formKey,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
'Veuillez entrer votre adresse email pour recevoir un nouveau mot de passe.',
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
CustomTextField(
|
||||
controller: emailController,
|
||||
label: 'Email',
|
||||
hintText: 'Entrez votre email',
|
||||
prefixIcon: Icons.email_outlined,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Veuillez entrer votre email';
|
||||
}
|
||||
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$')
|
||||
.hasMatch(value)) {
|
||||
return 'Veuillez entrer un email valide';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: const Text('Annuler'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: isLoading
|
||||
? null
|
||||
: () async {
|
||||
if (formKey.currentState!.validate()) {
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
// Vérifier la connexion Internet
|
||||
await connectivityService.checkConnectivity();
|
||||
if (!connectivityService.isConnected) {
|
||||
throw Exception('Aucune connexion Internet');
|
||||
}
|
||||
|
||||
// Construire l'URL de l'API
|
||||
final baseUrl = Uri.base.origin;
|
||||
final apiUrl = '$baseUrl/api/lostpassword';
|
||||
|
||||
print('Envoi de la requête à: $apiUrl');
|
||||
print('Email: ${emailController.text.trim()}');
|
||||
|
||||
http.Response? response;
|
||||
|
||||
try {
|
||||
// Envoyer la requête à l'API
|
||||
response = await http.post(
|
||||
Uri.parse(apiUrl),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode({
|
||||
'email': emailController.text.trim(),
|
||||
}),
|
||||
);
|
||||
|
||||
print('Réponse reçue: ${response.statusCode}');
|
||||
print('Corps de la réponse: ${response.body}');
|
||||
|
||||
// Si la réponse est 404, c'est peut-être un problème de route
|
||||
if (response.statusCode == 404) {
|
||||
// Essayer avec une URL alternative
|
||||
final alternativeUrl =
|
||||
'$baseUrl/api/index.php/lostpassword';
|
||||
print(
|
||||
'Tentative avec URL alternative: $alternativeUrl');
|
||||
|
||||
final alternativeResponse = await http.post(
|
||||
Uri.parse(alternativeUrl),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: json.encode({
|
||||
'email': emailController.text.trim(),
|
||||
}),
|
||||
);
|
||||
|
||||
print(
|
||||
'Réponse alternative reçue: ${alternativeResponse.statusCode}');
|
||||
print(
|
||||
'Corps de la réponse alternative: ${alternativeResponse.body}');
|
||||
|
||||
// Si la réponse alternative est un succès, utiliser cette réponse
|
||||
if (alternativeResponse.statusCode == 200) {
|
||||
response = alternativeResponse;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print(
|
||||
'Erreur lors de l\'envoi de la requête: $e');
|
||||
throw Exception('Erreur de connexion: $e');
|
||||
}
|
||||
|
||||
// Traiter la réponse
|
||||
if (response != null &&
|
||||
response.statusCode == 200) {
|
||||
// Modifier le contenu de la boîte de dialogue pour afficher le message de succès
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
|
||||
// Remplacer le contenu de la boîte de dialogue par un message de succès
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
// Fermer automatiquement la boîte de dialogue après 2 secondes
|
||||
Future.delayed(Duration(seconds: 2), () {
|
||||
if (Navigator.of(context).canPop()) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
});
|
||||
|
||||
return const AlertDialog(
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.check_circle,
|
||||
color: Colors.green,
|
||||
size: 48,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'Vous recevrez un nouveau mot de passe par email',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// Fermer la boîte de dialogue actuelle
|
||||
Navigator.of(context).pop();
|
||||
|
||||
// Afficher un message d'erreur
|
||||
final responseData = json.decode(response.body);
|
||||
throw Exception(responseData['message'] ??
|
||||
'Erreur lors de la récupération du mot de passe');
|
||||
}
|
||||
} catch (e) {
|
||||
// Afficher un message d'erreur
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(e
|
||||
.toString()
|
||||
.contains('Exception:')
|
||||
? e.toString().split('Exception: ')[1]
|
||||
: 'Erreur lors de la récupération du mot de passe'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
child: isLoading
|
||||
? SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor:
|
||||
AlwaysStoppedAnimation<Color>(Colors.white),
|
||||
),
|
||||
)
|
||||
: Text('Recevoir un nouveau mot de passe'),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:geosector_app/core/repositories/user_repository.dart';
|
||||
import 'package:geosector_app/core/theme/app_theme.dart';
|
||||
import 'package:geosector_app/app.dart'; // Pour accéder aux instances globales
|
||||
import 'package:geosector_app/core/services/app_info_service.dart';
|
||||
import 'package:geosector_app/core/constants/app_keys.dart';
|
||||
import 'package:geosector_app/core/data/models/user_model.dart';
|
||||
import 'package:geosector_app/core/data/models/amicale_model.dart';
|
||||
@@ -15,10 +13,11 @@ import 'package:geosector_app/core/data/models/membre_model.dart';
|
||||
import 'package:geosector_app/core/data/models/user_sector_model.dart';
|
||||
import 'package:geosector_app/chat/models/conversation_model.dart';
|
||||
import 'package:geosector_app/chat/models/message_model.dart';
|
||||
import 'package:geosector_app/core/services/hive_reset_state_service.dart';
|
||||
import 'package:geosector_app/presentation/widgets/clear_cache_dialog.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class SplashPage extends StatefulWidget {
|
||||
const SplashPage({super.key});
|
||||
@@ -58,12 +57,28 @@ class _SplashPageState extends State<SplashPage>
|
||||
String _statusMessage = "Initialisation...";
|
||||
double _progress = 0.0;
|
||||
bool _showButtons = false;
|
||||
String _appVersion = '';
|
||||
|
||||
final List<String> _initializationSteps = [
|
||||
"Initialisation des services...",
|
||||
"Vérification de l'authentification...",
|
||||
"Chargement des données..."
|
||||
];
|
||||
Future<void> _getAppVersion() async {
|
||||
try {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_appVersion = packageInfo.version;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la récupération de la version: $e');
|
||||
// Fallback sur la version du AppInfoService si elle existe
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_appVersion = AppInfoService.fullVersion
|
||||
.split(' ')
|
||||
.last; // Extraire juste le numéro
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -89,33 +104,12 @@ class _SplashPageState extends State<SplashPage>
|
||||
// Démarrer l'animation immédiatement
|
||||
_animationController.forward();
|
||||
|
||||
// Vérifier si Hive a été réinitialisé
|
||||
_checkHiveReset();
|
||||
_getAppVersion();
|
||||
|
||||
// Simuler le processus d'initialisation
|
||||
_startInitialization();
|
||||
}
|
||||
|
||||
// Méthode pour vérifier si Hive a été réinitialisé et afficher le dialogue si nécessaire
|
||||
void _checkHiveReset() {
|
||||
// Vérifier si Hive a été réinitialisé et si le dialogue n'a pas encore été affiché
|
||||
if (hiveResetStateService.wasReset && !hiveResetStateService.dialogShown) {
|
||||
// Attendre que le widget soit complètement construit
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
// Afficher le dialogue de nettoyage du cache
|
||||
ClearCacheDialog.show(
|
||||
context,
|
||||
onClose: () {
|
||||
// Marquer le dialogue comme ayant été affiché
|
||||
hiveResetStateService.markDialogAsShown();
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_animationController.dispose();
|
||||
@@ -123,11 +117,11 @@ class _SplashPageState extends State<SplashPage>
|
||||
}
|
||||
|
||||
void _startInitialization() async {
|
||||
// Étape 1: Initialisation des services
|
||||
// Étape 1: Initialisation des boîtes Hive (0% à 75%)
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = _initializationSteps[0];
|
||||
_progress = 0.2;
|
||||
_statusMessage = "Initialisation des données...";
|
||||
_progress = 0.0;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -135,20 +129,11 @@ class _SplashPageState extends State<SplashPage>
|
||||
await _initializeAllHiveBoxes();
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
// Étape 2: Vérification de l'authentification
|
||||
// Étape 2: Initialisation des services (75% à 100%)
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = _initializationSteps[1];
|
||||
_progress = 0.4;
|
||||
});
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
|
||||
// Étape 3: Chargement des données
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = _initializationSteps[2];
|
||||
_progress = 1.0; // Directement à 100% après la 3ème étape
|
||||
_statusMessage = "Préparation de l'application...";
|
||||
_progress = 0.75;
|
||||
});
|
||||
}
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
@@ -157,15 +142,8 @@ class _SplashPageState extends State<SplashPage>
|
||||
setState(() {
|
||||
_isInitializing = false;
|
||||
_showButtons = true;
|
||||
_progress = 1.0; // S'assurer que la barre est à 100%
|
||||
});
|
||||
|
||||
// Attendre quelques secondes avant de rediriger automatiquement
|
||||
// si l'utilisateur est déjà connecté
|
||||
if (userRepository.isLoggedIn) {
|
||||
Timer(const Duration(seconds: 2), () {
|
||||
_redirectToAppropriateScreen();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,8 +180,8 @@ class _SplashPageState extends State<SplashPage>
|
||||
},
|
||||
];
|
||||
|
||||
// Calculer l'incrément de progression pour chaque boîte
|
||||
final progressIncrement = 0.2 / boxesToOpen.length;
|
||||
// Calculer l'incrément de progression pour chaque boîte (0.75 / nombre de boîtes)
|
||||
final progressIncrement = 0.75 / boxesToOpen.length;
|
||||
double currentProgress = 0.0;
|
||||
|
||||
// Ouvrir chaque boîte si elle n'est pas déjà ouverte
|
||||
@@ -212,12 +190,11 @@ class _SplashPageState extends State<SplashPage>
|
||||
final displayName = boxesToOpen[i]['display'] as String;
|
||||
|
||||
// Mettre à jour la barre de progression et le message
|
||||
currentProgress += progressIncrement;
|
||||
currentProgress = progressIncrement * (i + 1);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = displayName;
|
||||
_progress =
|
||||
0.2 * (currentProgress / 0.2); // Normaliser entre 0 et 0.2
|
||||
_progress = currentProgress;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -266,10 +243,27 @@ class _SplashPageState extends State<SplashPage>
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = 'Toutes les boîtes sont prêtes';
|
||||
_progress = 0.2;
|
||||
_progress = 0.8;
|
||||
});
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_statusMessage = "Préparation de l'application...";
|
||||
_progress = 0.9;
|
||||
});
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
}
|
||||
|
||||
// Finalisation
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isInitializing = false;
|
||||
_showButtons = true;
|
||||
_progress = 1.0;
|
||||
});
|
||||
}
|
||||
debugPrint('Toutes les boîtes Hive sont maintenant ouvertes');
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de l\'initialisation des boîtes Hive: $e');
|
||||
@@ -283,33 +277,9 @@ class _SplashPageState extends State<SplashPage>
|
||||
}
|
||||
}
|
||||
|
||||
void _redirectToAppropriateScreen() {
|
||||
if (!mounted) return;
|
||||
|
||||
// Utiliser l'instance globale de userRepository définie dans app.dart
|
||||
if (userRepository.isLoggedIn) {
|
||||
debugPrint('SplashPage: Redirection d\'utilisateur connecté');
|
||||
|
||||
// Récupérer directement le rôle utilisateur
|
||||
final roleValue = userRepository.getUserRole();
|
||||
debugPrint('SplashPage: Rôle utilisateur = $roleValue');
|
||||
|
||||
// Redirection simple basée sur le rôle
|
||||
if (roleValue > 1) {
|
||||
debugPrint('SplashPage: Redirection vers /admin (rôle $roleValue > 1)');
|
||||
context.go('/admin');
|
||||
} else {
|
||||
debugPrint('SplashPage: Redirection vers /user (rôle $roleValue = 1)');
|
||||
context.go('/user');
|
||||
}
|
||||
}
|
||||
// Ne redirige plus vers la landing page
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final size = MediaQuery.of(context).size;
|
||||
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
@@ -424,7 +394,8 @@ class _SplashPageState extends State<SplashPage>
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
context.go('/login', extra: {'type': 'user'});
|
||||
context.go(
|
||||
'/login/user'); // Utiliser la route spécifique
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.green,
|
||||
@@ -449,13 +420,14 @@ class _SplashPageState extends State<SplashPage>
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Bouton Connexion Administrateur
|
||||
// Bouton Connexion Administrateur
|
||||
AnimatedOpacity(
|
||||
opacity: _showButtons ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
context.go('/login', extra: {'type': 'admin'});
|
||||
context.go(
|
||||
'/login/admin'); // Utiliser la route spécifique
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.red,
|
||||
@@ -479,18 +451,74 @@ class _SplashPageState extends State<SplashPage>
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
const SizedBox(
|
||||
height: 32), // 2 espaces sous le bouton précédent
|
||||
|
||||
// Lien d'inscription
|
||||
// Bouton d'inscription
|
||||
AnimatedOpacity(
|
||||
opacity: _showButtons ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: TextButton(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
context.go('/register');
|
||||
},
|
||||
child: Text(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 40,
|
||||
vertical: 16,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
),
|
||||
elevation: 2,
|
||||
),
|
||||
child: const Text(
|
||||
'Pas encore inscrit ?',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Lien vers le site web
|
||||
AnimatedOpacity(
|
||||
opacity: _showButtons ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: TextButton.icon(
|
||||
onPressed: () {
|
||||
// Déterminer l'URL du site web en fonction de l'environnement
|
||||
String webUrl = 'https://geosector.fr';
|
||||
|
||||
if (kIsWeb) {
|
||||
final host = Uri.base.host;
|
||||
if (host.startsWith('dapp.')) {
|
||||
webUrl = 'https://dev.geosector.fr';
|
||||
} else if (host.startsWith('rapp.')) {
|
||||
webUrl = 'https://rec.geosector.fr';
|
||||
} else if (host.startsWith('app.')) {
|
||||
webUrl = 'https://geosector.fr';
|
||||
}
|
||||
}
|
||||
|
||||
// Ouvrir l'URL dans une nouvelle fenêtre/onglet
|
||||
launchUrl(
|
||||
Uri.parse(webUrl),
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.language,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
label: Text(
|
||||
'Site web Geosector',
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -506,6 +534,38 @@ class _SplashPageState extends State<SplashPage>
|
||||
),
|
||||
),
|
||||
),
|
||||
// Badge de version en bas à droite
|
||||
if (_appVersion.isNotEmpty)
|
||||
Positioned(
|
||||
bottom: 16,
|
||||
right: 16,
|
||||
child: AnimatedOpacity(
|
||||
opacity: _showButtons ? 0.7 : 0.5,
|
||||
duration: const Duration(milliseconds: 500),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'v$_appVersion',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user