import 'package:flutter/material.dart'; import 'package:geosector_app/app.dart'; import 'package:geosector_app/core/data/models/user_model.dart'; import 'package:geosector_app/presentation/widgets/user_form.dart'; class ProfileDialog extends StatefulWidget { final UserModel user; const ProfileDialog({ Key? key, required this.user, }) : super(key: key); /// Méthode statique pour afficher la boîte de dialogue static Future show(BuildContext context, UserModel user) { return showDialog( context: context, builder: (context) => ProfileDialog(user: user), ); } @override State createState() => _ProfileDialogState(); } class _ProfileDialogState extends State { final _formKey = GlobalKey(); late UserModel _user; bool _isLoading = false; @override void initState() { super.initState(); _user = widget.user; } // Fonction pour capitaliser la première lettre de chaque mot String _capitalizeFirstLetter(String text) { if (text.isEmpty) return text; return text.split(' ').map((word) { if (word.isEmpty) return word; return word[0].toUpperCase() + word.substring(1).toLowerCase(); }).join(' '); } // Fonction pour mettre en majuscule String _toUpperCase(String text) { return text.toUpperCase(); } // Fonction pour valider et soumettre le formulaire Future _saveProfile(UserModel updatedUser) async { // Validation supplémentaire if (!_validateUser(updatedUser)) { return; } setState(() { _isLoading = true; }); try { // Formatage des données final formattedUser = updatedUser.copyWith( name: _toUpperCase(updatedUser.name ?? ''), firstName: _capitalizeFirstLetter(updatedUser.firstName ?? ''), ); // Sauvegarde de l'utilisateur await userRepository.saveUser(formattedUser); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Profil mis à jour avec succès'), backgroundColor: Colors.green, ), ); Navigator.of(context).pop(true); // Fermer la modale avec succès } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Erreur lors de la mise à jour du profil: $e'), backgroundColor: Colors.red, ), ); } } finally { if (mounted) { setState(() { _isLoading = false; }); } } } // Validation supplémentaire bool _validateUser(UserModel user) { // Vérifier que l'email est valide if (user.email.isEmpty || !user.email.contains('@') || !user.email.contains('.')) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Veuillez entrer une adresse email valide'), backgroundColor: Colors.red, ), ); return false; } // Vérifier que le nom ou le sectName est renseigné if ((user.name == null || user.name!.isEmpty) && (user.sectName == null || user.sectName!.isEmpty)) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Le nom ou le nom du secteur doit être renseigné'), backgroundColor: Colors.red, ), ); return false; } // Vérifier que le téléphone fixe est valide s'il est renseigné if (user.phone != null && user.phone!.isNotEmpty && user.phone!.length != 10) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Le numéro de téléphone fixe doit contenir 10 chiffres'), backgroundColor: Colors.red, ), ); return false; } // Vérifier que le téléphone mobile est valide s'il est renseigné if (user.mobile != null && user.mobile!.isNotEmpty && user.mobile!.length != 10) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Le numéro de téléphone mobile doit contenir 10 chiffres'), backgroundColor: Colors.red, ), ); return false; } return true; } @override Widget build(BuildContext context) { final theme = Theme.of(context); return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: 0, backgroundColor: Colors.transparent, child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: theme.colorScheme.surface, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, 5), ), ], ), constraints: const BoxConstraints( maxWidth: 600, maxHeight: 700, ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Titre Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Mon compte', style: theme.textTheme.headlineSmall?.copyWith( color: theme.colorScheme.primary, fontWeight: FontWeight.bold, ), ), IconButton( icon: const Icon(Icons.close), onPressed: () => Navigator.of(context).pop(), tooltip: 'Fermer', ), ], ), const Divider(), const SizedBox(height: 10), // Formulaire Expanded( child: SingleChildScrollView( child: UserForm( user: _user, onSubmit: _saveProfile, ), ), ), // Boutons const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: _isLoading ? null : () => Navigator.of(context).pop(), style: TextButton.styleFrom( padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 12), ), child: const Text('Fermer'), ), const SizedBox(width: 10), ElevatedButton( onPressed: _isLoading ? null : () { // Appeler directement la méthode onSubmit du UserForm // qui va déclencher la validation et la soumission _saveProfile(_user); }, style: ElevatedButton.styleFrom( backgroundColor: theme.colorScheme.primary, foregroundColor: theme.colorScheme.onPrimary, padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 12), ), child: _isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : const Text('Enregistrer'), ), ], ), ], ), ), ); } }