/// Dialogue de modification de membre /// Formulaire complet pour modifier un membre existant library edit_member_dialog; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import '../../bloc/membres_bloc.dart'; import '../../bloc/membres_event.dart'; import '../../data/models/membre_complete_model.dart'; /// Dialogue de modification de membre class EditMemberDialog extends StatefulWidget { final MembreCompletModel membre; const EditMemberDialog({ super.key, required this.membre, }); @override State createState() => _EditMemberDialogState(); } class _EditMemberDialogState extends State { final _formKey = GlobalKey(); // Contrôleurs de texte late final TextEditingController _nomController; late final TextEditingController _prenomController; late final TextEditingController _emailController; late final TextEditingController _telephoneController; late final TextEditingController _adresseController; late final TextEditingController _villeController; late final TextEditingController _codePostalController; late final TextEditingController _regionController; late final TextEditingController _paysController; late final TextEditingController _professionController; late final TextEditingController _nationaliteController; // Valeurs sélectionnées Genre? _selectedGenre; DateTime? _dateNaissance; StatutMembre? _selectedStatut; @override void initState() { super.initState(); // Initialiser les contrôleurs avec les valeurs existantes _nomController = TextEditingController(text: widget.membre.nom); _prenomController = TextEditingController(text: widget.membre.prenom); _emailController = TextEditingController(text: widget.membre.email); _telephoneController = TextEditingController(text: widget.membre.telephone ?? ''); _adresseController = TextEditingController(text: widget.membre.adresse ?? ''); _villeController = TextEditingController(text: widget.membre.ville ?? ''); _codePostalController = TextEditingController(text: widget.membre.codePostal ?? ''); _regionController = TextEditingController(text: widget.membre.region ?? ''); _paysController = TextEditingController(text: widget.membre.pays ?? ''); _professionController = TextEditingController(text: widget.membre.profession ?? ''); _nationaliteController = TextEditingController(text: widget.membre.nationalite ?? ''); _selectedGenre = widget.membre.genre; _dateNaissance = widget.membre.dateNaissance; _selectedStatut = widget.membre.statut; } @override void dispose() { _nomController.dispose(); _prenomController.dispose(); _emailController.dispose(); _telephoneController.dispose(); _adresseController.dispose(); _villeController.dispose(); _codePostalController.dispose(); _regionController.dispose(); _paysController.dispose(); _professionController.dispose(); _nationaliteController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Dialog( child: Container( width: MediaQuery.of(context).size.width * 0.9, constraints: const BoxConstraints(maxHeight: 600), child: Column( mainAxisSize: MainAxisSize.min, children: [ // En-tête Container( padding: const EdgeInsets.all(16), decoration: const BoxDecoration( color: Color(0xFF6C5CE7), borderRadius: BorderRadius.only( topLeft: Radius.circular(4), topRight: Radius.circular(4), ), ), child: Row( children: [ const Icon(Icons.edit, color: Colors.white), const SizedBox(width: 12), const Text( 'Modifier le membre', style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), const Spacer(), IconButton( icon: const Icon(Icons.close, color: Colors.white), onPressed: () => Navigator.pop(context), ), ], ), ), // Formulaire Expanded( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Informations personnelles _buildSectionTitle('Informations personnelles'), const SizedBox(height: 12), TextFormField( controller: _nomController, decoration: const InputDecoration( labelText: 'Nom *', border: OutlineInputBorder(), prefixIcon: Icon(Icons.person), ), validator: (value) { if (value == null || value.isEmpty) { return 'Le nom est obligatoire'; } return null; }, ), const SizedBox(height: 12), TextFormField( controller: _prenomController, decoration: const InputDecoration( labelText: 'Prénom *', border: OutlineInputBorder(), prefixIcon: Icon(Icons.person_outline), ), validator: (value) { if (value == null || value.isEmpty) { return 'Le prénom est obligatoire'; } return null; }, ), const SizedBox(height: 12), TextFormField( controller: _emailController, decoration: const InputDecoration( labelText: 'Email *', border: OutlineInputBorder(), prefixIcon: Icon(Icons.email), ), keyboardType: TextInputType.emailAddress, validator: (value) { if (value == null || value.isEmpty) { return 'L\'email est obligatoire'; } if (!value.contains('@')) { return 'Email invalide'; } return null; }, ), const SizedBox(height: 12), TextFormField( controller: _telephoneController, decoration: const InputDecoration( labelText: 'Téléphone', border: OutlineInputBorder(), prefixIcon: Icon(Icons.phone), ), keyboardType: TextInputType.phone, ), const SizedBox(height: 12), // Genre DropdownButtonFormField( value: _selectedGenre, decoration: const InputDecoration( labelText: 'Genre', border: OutlineInputBorder(), prefixIcon: Icon(Icons.wc), ), items: Genre.values.map((genre) { return DropdownMenuItem( value: genre, child: Text(_getGenreLabel(genre)), ); }).toList(), onChanged: (value) { setState(() { _selectedGenre = value; }); }, ), const SizedBox(height: 12), // Statut DropdownButtonFormField( value: _selectedStatut, decoration: const InputDecoration( labelText: 'Statut *', border: OutlineInputBorder(), prefixIcon: Icon(Icons.info), ), items: StatutMembre.values.map((statut) { return DropdownMenuItem( value: statut, child: Text(_getStatutLabel(statut)), ); }).toList(), onChanged: (value) { setState(() { _selectedStatut = value; }); }, ), const SizedBox(height: 12), // Date de naissance InkWell( onTap: () => _selectDate(context), child: InputDecorator( decoration: const InputDecoration( labelText: 'Date de naissance', border: OutlineInputBorder(), prefixIcon: Icon(Icons.calendar_today), ), child: Text( _dateNaissance != null ? DateFormat('dd/MM/yyyy').format(_dateNaissance!) : 'Sélectionner une date', ), ), ), const SizedBox(height: 16), // Adresse _buildSectionTitle('Adresse'), const SizedBox(height: 12), TextFormField( controller: _adresseController, decoration: const InputDecoration( labelText: 'Adresse', border: OutlineInputBorder(), prefixIcon: Icon(Icons.home), ), maxLines: 2, ), const SizedBox(height: 12), Row( children: [ Expanded( child: TextFormField( controller: _villeController, decoration: const InputDecoration( labelText: 'Ville', border: OutlineInputBorder(), ), ), ), const SizedBox(width: 12), Expanded( child: TextFormField( controller: _codePostalController, decoration: const InputDecoration( labelText: 'Code postal', border: OutlineInputBorder(), ), ), ), ], ), const SizedBox(height: 12), TextFormField( controller: _regionController, decoration: const InputDecoration( labelText: 'Région', border: OutlineInputBorder(), ), ), const SizedBox(height: 12), TextFormField( controller: _paysController, decoration: const InputDecoration( labelText: 'Pays', border: OutlineInputBorder(), ), ), ], ), ), ), ), // Boutons d'action Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.grey[100], border: Border(top: BorderSide(color: Colors.grey[300]!)), ), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Annuler'), ), const SizedBox(width: 12), ElevatedButton( onPressed: _submitForm, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF6C5CE7), foregroundColor: Colors.white, ), child: const Text('Enregistrer'), ), ], ), ), ], ), ), ); } Widget _buildSectionTitle(String title) { return Text( title, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Color(0xFF6C5CE7), ), ); } String _getGenreLabel(Genre genre) { switch (genre) { case Genre.homme: return 'Homme'; case Genre.femme: return 'Femme'; case Genre.autre: return 'Autre'; } } String _getStatutLabel(StatutMembre statut) { switch (statut) { case StatutMembre.actif: return 'Actif'; case StatutMembre.inactif: return 'Inactif'; case StatutMembre.suspendu: return 'Suspendu'; case StatutMembre.enAttente: return 'En attente'; } } Future _selectDate(BuildContext context) async { final DateTime? picked = await showDatePicker( context: context, initialDate: _dateNaissance ?? DateTime.now().subtract(const Duration(days: 365 * 25)), firstDate: DateTime(1900), lastDate: DateTime.now(), ); if (picked != null && picked != _dateNaissance) { setState(() { _dateNaissance = picked; }); } } void _submitForm() { if (_formKey.currentState!.validate()) { // Créer le modèle de membre mis à jour final membreUpdated = widget.membre.copyWith( nom: _nomController.text, prenom: _prenomController.text, email: _emailController.text, telephone: _telephoneController.text.isNotEmpty ? _telephoneController.text : null, dateNaissance: _dateNaissance, genre: _selectedGenre, adresse: _adresseController.text.isNotEmpty ? _adresseController.text : null, ville: _villeController.text.isNotEmpty ? _villeController.text : null, codePostal: _codePostalController.text.isNotEmpty ? _codePostalController.text : null, region: _regionController.text.isNotEmpty ? _regionController.text : null, pays: _paysController.text.isNotEmpty ? _paysController.text : null, profession: _professionController.text.isNotEmpty ? _professionController.text : null, nationalite: _nationaliteController.text.isNotEmpty ? _nationaliteController.text : null, statut: _selectedStatut!, ); // Envoyer l'événement au BLoC context.read().add(UpdateMembre(widget.membre.id!, membreUpdated)); // Fermer le dialogue Navigator.pop(context); // Afficher un message de succès ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Membre modifié avec succès'), backgroundColor: Colors.green, ), ); } } }