feat: Release version 3.1.4 - Mode terrain et génération PDF

 Nouvelles fonctionnalités:
- Ajout du mode terrain pour utilisation mobile hors connexion
- Génération automatique de reçus PDF avec template personnalisé
- Révision complète du système de cartes avec amélioration des performances

🔧 Améliorations techniques:
- Refactoring du module chat avec architecture simplifiée
- Optimisation du système de sécurité NIST SP 800-63B
- Amélioration de la gestion des secteurs géographiques
- Support UTF-8 étendu pour les noms d'utilisateurs

📱 Application mobile:
- Nouveau mode terrain dans user_field_mode_page
- Interface utilisateur adaptative pour conditions difficiles
- Synchronisation offline améliorée

🗺️ Cartographie:
- Optimisation des performances MapBox
- Meilleure gestion des tuiles hors ligne
- Amélioration de l'affichage des secteurs

📄 Documentation:
- Ajout guide Android (ANDROID-GUIDE.md)
- Documentation sécurité API (API-SECURITY.md)
- Guide module chat (CHAT_MODULE.md)

🐛 Corrections:
- Résolution des erreurs 400 lors de la création d'utilisateurs
- Correction de la validation des noms d'utilisateurs
- Fix des problèmes de synchronisation chat

🤖 Generated with Claude Code (https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-19 19:38:03 +02:00
parent 4f7247eb2d
commit 3443277d4a
185 changed files with 109354 additions and 102937 deletions

View File

@@ -12,6 +12,7 @@ import 'package:geosector_app/presentation/widgets/custom_text_field.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
import 'package:geosector_app/core/services/hive_service.dart'; // Pour vérifier l'initialisation
class LoginPage extends StatefulWidget {
final String? loginType;
@@ -58,7 +59,7 @@ class _LoginPageState extends State<LoginPage> {
// État de la connexion Internet
bool _isConnected = false;
bool _isConnected = true; // Par défaut, on suppose qu'il y a une connexion
Future<void> _getAppVersion() async {
try {
@@ -95,7 +96,28 @@ class _LoginPageState extends State<LoginPage> {
void initState() {
super.initState();
// Vérification du type de connexion
// VÉRIFICATION CRITIQUE : S'assurer que Hive est initialisé
// Cette vérification DOIT se faire avant tout accès aux repositories
if (!HiveService.instance.areBoxesInitialized()) {
debugPrint('⚠️ LoginPage: Boxes Hive non initialisées, redirection vers SplashPage');
// Construire les paramètres pour la redirection après initialisation
final loginType = widget.loginType ?? 'admin';
// Rediriger immédiatement vers SplashPage avec les bons paramètres
// pour que SplashPage puisse rediriger automatiquement après l'initialisation
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
context.go('/?action=login&type=$loginType');
}
});
// Initialiser avec des valeurs par défaut pour éviter les erreurs
_loginType = '';
return; // IMPORTANT : Arrêter l'exécution du reste de initState
}
// 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(
@@ -191,7 +213,14 @@ class _LoginPageState extends State<LoginPage> {
// 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((_) {
final users = userRepository.getAllUsers();
// Vérifier à nouveau que les boxes sont disponibles
if (!HiveService.instance.areBoxesInitialized()) {
debugPrint('⚠️ Boxes non disponibles pour pré-remplir le username');
return;
}
try {
final users = userRepository.getAllUsers();
if (users.isNotEmpty) {
// Trouver l'utilisateur le plus récent (celui avec la date de dernière connexion la plus récente)
@@ -236,6 +265,10 @@ class _LoginPageState extends State<LoginPage> {
'Le rôle ($roleValue) ne correspond pas au type de login ($_loginType), champ username non pré-rempli');
}
}
} catch (e) {
debugPrint('Erreur lors du pré-remplissage: $e');
// Continuer sans pré-remplir en cas d'erreur
}
});
}