import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import '../../services/auth_service.dart'; import '../../widgets/custom_app_text_field.dart'; import '../../widgets/image_button.dart'; /// Dialogue modal bloquant pour le changement de mot de passe obligatoire /// Utilisé après la première connexion quand changement_mdp_obligatoire = true class ChangePasswordDialog extends StatefulWidget { const ChangePasswordDialog({super.key}); @override State createState() => _ChangePasswordDialogState(); } class _ChangePasswordDialogState extends State { final _formKey = GlobalKey(); final _currentPasswordController = TextEditingController(); final _newPasswordController = TextEditingController(); final _confirmPasswordController = TextEditingController(); bool _isLoading = false; String? _errorMessage; @override void dispose() { _currentPasswordController.dispose(); _newPasswordController.dispose(); _confirmPasswordController.dispose(); super.dispose(); } String? _validateCurrentPassword(String? value) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre mot de passe actuel'; } return null; } String? _validateNewPassword(String? value) { if (value == null || value.isEmpty) { return 'Veuillez entrer un nouveau mot de passe'; } if (value.length < 8) { return 'Le mot de passe doit contenir au moins 8 caractères'; } if (!RegExp(r'[A-Z]').hasMatch(value)) { return 'Le mot de passe doit contenir au moins une majuscule'; } if (!RegExp(r'[a-z]').hasMatch(value)) { return 'Le mot de passe doit contenir au moins une minuscule'; } if (!RegExp(r'[0-9]').hasMatch(value)) { return 'Le mot de passe doit contenir au moins un chiffre'; } return null; } String? _validateConfirmPassword(String? value) { if (value == null || value.isEmpty) { return 'Veuillez confirmer votre nouveau mot de passe'; } if (value != _newPasswordController.text) { return 'Les mots de passe ne correspondent pas'; } return null; } Future _handleSubmit() async { // Réinitialiser le message d'erreur setState(() { _errorMessage = null; }); if (!(_formKey.currentState?.validate() ?? false)) { return; } setState(() { _isLoading = true; }); try { await AuthService.changePasswordRequired( currentPassword: _currentPasswordController.text, newPassword: _newPasswordController.text, ); if (mounted) { // Fermer le dialogue avec succès Navigator.of(context).pop(true); // Afficher un message de succès ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Mot de passe modifié avec succès', style: GoogleFonts.merienda(), ), backgroundColor: Colors.green, ), ); } } catch (e) { setState(() { _isLoading = false; _errorMessage = e.toString().replaceAll('Exception: ', ''); }); } } @override Widget build(BuildContext context) { return PopScope( // Empêcher la fermeture du dialogue avec le bouton retour canPop: false, child: Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), child: Container( constraints: const BoxConstraints(maxWidth: 500), padding: const EdgeInsets.all(30), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 20, offset: const Offset(0, 10), ), ], ), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Titre Text( 'Changement de mot de passe obligatoire', style: GoogleFonts.merienda( fontSize: 20, fontWeight: FontWeight.bold, color: const Color(0xFF2D6A4F), ), textAlign: TextAlign.center, ), const SizedBox(height: 10), // Message d'explication Text( 'Pour des raisons de sécurité, vous devez changer votre mot de passe avant de continuer.', style: GoogleFonts.merienda( fontSize: 14, color: Colors.black87, ), textAlign: TextAlign.center, ), const SizedBox(height: 25), // Champ mot de passe actuel CustomAppTextField( controller: _currentPasswordController, labelText: 'Mot de passe actuel', hintText: 'Votre mot de passe actuel', obscureText: true, validator: _validateCurrentPassword, style: CustomAppTextFieldStyle.lavande, fieldHeight: 53, fieldWidth: double.infinity, enabled: !_isLoading, ), const SizedBox(height: 15), // Champ nouveau mot de passe CustomAppTextField( controller: _newPasswordController, labelText: 'Nouveau mot de passe', hintText: 'Minimum 8 caractères', obscureText: true, validator: _validateNewPassword, style: CustomAppTextFieldStyle.jaune, fieldHeight: 53, fieldWidth: double.infinity, enabled: !_isLoading, ), const SizedBox(height: 15), // Champ confirmation mot de passe CustomAppTextField( controller: _confirmPasswordController, labelText: 'Confirmer le mot de passe', hintText: 'Retapez le nouveau mot de passe', obscureText: true, validator: _validateConfirmPassword, style: CustomAppTextFieldStyle.jaune, fieldHeight: 53, fieldWidth: double.infinity, enabled: !_isLoading, ), const SizedBox(height: 10), // Critères du mot de passe Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(10), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Le mot de passe doit contenir :', style: GoogleFonts.merienda( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 5), _buildPasswordCriteria('Au moins 8 caractères'), _buildPasswordCriteria('Au moins une majuscule'), _buildPasswordCriteria('Au moins une minuscule'), _buildPasswordCriteria('Au moins un chiffre'), ], ), ), // Message d'erreur if (_errorMessage != null) ...[ const SizedBox(height: 15), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.red[50], borderRadius: BorderRadius.circular(10), border: Border.all(color: Colors.red[300]!), ), child: Row( children: [ Icon(Icons.error_outline, color: Colors.red[700], size: 20), const SizedBox(width: 10), Expanded( child: Text( _errorMessage!, style: GoogleFonts.merienda( fontSize: 12, color: Colors.red[700], ), ), ), ], ), ), ], const SizedBox(height: 25), // Bouton de validation Center( child: _isLoading ? const CircularProgressIndicator() : ImageButton( bg: 'assets/images/bg_green.png', width: 250, height: 40, text: 'Changer le mot de passe', textColor: const Color(0xFF2D6A4F), onPressed: _handleSubmit, ), ), ], ), ), ), ), ); } Widget _buildPasswordCriteria(String text) { return Padding( padding: const EdgeInsets.only(top: 3, left: 5), child: Row( children: [ const Icon(Icons.check_circle_outline, size: 14, color: Colors.green), const SizedBox(width: 8), Text( text, style: GoogleFonts.merienda( fontSize: 11, color: Colors.black87, ), ), ], ), ); } }