feat: Version 3.3.4 - Nouvelle architecture pages, optimisations widgets Flutter et API

- Mise à jour VERSION vers 3.3.4
- Optimisations et révisions architecture API (deploy-api.sh, scripts de migration)
- Ajout documentation Stripe Tap to Pay complète
- Migration vers polices Inter Variable pour Flutter
- Optimisations build Android et nettoyage fichiers temporaires
- Amélioration système de déploiement avec gestion backups
- Ajout scripts CRON et migrations base de données

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
pierre
2025-10-05 20:11:15 +02:00
parent 2786252307
commit 570a1fa1f0
212 changed files with 24275 additions and 11321 deletions

View File

@@ -1,13 +1,14 @@
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'dart:convert';
import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode;
import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode, debugPrint;
import 'package:geosector_app/core/services/js_stub.dart'
if (dart.library.js) 'dart:js' as js;
import 'package:go_router/go_router.dart';
import 'package:http/http.dart' as http;
import 'package:hive_flutter/hive_flutter.dart';
import 'package:geosector_app/core/services/app_info_service.dart';
import 'package:geosector_app/core/services/current_user_service.dart';
import 'package:geosector_app/core/constants/app_keys.dart';
import 'package:geosector_app/presentation/widgets/custom_button.dart';
import 'package:geosector_app/presentation/widgets/custom_text_field.dart';
@@ -163,7 +164,7 @@ class _LoginPageState extends State<LoginPage> {
// Vérification du type de connexion (seulement si Hive est initialisé)
if (widget.loginType == null) {
// Si aucun type n'est spécifié, naviguer vers la splash page
print(
debugPrint(
'LoginPage: Aucun type de connexion spécifié, navigation vers splash page');
WidgetsBinding.instance.addPostFrameCallback((_) {
GoRouter.of(context).go('/');
@@ -171,7 +172,7 @@ class _LoginPageState extends State<LoginPage> {
_loginType = '';
} else {
_loginType = widget.loginType!;
print('LoginPage: Type de connexion utilisé: $_loginType');
debugPrint('LoginPage: Type de connexion utilisé: $_loginType');
}
// En mode web, essayer de détecter le paramètre dans l'URL directement
@@ -222,17 +223,17 @@ class _LoginPageState extends State<LoginPage> {
result.toLowerCase() == 'user') {
setState(() {
_loginType = 'user';
print(
debugPrint(
'LoginPage: Type détecté depuis sessionStorage: $_loginType');
});
}
} catch (e) {
print('LoginPage: Erreur lors de l\'accès au sessionStorage: $e');
debugPrint('LoginPage: Erreur lors de l\'accès au sessionStorage: $e');
}
});
}
} catch (e) {
print('Erreur lors de la récupération des paramètres d\'URL: $e');
debugPrint('Erreur lors de la récupération des paramètres d\'URL: $e');
}
}
@@ -327,7 +328,7 @@ class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
print('DEBUG BUILD: Reconstruction de LoginPage avec type: $_loginType');
debugPrint('DEBUG BUILD: Reconstruction de LoginPage avec type: $_loginType');
// Utiliser l'instance globale de userRepository
final theme = Theme.of(context);
@@ -565,13 +566,13 @@ class _LoginPageState extends State<LoginPage> {
_formKey.currentState!.validate()) {
// Vérifier que le type de connexion est spécifié
if (_loginType.isEmpty) {
print(
debugPrint(
'Login: Type non spécifié, redirection vers la page de démarrage');
context.go('/');
return;
}
print(
debugPrint(
'Login: Tentative avec type: $_loginType');
final success =
@@ -615,19 +616,37 @@ class _LoginPageState extends State<LoginPage> {
debugPrint(
'Role de l\'utilisateur: $roleValue');
// Redirection simple basée sur le rôle
if (roleValue > 1) {
debugPrint(
'Redirection vers /admin (rôle > 1)');
if (context.mounted) {
context.go('/admin');
}
} else {
debugPrint(
'Redirection vers /user (rôle = 1)');
// Définir le mode d'affichage selon le type de connexion
if (_loginType == 'user') {
// Connexion en mode user : toujours mode user
await CurrentUserService.instance.setDisplayMode('user');
debugPrint('Mode d\'affichage défini: user');
if (context.mounted) {
context.go('/user');
}
} else {
// Connexion en mode admin
if (roleValue >= 2) {
await CurrentUserService.instance.setDisplayMode('admin');
debugPrint('Mode d\'affichage défini: admin');
if (context.mounted) {
context.go('/admin');
}
} else {
// Un user (rôle 1) ne peut pas se connecter en mode admin
debugPrint('Erreur: User (rôle 1) tentant de se connecter en mode admin');
if (context.mounted) {
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
'Accès administrateur non autorisé pour ce compte.'),
backgroundColor: Colors.red,
),
);
}
return;
}
}
} else if (context.mounted) {
ScaffoldMessenger.of(context)
@@ -716,7 +735,7 @@ class _LoginPageState extends State<LoginPage> {
// Vérifier que le type de connexion est spécifié
if (_loginType.isEmpty) {
print(
debugPrint(
'Login: Type non spécifié, redirection vers la page de démarrage');
if (context.mounted) {
context.go('/');
@@ -724,7 +743,7 @@ class _LoginPageState extends State<LoginPage> {
return;
}
print(
debugPrint(
'Login: Tentative avec type: $_loginType');
// Utiliser le nouveau spinner moderne pour la connexion
@@ -773,19 +792,37 @@ class _LoginPageState extends State<LoginPage> {
debugPrint(
'Role de l\'utilisateur: $roleValue');
// Redirection simple basée sur le rôle
if (roleValue > 1) {
debugPrint(
'Redirection vers /admin (rôle > 1)');
if (context.mounted) {
context.go('/admin');
}
} else {
debugPrint(
'Redirection vers /user (rôle = 1)');
// Définir le mode d'affichage selon le type de connexion
if (_loginType == 'user') {
// Connexion en mode user : toujours mode user
await CurrentUserService.instance.setDisplayMode('user');
debugPrint('Mode d\'affichage défini: user');
if (context.mounted) {
context.go('/user');
}
} else {
// Connexion en mode admin
if (roleValue >= 2) {
await CurrentUserService.instance.setDisplayMode('admin');
debugPrint('Mode d\'affichage défini: admin');
if (context.mounted) {
context.go('/admin');
}
} else {
// Un user (rôle 1) ne peut pas se connecter en mode admin
debugPrint('Erreur: User (rôle 1) tentant de se connecter en mode admin');
if (context.mounted) {
ScaffoldMessenger.of(context)
.showSnackBar(
const SnackBar(
content: Text(
'Accès administrateur non autorisé pour ce compte.'),
backgroundColor: Colors.red,
),
);
}
return;
}
}
} else if (context.mounted) {
ScaffoldMessenger.of(context)
@@ -998,8 +1035,8 @@ class _LoginPageState extends State<LoginPage> {
final baseUrl = Uri.base.origin;
final apiUrl = '$baseUrl/api/lostpassword';
print('Envoi de la requête à: $apiUrl');
print('Email: ${emailController.text.trim()}');
debugPrint('Envoi de la requête à: $apiUrl');
debugPrint('Email: ${emailController.text.trim()}');
http.Response? response;
@@ -1013,15 +1050,15 @@ class _LoginPageState extends State<LoginPage> {
}),
);
print('Réponse reçue: ${response.statusCode}');
print('Corps de la réponse: ${response.body}');
debugPrint('Réponse reçue: ${response.statusCode}');
debugPrint('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(
debugPrint(
'Tentative avec URL alternative: $alternativeUrl');
final alternativeResponse = await http.post(
@@ -1032,9 +1069,9 @@ class _LoginPageState extends State<LoginPage> {
}),
);
print(
debugPrint(
'Réponse alternative reçue: ${alternativeResponse.statusCode}');
print(
debugPrint(
'Corps de la réponse alternative: ${alternativeResponse.body}');
// Si la réponse alternative est un succès, utiliser cette réponse
@@ -1043,7 +1080,7 @@ class _LoginPageState extends State<LoginPage> {
}
}
} catch (e) {
print(
debugPrint(
'Erreur lors de l\'envoi de la requête: $e');
throw Exception('Erreur de connexion: $e');
}