gcx/frontend/mobile/lib/features/wallet/presentation/pages/withdraw_page.dart

146 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import '../../../../app/i18n/app_localizations.dart';
import '../../../../app/theme/app_colors.dart';
import '../../../../app/theme/app_typography.dart';
import '../../../../app/theme/app_spacing.dart';
/// 提现页面
///
/// 将平台余额提现到银行账户
/// 展示可提现余额、手续费、到账时间
class WithdrawPage extends StatefulWidget {
const WithdrawPage({super.key});
@override
State<WithdrawPage> createState() => _WithdrawPageState();
}
class _WithdrawPageState extends State<WithdrawPage> {
final _amountController = TextEditingController();
double _balance = 128.50;
double get _amount => double.tryParse(_amountController.text) ?? 0;
double get _fee => _amount * 0.005; // 0.5%
double get _receive => _amount - _fee;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(context.t('withdraw.title'))),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Balance
Text(context.t('withdraw.availableBalance'), style: AppTypography.bodySmall),
const SizedBox(height: 4),
Text('\$${_balance.toStringAsFixed(2)}', style: AppTypography.displayMedium),
const SizedBox(height: 24),
// Amount Input
Text(context.t('withdraw.amount'), style: AppTypography.h3),
const SizedBox(height: 12),
TextField(
controller: _amountController,
keyboardType: const TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
prefixText: '\$ ',
suffixIcon: TextButton(
onPressed: () {
_amountController.text = _balance.toStringAsFixed(2);
setState(() {});
},
child: Text(context.t('withdraw.all')),
),
),
style: AppTypography.priceLarge,
onChanged: (_) => setState(() {}),
),
const SizedBox(height: 24),
// Withdraw To
Text(context.t('withdraw.to'), style: AppTypography.h3),
const SizedBox(height: 12),
Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: AppSpacing.borderRadiusMd,
border: Border.all(color: AppColors.primary),
),
child: Row(
children: [
const Icon(Icons.account_balance_rounded, color: AppColors.primary),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Bank of America •••• 6789', style: AppTypography.labelMedium),
Text(context.t('withdraw.savingsAccount'), style: AppTypography.caption),
],
),
),
const Icon(Icons.check_circle_rounded, color: AppColors.primary, size: 20),
],
),
),
const SizedBox(height: 24),
// Fee Details
if (_amount > 0) ...[
Container(
padding: AppSpacing.cardPadding,
decoration: BoxDecoration(
color: AppColors.gray50,
borderRadius: AppSpacing.borderRadiusMd,
),
child: Column(
children: [
_buildRow(context.t('withdraw.amount'), '\$${_amount.toStringAsFixed(2)}'),
_buildRow(context.t('withdraw.fee'), '-\$${_fee.toStringAsFixed(2)}'),
const Divider(height: 16),
_buildRow(context.t('withdraw.actualReceive'), '\$${_receive.toStringAsFixed(2)}', bold: true),
const SizedBox(height: 8),
Row(
children: [
const Icon(Icons.schedule_rounded, size: 14, color: AppColors.textTertiary),
const SizedBox(width: 4),
Text(context.t('withdraw.estimateTime'), style: AppTypography.caption),
],
),
],
),
),
],
],
),
),
bottomNavigationBar: Container(
padding: const EdgeInsets.all(20),
child: SizedBox(
height: AppSpacing.buttonHeight,
child: ElevatedButton(
onPressed: _amount > 0 && _amount <= _balance ? () {} : null,
child: Text('${context.t('withdraw.submit')} \$${_amount.toStringAsFixed(2)}'),
),
),
),
);
}
Widget _buildRow(String label, String value, {bool bold = false}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label, style: AppTypography.bodyMedium.copyWith(color: AppColors.textSecondary)),
Text(value, style: bold ? AppTypography.priceSmall : AppTypography.labelMedium),
],
),
);
}
}