import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../core/design/tokens.dart'; import '../../../core/design/tripz_colors.dart'; import '../../../core/di.dart'; import '../../../core/l10n/l10n.dart'; import '../../../core/payments/payment_channels.dart'; import '../../../core/tenant/tenant_cubit.dart'; import '../../../core/ui/channel_picker.dart'; import '../../../core/ui/empty_view.dart'; import '../../../core/ui/status_banner.dart'; import '../../../core/ui/tripz_button.dart'; import '../../../core/ui/tripz_scaffold.dart'; import '../../../core/ui/tripz_sheet.dart'; import '../../../core/ui/tripz_text_field.dart'; import '../cubit/wallet_cubit.dart'; import '../cubit/wallet_state.dart'; import 'widgets/balance_card.dart'; import 'widgets/invoice_sheet.dart'; import 'widgets/txn_tile.dart'; /// محفظة الراكب — **رصيدٌ دفعه ولم يستهلكه**، أي التزامٌ على المنصّة. /// شاشة السائق مختلفة عمداً (أرباح + سحب): لا تُوحَّدان (docs/39 §4). class WalletPage extends StatefulWidget { const WalletPage({super.key}); @override State createState() => _WalletPageState(); } class _WalletPageState extends State { late final WalletCubit _cubit = sl()..load(); @override void dispose() { _cubit.close(); super.dispose(); } @override Widget build(BuildContext context) { final l10n = context.l10n; return BlocProvider.value( value: _cubit, child: BlocConsumer( listenWhen: (p, n) => p.action != n.action, listener: (context, state) { if (state.action == WalletAction.topupFailed) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(l10n.walletTopupFailed)), ); } // الفاتورة تُعرض فور جهوزها: المستخدم يحتاج المرجع وحساب الاستلام // قبل أن يغادر التطبيق ليحوّل. final invoice = state.invoice; if (state.action == WalletAction.invoiceReady && invoice != null) { TripzSheet.show(context, child: InvoiceSheet(invoice: invoice)); } }, builder: (context, state) { return TripzScaffold( title: l10n.walletTitle, status: state.status, error: state.error, onRetry: _cubit.load, child: ListView( children: [ BalanceCard( label: l10n.walletBalance, balance: state.wallet?.balance, currency: state.currency, action: TripzButton.primary( label: l10n.walletTopup, loading: state.action == WalletAction.toppingUp, onPressed: () => _openTopup(context), ), ), const SizedBox(height: Space.lg), Text(l10n.walletTransactions, style: context.texts.titleMedium), const SizedBox(height: Space.xs), if (state.transactions.isEmpty) Padding( padding: const EdgeInsets.only(top: Space.xl), child: EmptyView( icon: Icons.receipt_long_outlined, message: l10n.walletEmpty, ), ) else for (final txn in state.transactions) TxnTile(txn: txn, currency: state.currency), ], ), ); }, ), ); } void _openTopup(BuildContext context) { final l10n = context.l10n; final controller = TextEditingController(); // القنوات من حزمة دولة المستأجر لا من لغة الجهاز (docs/38 §10). final channels = PaymentChannel.forCountry( context.read().state.countryPack, ); var channel = channels.first; TripzSheet.show( context, title: l10n.walletTopup, child: StatefulBuilder( builder: (context, setState) => Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TripzTextField( controller: controller, label: l10n.walletTopupAmount, numeric: true, autofocus: true, keyboardType: const TextInputType.numberWithOptions(decimal: true), ), const SizedBox(height: Space.md), Text(l10n.walletChannel, style: context.texts.titleSmall), const SizedBox(height: Space.xs), ChannelPicker( channels: channels, selected: channel, onSelect: (c) => setState(() => channel = c), ), const SizedBox(height: Space.md), // الشحن ليس فورياً في قنوات الفاتورة — يُقال قبل الضغط لا بعده. if (channel != PaymentChannel.cash) StatusBanner( message: l10n.walletInvoicePending, tone: BannerTone.info, icon: Icons.schedule_rounded, ), ], ), ), bottomAction: TripzButton.primary( label: l10n.walletTopup, onPressed: () { final amount = num.tryParse(controller.text.trim()); Navigator.of(context).pop(); if (amount != null) { _cubit.topup(amount: amount, provider: channel.wire); } }, ), ); } }