import 'package:flutter/material.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; import '../../core/i18n/app_localizations.dart'; import '../../core/theme/app_colors_extension.dart'; import '../models/user_model.dart'; class ApprovalActions extends StatefulWidget { final String status; final UserRole userRole; final VoidCallback onApprove; final VoidCallback onReject; final VoidCallback? onEdit; final VoidCallback? onWithdraw; final bool isSubmitting; const ApprovalActions({ super.key, required this.status, required this.userRole, required this.onApprove, required this.onReject, this.onEdit, this.onWithdraw, this.isSubmitting = false, }); @override State createState() => _ApprovalActionsState(); } class _ApprovalActionsState extends State { final _opinionCtrl = TextEditingController(); Future _showOpinionDialog(String action) async { final l10n = AppLocalizations.of(context); final result = await showDialog( context: context, builder: (ctx) => TDAlertDialog( title: action == 'approve' ? l10n.get('confirmApprove') : l10n.get('confirmReject'), contentWidget: Column( mainAxisSize: MainAxisSize.min, children: [ Text( l10n.getString( 'confirmAction', args: { 'action': action == 'approve' ? l10n.get('approve') : l10n.get('reject'), }, ), ), const SizedBox(height: 12), TDInput( controller: _opinionCtrl, type: TDInputType.longText, maxLines: 3, hintText: l10n.get('approvalComment'), ), ], ), leftBtn: TDDialogButtonOptions(title: l10n.get('cancel'), action: () => Navigator.pop(ctx, false)), rightBtn: TDDialogButtonOptions(title: l10n.get('confirm'), action: () => Navigator.pop(ctx, true)), ), ); if (result == true) { if (action == 'approve') { widget.onApprove(); } else { widget.onReject(); } } } @override Widget build(BuildContext context) { final colors = Theme.of(context).extension()!; final l10n = AppLocalizations.of(context); final isPending = widget.status == 'pending'; final isDraft = widget.status == 'draft'; final canApprove = isPending && (widget.userRole == UserRole.approver || widget.userRole == UserRole.finance || widget.userRole == UserRole.admin); return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 4, offset: const Offset(0, -1), ), ], ), child: canApprove ? Row( children: [ Expanded( child: TDButton( text: l10n.get('reject'), size: TDButtonSize.large, type: TDButtonType.outline, style: TDButtonStyle( frameColor: colors.danger, textColor: colors.danger, ), onTap: widget.isSubmitting ? null : () => _showOpinionDialog('reject'), ), ), const SizedBox(width: 12), Expanded( flex: 2, child: TDButton( text: widget.isSubmitting ? '' : l10n.get('approve'), size: TDButtonSize.large, theme: TDButtonTheme.primary, onTap: widget.isSubmitting ? null : () => _showOpinionDialog('approve'), iconWidget: widget.isSubmitting ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : null, ), ), ], ) : Row( children: [ if (isDraft && widget.onEdit != null) ...[ Expanded( child: TDButton( text: l10n.get('edit'), size: TDButtonSize.large, type: TDButtonType.outline, onTap: widget.onEdit, ), ), const SizedBox(width: 12), ], if (isPending && widget.onWithdraw != null) Expanded( child: TDButton( text: l10n.get('withdrawAction'), size: TDButtonSize.large, type: TDButtonType.outline, style: TDButtonStyle( frameColor: colors.warning, textColor: colors.warning, ), onTap: widget.onWithdraw, ), ), ], ), ); } @override void dispose() { _opinionCtrl.dispose(); super.dispose(); } }