/// Dialog pour enregistrer un paiement sur une adhésion library paiement_adhesion_dialog; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../shared/constants/payment_method_assets.dart'; import '../../bloc/adhesions_bloc.dart'; class PaiementAdhesionDialog extends StatefulWidget { final String adhesionId; final double montantRestant; final VoidCallback onPaid; const PaiementAdhesionDialog({ super.key, required this.adhesionId, required this.montantRestant, required this.onPaid, }); @override State createState() => _PaiementAdhesionDialogState(); } class _PaiementAdhesionDialogState extends State { final _montantController = TextEditingController(); final _refController = TextEditingController(); String? _methode; bool _loading = false; @override void initState() { super.initState(); _montantController.text = widget.montantRestant.toStringAsFixed(0); } @override void dispose() { _montantController.dispose(); _refController.dispose(); super.dispose(); } List> _buildPaymentMethodItems() { const codes = ['ESPECES', 'VIREMENT', 'WAVE_MONEY', 'ORANGE_MONEY', 'CHEQUE']; const labels = {'ESPECES': 'Espèces', 'VIREMENT': 'Virement', 'WAVE_MONEY': 'Wave Money', 'ORANGE_MONEY': 'Orange Money', 'CHEQUE': 'Chèque'}; return codes.map((code) { final label = labels[code] ?? code; return DropdownMenuItem( value: code, child: Row( mainAxisSize: MainAxisSize.min, children: [ PaymentMethodIcon(paymentMethodCode: code, width: 24, height: 24), const SizedBox(width: 12), Text(label), ], ), ); }).toList(); } void _submit() { final montant = double.tryParse(_montantController.text.replaceAll(',', '.')); if (montant == null || montant <= 0) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Montant invalide')), ); return; } if (montant > widget.montantRestant) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Le montant ne peut pas dépasser le restant dû')), ); return; } setState(() => _loading = true); context.read().add( EnregistrerPaiementAdhesion( widget.adhesionId, montantPaye: montant, methodePaiement: _methode, referencePaiement: _refController.text.trim().isEmpty ? null : _refController.text.trim(), ), ); widget.onPaid(); if (mounted) { setState(() => _loading = false); Navigator.of(context).pop(); } } @override Widget build(BuildContext context) { return AlertDialog( title: const Text('Enregistrer un paiement'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Restant dû : ${widget.montantRestant.toStringAsFixed(0)} FCFA'), const SizedBox(height: 16), TextField( controller: _montantController, decoration: const InputDecoration( labelText: 'Montant payé (FCFA)', border: OutlineInputBorder(), ), keyboardType: const TextInputType.numberWithOptions(decimal: true), enabled: !_loading, ), const SizedBox(height: 12), DropdownButtonFormField( value: _methode, decoration: const InputDecoration( labelText: 'Méthode de paiement', border: OutlineInputBorder(), ), items: _buildPaymentMethodItems(), onChanged: _loading ? null : (v) => setState(() => _methode = v), ), const SizedBox(height: 12), TextField( controller: _refController, decoration: const InputDecoration( labelText: 'Référence (optionnel)', border: OutlineInputBorder(), ), enabled: !_loading, ), ], ), ), actions: [ TextButton( onPressed: _loading ? null : () => Navigator.of(context).pop(), child: const Text('Annuler'), ), FilledButton( onPressed: _loading ? null : _submit, child: _loading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Enregistrer'), ), ], ); } }