From d3813bfcdb3e2d73ea6bd49a2cf2b5cf1afad431 Mon Sep 17 00:00:00 2001 From: "PC-PAUL\\paulf" Date: Wed, 5 Mar 2025 19:56:58 +0100 Subject: [PATCH] =?UTF-8?q?Auth=20r=C3=A9par=C3=A9e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- em2rp/.vscode/launch.json | 17 +- em2rp/lib/main.dart | 102 +++++------- em2rp/lib/providers/user_provider.dart | 29 ++-- em2rp/lib/views/calendar_page.dart | 1 - em2rp/lib/views/login_page.dart | 162 +++++++------------ em2rp/lib/views/widgets/nav/main_drawer.dart | 2 +- 6 files changed, 136 insertions(+), 177 deletions(-) diff --git a/em2rp/.vscode/launch.json b/em2rp/.vscode/launch.json index bafe1d0..55b9f54 100644 --- a/em2rp/.vscode/launch.json +++ b/em2rp/.vscode/launch.json @@ -4,7 +4,22 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - + { + "name": "Attach to Chrome", + "port": 9222, + "request": "attach", + "type": "chrome", + "webRoot": "${workspaceFolder}", + "preLaunchTask": "npm: vite", + + }, + { + "name": "Launch Chrome", + "request": "launch", + "type": "chrome", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + }, { "name": "Launch Edge", "request": "launch", diff --git a/em2rp/lib/main.dart b/em2rp/lib/main.dart index 296a390..9cc0d71 100644 --- a/em2rp/lib/main.dart +++ b/em2rp/lib/main.dart @@ -31,68 +31,50 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { print("test"); return MaterialApp( - title: 'EM2 ERP', - theme: ThemeData( - primarySwatch: Colors.red, - primaryColor: AppColors.noir, - colorScheme: - ColorScheme.fromSwatch().copyWith(secondary: AppColors.rouge), - textTheme: const TextTheme( - bodyMedium: TextStyle(color: AppColors.noir), - ), - // Personnalisation de l'InputDecorationTheme pour les text fields - inputDecorationTheme: InputDecorationTheme( - focusedBorder: OutlineInputBorder( - // Bordure lorsqu'il est focus - borderSide: - BorderSide(color: AppColors.noir), // Couleur rouge quand focus + title: 'EM2 ERP', + theme: ThemeData( + primarySwatch: Colors.red, + primaryColor: AppColors.noir, + colorScheme: + ColorScheme.fromSwatch().copyWith(secondary: AppColors.rouge), + textTheme: const TextTheme( + bodyMedium: TextStyle(color: AppColors.noir), ), - enabledBorder: OutlineInputBorder( - // Bordure par défaut (non focus) - borderSide: - BorderSide(color: AppColors.gris), // Couleur grise par défaut - ), - labelStyle: TextStyle(color: AppColors.noir), // Couleur du label - hintStyle: TextStyle(color: AppColors.gris), // Couleur du hint text - // Tu peux personnaliser d'autres propriétés ici : - // fillColor, filled, iconColor, prefixStyle, suffixStyle, etc. - ), - elevatedButtonTheme: ElevatedButtonThemeData( - style: ElevatedButton.styleFrom( - foregroundColor: - AppColors.blanc, // Couleur du texte du bouton (ici blanc) - backgroundColor: AppColors - .noir, // Couleur de fond du bouton (si tu veux aussi changer le fond) - // Autres styles possibles pour les boutons : - // textStyle, padding, shape, elevation, etc. - ), - ), - ), - routes: { - '/login': (context) => const LoginPage(), - '/calendar': (context) => const CalendarPage(), - '/my_account': (context) => const MyAccountPage(), - '/user_management': (context) => const UserManagementPage(), - }, - // Conditionally set home based on authentication state - home: StreamBuilder( - stream: FirebaseAuth.instance.authStateChanges(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.active) { - User? user = snapshot.data; - if (user == null) { - return const LoginPage(); // User not logged in, show LoginPage - } - return const CalendarPage(); // User logged in, show CalendarPage - } - // Checking auth state, show loading indicator - return const Scaffold( - body: Center( - child: CircularProgressIndicator(), + // Personnalisation de l'InputDecorationTheme pour les text fields + inputDecorationTheme: InputDecorationTheme( + focusedBorder: OutlineInputBorder( + // Bordure lorsqu'il est focus + borderSide: BorderSide( + color: AppColors.noir), // Couleur rouge quand focus ), - ); + enabledBorder: OutlineInputBorder( + // Bordure par défaut (non focus) + borderSide: + BorderSide(color: AppColors.gris), // Couleur grise par défaut + ), + labelStyle: TextStyle(color: AppColors.noir), // Couleur du label + hintStyle: TextStyle(color: AppColors.gris), // Couleur du hint text + // Tu peux personnaliser d'autres propriétés ici : + // fillColor, filled, iconColor, prefixStyle, suffixStyle, etc. + ), + elevatedButtonTheme: ElevatedButtonThemeData( + style: ElevatedButton.styleFrom( + foregroundColor: + AppColors.blanc, // Couleur du texte du bouton (ici blanc) + backgroundColor: AppColors + .noir, // Couleur de fond du bouton (si tu veux aussi changer le fond) + // Autres styles possibles pour les boutons : + // textStyle, padding, shape, elevation, etc. + ), + ), + ), + routes: { + '/login': (context) => const LoginPage(), + '/calendar': (context) => const CalendarPage(), + '/my_account': (context) => const MyAccountPage(), + '/user_management': (context) => const UserManagementPage(), }, - ), - ); + // Conditionally set home based on authentication state + home: LoginPage()); } } diff --git a/em2rp/lib/providers/user_provider.dart b/em2rp/lib/providers/user_provider.dart index 12b110f..7504aa9 100644 --- a/em2rp/lib/providers/user_provider.dart +++ b/em2rp/lib/providers/user_provider.dart @@ -5,27 +5,38 @@ class UserProvider extends ChangeNotifier { String? _firstName; String? _lastName; String? _role; - String? _profilePictureUrl; + // String? _profilePictureUrl; String? _email; - String? _phoneNumber; + // String? _phoneNumber; String? get uid => _uid; String? get firstName => _firstName; String? get lastName => _lastName; String? get role => _role; - String? get profilePhotoUrl => _profilePictureUrl; + // String? get profilePhotoUrl => _profilePictureUrl; String? get email => _email; - String? get phoneNumber => _phoneNumber; + // String? get phoneNumber => _phoneNumber; + // void setUserData(Map userData, String uid) { + // _uid = uid; + // _firstName = userData['firstName']; + // _lastName = userData['lastName']; + // _role = userData['role'] ?? 'USER'; // Default role if not provided + // // _profilePictureUrl = userData['profilePhotoUrl']; + // _email = userData['email']; + // // _phoneNumber = userData['phoneNumber']; + // notifyListeners(); // Notify listeners that state has changed + // } void setUserData(Map userData, String uid) { _uid = uid; _firstName = userData['firstName']; _lastName = userData['lastName']; _role = userData['role'] ?? 'USER'; // Default role if not provided - _profilePictureUrl = userData['profilePhotoUrl']; _email = userData['email']; - _phoneNumber = userData['phoneNumber']; - notifyListeners(); // Notify listeners that state has changed + + print("User data set: $_firstName $_lastName ($_email)"); + + notifyListeners(); } void clearUserData() { @@ -33,9 +44,9 @@ class UserProvider extends ChangeNotifier { _firstName = null; _lastName = null; _role = null; - _profilePictureUrl = null; + // _profilePictureUrl = null; _email = null; - _phoneNumber = null; + // _phoneNumber = null; notifyListeners(); } } diff --git a/em2rp/lib/views/calendar_page.dart b/em2rp/lib/views/calendar_page.dart index 3325beb..2327deb 100644 --- a/em2rp/lib/views/calendar_page.dart +++ b/em2rp/lib/views/calendar_page.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:firebase_auth/firebase_auth.dart'; import 'package:em2rp/views/widgets/nav/main_drawer.dart'; import 'package:provider/provider.dart'; // Import Provider import 'package:em2rp/providers/user_provider.dart'; // Import UserProvider diff --git a/em2rp/lib/views/login_page.dart b/em2rp/lib/views/login_page.dart index a1aeee9..9615d2d 100644 --- a/em2rp/lib/views/login_page.dart +++ b/em2rp/lib/views/login_page.dart @@ -1,6 +1,5 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:em2rp/providers/user_provider.dart'; -import 'package:em2rp/views/widgets/auth/forgot_password_dialog.dart'; import 'package:em2rp/views/widgets/auth/mail_textfield.dart'; import 'package:em2rp/views/widgets/error_message.dart'; import 'package:em2rp/views/widgets/auth/forgot_password_button.dart'; @@ -11,6 +10,7 @@ import 'package:em2rp/views/widgets/auth/password_textfield.dart'; import 'package:em2rp/views/widgets/auth/welcome_text.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; +import 'package:em2rp/views/widgets/auth/forgot_password_dialog.dart'; import 'package:provider/provider.dart'; class LoginPage extends StatefulWidget { @@ -33,13 +33,11 @@ class _LoginPageState extends State { void dispose() { _emailController.dispose(); _passwordController.dispose(); - print("LoginPage DISPOSED"); super.dispose(); } - Future _loginUser() async { - if (!mounted) return; // Early exit if widget is unmounted - + Future _signInWithEmailAndPassword() async { + // Pas de vérification mounted ici, le widget reste monté pendant toute l'opération setState(() { _errorMessage = ''; _isLoading = true; @@ -47,95 +45,54 @@ class _LoginPageState extends State { _highlightEmailField = false; }); - String email = _emailController.text.trim(); - String password = _passwordController.text; - try { - // 1. Sign in with Firebase Authentication - UserCredential userCredential = await FirebaseAuth.instance - .signInWithEmailAndPassword(email: email, password: password); - User? user = userCredential.user; + final UserCredential userCredential = + await FirebaseAuth.instance.signInWithEmailAndPassword( + email: _emailController.text.trim(), + password: _passwordController.text, + ); + final uid = userCredential.user!.uid; - if (user != null) { - // 2. Fetch user data from Firestore - print( - "Fetching user data from Firestore..."); // Log before Firestore fetch - DocumentSnapshot userDoc = await FirebaseFirestore.instance - .collection('users') - .doc(user.uid) - .get(); - print("Firestore DocumentSnapshot retrieved."); // Log after fetch + final DocumentSnapshot userDoc = + await FirebaseFirestore.instance.collection('users').doc(uid).get(); - if (userDoc.exists) { - print("Firestore Document Exists: true"); // Log doc exists check - print("Document ID: ${userDoc.id}"); // Log document ID - print( - "Before data cast - userDoc.data(): ${userDoc.data()}"); // Log raw data before cast + if (userDoc.exists) { + print("User document found: ${userDoc.data()}"); + Provider.of(context, listen: false) + .setUserData(userDoc.data() as Map, uid); - Map userData = - userDoc.data() as Map; - - print( - "After data cast - userData: $userData"); // Log userData after cast - - // 3. Store user data in UserProvider - final userProvider = - Provider.of(context, listen: false); - print( - "Before setUserData call - userProvider: $userProvider"); // Log userProvider instance - userProvider.setUserData( - userData, user.uid); // Store user data in provider - print("After setUserData call"); // Log after setUserData is called - - print( - 'Login successful! Role: ${userProvider.role}'); // Log success and role - if (mounted) { - Navigator.of(context).pushReplacementNamed( - '/calendar'); // 4. Navigate to CalendarPage - } - } else { - // User document not found in Firestore - print( - "Firestore Document Exists: false"); // Log doc exists check - false - if (mounted) { - setState(() { - _isLoading = false; - _errorMessage = - "Erreur: Utilisateur non trouvé dans la base de données."; - }); - } - print('Login Error: Firestore user document not found'); - } + // Maintenant que toutes les données sont chargées, naviguer vers CalendarPage. + Navigator.of(context).pushReplacementNamed('/calendar'); + } else { + setState(() { + _errorMessage = "Aucune donnée utilisateur trouvée."; + _isLoading = false; + }); } } on FirebaseAuthException catch (e) { - // Firebase Authentication error - if (mounted) { - setState(() { - _isLoading = false; - if (e.code == 'user-not-found' || e.code == 'wrong-password') { - _errorMessage = "Email ou mot de passe incorrect."; - _highlightPasswordField = true; - _highlightEmailField = true; - } else if (e.code == 'invalid-email') { - _errorMessage = "Adresse email invalide."; - _highlightEmailField = true; - } else { - _errorMessage = "Erreur de connexion. Veuillez réessayer."; - } - }); - } - print('Login Error (FirebaseAuth): ${e.code} - ${e.message}'); - } finally { - if (mounted) { - setState(() { - _isLoading = false; - }); - } + setState(() { + _isLoading = false; + if (e.code == 'user-not-found' || e.code == 'wrong-password') { + _errorMessage = "Email ou mot de passe incorrect."; + _highlightPasswordField = true; + _highlightEmailField = true; + } else { + _errorMessage = "Erreur de connexion. Veuillez réessayer."; + } + }); + } catch (e) { + setState(() { + _errorMessage = + "Erreur lors de la récupération des données utilisateur."; + _isLoading = false; + }); } } void _togglePasswordVisibility() { - if (mounted) setState(() => _obscurePassword = !_obscurePassword); + setState(() { + _obscurePassword = !_obscurePassword; + }); } void _forgotPassword() { @@ -151,9 +108,13 @@ class _LoginPageState extends State { Widget build(BuildContext context) { return Scaffold( body: LayoutBuilder( - builder: (context, constraints) => constraints.maxWidth > 900 - ? _buildLargeScreenLayout(context) - : _buildSmallScreenLayout(context), + builder: (context, constraints) { + if (constraints.maxWidth > 900) { + return _buildLargeScreenLayout(context); + } else { + return _buildSmallScreenLayout(context); + } + }, ), ); } @@ -161,11 +122,15 @@ class _LoginPageState extends State { Widget _buildLargeScreenLayout(BuildContext context) { return Row( children: [ - const Expanded(flex: 6, child: ImageSectionWidget()), + Expanded( + flex: 6, + child: const ImageSectionWidget(), // Affiche l'image de gauche + ), Expanded( flex: 4, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 30), + padding: + const EdgeInsets.symmetric(horizontal: 50.0, vertical: 30.0), child: _buildLoginForm(context), ), ), @@ -200,26 +165,13 @@ class _LoginPageState extends State { passwordController: _passwordController, obscurePassword: _obscurePassword, highlightPasswordField: _highlightPasswordField, - onTogglePasswordVisibility: () { - if (!mounted) return; - setState(() { - _obscurePassword = !_obscurePassword; - }); - }, + onTogglePasswordVisibility: _togglePasswordVisibility, ), - ForgotPasswordButtonWidget(onPressed: () { - showDialog( - context: context, - builder: (BuildContext context) { - return const ForgotPasswordDialogWidget(); - }, - ); - }), + ForgotPasswordButtonWidget(onPressed: _forgotPassword), const SizedBox(height: 30), LoginButtonWidget( isLoading: _isLoading, - onPressed: () => Navigator.of(context).pushNamed( - '/calendar'), //Ici, remplacer par une fonction de connexion avec firebase Auth + onPressed: _signInWithEmailAndPassword, ), const SizedBox(height: 20), ErrorMessageWidget(errorMessage: _errorMessage), diff --git a/em2rp/lib/views/widgets/nav/main_drawer.dart b/em2rp/lib/views/widgets/nav/main_drawer.dart index 4c4cea7..76c9234 100644 --- a/em2rp/lib/views/widgets/nav/main_drawer.dart +++ b/em2rp/lib/views/widgets/nav/main_drawer.dart @@ -4,7 +4,7 @@ import 'package:em2rp/views/calendar_page.dart'; import 'package:em2rp/views/my_account_page.dart'; import 'package:em2rp/views/user_management_page.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; // Import Provider +// Import Provider class MainDrawer extends StatelessWidget { final String currentPage;