/// Dialogue de création de contribution library create_contribution_dialog; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import '../../bloc/contributions_bloc.dart'; import '../../bloc/contributions_event.dart'; import '../../data/models/contribution_model.dart'; import '../../../members/bloc/membres_bloc.dart'; import '../../../members/bloc/membres_event.dart'; import '../../../members/bloc/membres_state.dart'; class CreateContributionDialog extends StatefulWidget { const CreateContributionDialog({super.key}); @override State createState() => _CreateContributionDialogState(); } class _CreateContributionDialogState extends State { final _formKey = GlobalKey(); final _montantController = TextEditingController(); final _descriptionController = TextEditingController(); ContributionType _selectedType = ContributionType.mensuelle; dynamic _selectedMembre; DateTime _dateEcheance = DateTime.now().add(const Duration(days: 30)); bool _isLoading = false; @override void initState() { super.initState(); // Charger la liste des membres context.read().add(const LoadMembres()); } @override void dispose() { _montantController.dispose(); _descriptionController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AlertDialog( title: const Text('Nouvelle contribution'), content: SizedBox( width: MediaQuery.of(context).size.width * 0.8, child: Form( key: _formKey, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ // Sélection du membre BlocBuilder( builder: (context, state) { if (state is MembresLoaded) { return DropdownButtonFormField( value: _selectedMembre, decoration: const InputDecoration( labelText: 'Membre', border: OutlineInputBorder(), ), items: state.membres.map((membre) { return DropdownMenuItem( value: membre, child: Text('${membre.nom} ${membre.prenom}'), ); }).toList(), onChanged: (value) { setState(() { _selectedMembre = value; }); }, validator: (value) { if (value == null) { return 'Veuillez sélectionner un membre'; } return null; }, ); } return const CircularProgressIndicator(); }, ), const SizedBox(height: 16), // Type de contribution DropdownButtonFormField( value: _selectedType, decoration: const InputDecoration( labelText: 'Type de contribution', border: OutlineInputBorder(), ), items: ContributionType.values.map((type) { return DropdownMenuItem( value: type, child: Text(_getTypeLabel(type)), ); }).toList(), onChanged: (value) { if (value != null) { setState(() { _selectedType = value; }); } }, ), const SizedBox(height: 16), // Montant TextFormField( controller: _montantController, decoration: const InputDecoration( labelText: 'Montant (FCFA)', border: OutlineInputBorder(), prefixIcon: Icon(Icons.attach_money), ), keyboardType: TextInputType.number, validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez saisir un montant'; } if (double.tryParse(value) == null) { return 'Montant invalide'; } return null; }, ), const SizedBox(height: 16), // Date d'échéance InkWell( onTap: () async { final date = await showDatePicker( context: context, initialDate: _dateEcheance, firstDate: DateTime.now(), lastDate: DateTime.now().add(const Duration(days: 365)), ); if (date != null) { setState(() { _dateEcheance = date; }); } }, child: InputDecorator( decoration: const InputDecoration( labelText: 'Date d\'échéance', border: OutlineInputBorder(), prefixIcon: Icon(Icons.calendar_today), ), child: Text( DateFormat('dd/MM/yyyy').format(_dateEcheance), ), ), ), const SizedBox(height: 16), // Description TextFormField( controller: _descriptionController, decoration: const InputDecoration( labelText: 'Description (optionnel)', border: OutlineInputBorder(), prefixIcon: Icon(Icons.description), ), maxLines: 3, ), ], ), ), ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Annuler'), ), ElevatedButton( onPressed: _isLoading ? null : _createContribution, child: _isLoading ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Créer'), ), ], ); } String _getTypeLabel(ContributionType type) { switch (type) { case ContributionType.mensuelle: return 'Mensuelle'; case ContributionType.trimestrielle: return 'Trimestrielle'; case ContributionType.semestrielle: return 'Semestrielle'; case ContributionType.annuelle: return 'Annuelle'; case ContributionType.exceptionnelle: return 'Exceptionnelle'; } } void _createContribution() { if (!_formKey.currentState!.validate()) { return; } if (_selectedMembre == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Veuillez sélectionner un membre'), backgroundColor: Colors.red, ), ); return; } setState(() { _isLoading = true; }); final contribution = ContributionModel( membreId: _selectedMembre!.id!, membreNom: _selectedMembre!.nom, membrePrenom: _selectedMembre!.prenom, type: _selectedType, annee: DateTime.now().year, montant: double.parse(_montantController.text), dateEcheance: _dateEcheance, description: _descriptionController.text.isNotEmpty ? _descriptionController.text : null, statut: ContributionStatus.nonPayee, dateCreation: DateTime.now(), dateModification: DateTime.now(), ); context.read().add(CreateContribution(contribution: contribution)); Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Contribution créée avec succès'), backgroundColor: Colors.green, ), ); } }