/// Dialog pour rejeter une transaction library reject_dialog; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import '../../../../core/validation/validators.dart'; import '../../../../shared/design_system/unionflow_design_system.dart'; import '../../domain/entities/transaction_approval.dart'; import '../bloc/approval_bloc.dart'; import '../bloc/approval_event.dart'; class RejectDialog extends StatefulWidget { final TransactionApproval approval; const RejectDialog({ super.key, required this.approval, }); @override State createState() => _RejectDialogState(); } class _RejectDialogState extends State { final _reasonController = TextEditingController(); final _formKey = GlobalKey(); @override void dispose() { _reasonController.dispose(); super.dispose(); } String _getTransactionTypeLabel(TransactionType type) { switch (type) { case TransactionType.contribution: return 'Cotisation'; case TransactionType.deposit: return 'Dépôt'; case TransactionType.withdrawal: return 'Retrait'; case TransactionType.transfer: return 'Transfert'; case TransactionType.solidarity: return 'Solidarité'; case TransactionType.event: return 'Événement'; case TransactionType.other: return 'Autre'; } } @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; final currencyFormat = NumberFormat.currency(symbol: widget.approval.currency); return AlertDialog( title: const Text('Rejeter la transaction'), content: SingleChildScrollView( child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Vous êtes sur le point de rejeter cette transaction.', style: AppTypography.bodyTextSmall.copyWith( color: AppColors.error, fontWeight: FontWeight.w500, ), ), const SizedBox(height: SpacingTokens.md), Container( padding: const EdgeInsets.all(SpacingTokens.md), decoration: BoxDecoration( color: isDark ? AppColors.surfaceDark : AppColors.surface, borderRadius: BorderRadius.circular(SpacingTokens.radiusSm), border: Border.all(color: isDark ? AppColors.borderDark : AppColors.border), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildInfoRow( 'Type', _getTransactionTypeLabel(widget.approval.transactionType), ), const SizedBox(height: SpacingTokens.sm), _buildInfoRow( 'Montant', currencyFormat.format(widget.approval.amount), valueStyle: AppTypography.actionText.copyWith( color: AppColors.primary, fontWeight: FontWeight.bold, ), ), const SizedBox(height: SpacingTokens.sm), _buildInfoRow( 'Demandeur', widget.approval.requesterName, ), ], ), ), const SizedBox(height: SpacingTokens.md), TextFormField( controller: _reasonController, decoration: const InputDecoration( labelText: 'Raison du rejet *', hintText: 'Expliquez la raison du rejet...', border: OutlineInputBorder(), helperText: 'Minimum 10 caractères, maximum 500', ), maxLines: 4, maxLength: 500, validator: FinanceValidators.rejectionReason(), ), ], ), ), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Annuler'), ), ElevatedButton.icon( onPressed: () { if (_formKey.currentState!.validate()) { context.read().add( RejectTransactionEvent( approvalId: widget.approval.id, reason: _reasonController.text.trim(), ), ); Navigator.of(context).pop(); } }, icon: const Icon(Icons.close), label: const Text('Rejeter'), style: ElevatedButton.styleFrom( backgroundColor: AppColors.error, foregroundColor: AppColors.onError, ), ), ], ); } Widget _buildInfoRow(String label, String value, {TextStyle? valueStyle}) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 90, child: Text( '$label :', style: AppTypography.subtitleSmall.copyWith( fontWeight: FontWeight.w600, ), ), ), Expanded( child: Text( value, style: valueStyle ?? AppTypography.bodyTextSmall, ), ), ], ); } }