SEND063
This commit is contained in:
83
frontend/pweb/lib/widgets/payment/source_of_funds_panel.dart
Normal file
83
frontend/pweb/lib/widgets/payment/source_of_funds_panel.dart
Normal file
@@ -0,0 +1,83 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pweb/models/payment/source_funds.dart';
|
||||
import 'package:pweb/pages/payout_page/send/widgets/section/card.dart';
|
||||
import 'package:pweb/pages/payout_page/send/widgets/section/title.dart';
|
||||
|
||||
|
||||
class SourceOfFundsPanel extends StatelessWidget {
|
||||
const SourceOfFundsPanel({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.sourceSelector,
|
||||
this.visibleStates = const <SourceOfFundsVisibleState>{},
|
||||
this.stateWidgets = const <SourceOfFundsVisibleState, Widget>{},
|
||||
this.selectorSpacing = 8,
|
||||
this.sectionSpacing = 12,
|
||||
this.padding,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final Widget sourceSelector;
|
||||
final Set<SourceOfFundsVisibleState> visibleStates;
|
||||
final Map<SourceOfFundsVisibleState, Widget> stateWidgets;
|
||||
final double selectorSpacing;
|
||||
final double sectionSpacing;
|
||||
final EdgeInsetsGeometry? padding;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final headerAction = _stateWidget(SourceOfFundsVisibleState.headerAction);
|
||||
final headerActions = headerAction == null
|
||||
? const <Widget>[]
|
||||
: <Widget>[headerAction];
|
||||
final bodySections = _buildBodySections();
|
||||
|
||||
return PaymentSectionCard(
|
||||
padding: padding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: SectionTitle(title)),
|
||||
...headerActions,
|
||||
],
|
||||
),
|
||||
SizedBox(height: selectorSpacing),
|
||||
sourceSelector,
|
||||
if (bodySections.isNotEmpty) ...[
|
||||
SizedBox(height: sectionSpacing),
|
||||
const Divider(height: 1),
|
||||
SizedBox(height: sectionSpacing),
|
||||
...bodySections,
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildBodySections() {
|
||||
const orderedStates = <SourceOfFundsVisibleState>[
|
||||
SourceOfFundsVisibleState.summary,
|
||||
SourceOfFundsVisibleState.quoteStatus,
|
||||
SourceOfFundsVisibleState.sendAction,
|
||||
];
|
||||
|
||||
final sections = <Widget>[];
|
||||
for (final state in orderedStates) {
|
||||
final section = _stateWidget(state);
|
||||
if (section == null) continue;
|
||||
if (sections.isNotEmpty) {
|
||||
sections.add(SizedBox(height: sectionSpacing));
|
||||
}
|
||||
sections.add(section);
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
|
||||
Widget? _stateWidget(SourceOfFundsVisibleState state) {
|
||||
if (!visibleStates.contains(state)) return null;
|
||||
return stateWidgets[state];
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:pshared/controllers/balance_mask/wallets.dart';
|
||||
import 'package:pshared/controllers/payment/source.dart';
|
||||
import 'package:pshared/models/ledger/account.dart';
|
||||
import 'package:pshared/models/payment/source_type.dart';
|
||||
@@ -10,78 +9,52 @@ import 'package:pshared/utils/money.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
|
||||
typedef _SourceOptionKey = ({PaymentSourceType type, String ref});
|
||||
|
||||
class SourceWalletSelector extends StatelessWidget {
|
||||
const SourceWalletSelector({
|
||||
super.key,
|
||||
this.walletsController,
|
||||
this.sourceController,
|
||||
required this.sourceController,
|
||||
this.isBusy = false,
|
||||
this.onChanged,
|
||||
}) : assert(
|
||||
(walletsController != null) != (sourceController != null),
|
||||
'Provide either walletsController or sourceController',
|
||||
);
|
||||
});
|
||||
|
||||
final WalletsController? walletsController;
|
||||
final PaymentSourceController? sourceController;
|
||||
final PaymentSourceController sourceController;
|
||||
final bool isBusy;
|
||||
final ValueChanged<Wallet>? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final source = sourceController;
|
||||
if (source != null) {
|
||||
final selectedWallet = source.selectedWallet;
|
||||
final selectedLedger = source.selectedLedgerAccount;
|
||||
final selectedValue = switch (source.selectedType) {
|
||||
PaymentSourceType.wallet =>
|
||||
selectedWallet == null ? null : _walletKey(selectedWallet.id),
|
||||
PaymentSourceType.ledger =>
|
||||
selectedLedger == null
|
||||
? null
|
||||
: _ledgerKey(selectedLedger.ledgerAccountRef),
|
||||
null => null,
|
||||
};
|
||||
final selectedWallet = source.selectedWallet;
|
||||
final selectedLedger = source.selectedLedgerAccount;
|
||||
final selectedValue = switch (source.selectedType) {
|
||||
PaymentSourceType.wallet =>
|
||||
selectedWallet == null ? null : _walletKey(selectedWallet.id),
|
||||
PaymentSourceType.ledger =>
|
||||
selectedLedger == null
|
||||
? null
|
||||
: _ledgerKey(selectedLedger.ledgerAccountRef),
|
||||
null => null,
|
||||
};
|
||||
|
||||
return _buildSourceSelector(
|
||||
context: context,
|
||||
wallets: source.wallets,
|
||||
ledgerAccounts: source.ledgerAccounts,
|
||||
selectedValue: selectedValue,
|
||||
onChanged: (value) {
|
||||
if (value.type == PaymentSourceType.wallet) {
|
||||
source.selectWalletByRef(value.ref);
|
||||
final selected = source.selectedWallet;
|
||||
if (selected != null) {
|
||||
onChanged?.call(selected);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.type == PaymentSourceType.ledger) {
|
||||
source.selectLedgerByRef(value.ref);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
final wallets = walletsController!;
|
||||
return _buildSourceSelector(
|
||||
context: context,
|
||||
wallets: wallets.wallets,
|
||||
ledgerAccounts: const <LedgerAccount>[],
|
||||
selectedValue: wallets.selectedWalletRef == null
|
||||
? null
|
||||
: _walletKey(wallets.selectedWalletRef!),
|
||||
wallets: source.wallets,
|
||||
ledgerAccounts: source.ledgerAccounts,
|
||||
selectedValue: selectedValue,
|
||||
onChanged: (value) {
|
||||
if (value.type != PaymentSourceType.wallet) return;
|
||||
wallets.selectWalletByRef(value.ref);
|
||||
final selected = wallets.selectedWallet;
|
||||
if (selected != null) {
|
||||
onChanged?.call(selected);
|
||||
if (value.type == PaymentSourceType.wallet) {
|
||||
source.selectWalletByRef(value.ref);
|
||||
final selected = source.selectedWallet;
|
||||
if (selected != null) {
|
||||
onChanged?.call(selected);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.type == PaymentSourceType.ledger) {
|
||||
source.selectLedgerByRef(value.ref);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -106,7 +79,7 @@ class SourceWalletSelector extends StatelessWidget {
|
||||
return DropdownMenuItem<_SourceOptionKey>(
|
||||
value: _walletKey(wallet.id),
|
||||
child: Text(
|
||||
'${wallet.name} - ${_walletBalance(wallet)}',
|
||||
'${_walletDisplayName(wallet, l10n)} - ${_walletBalance(wallet)}',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
@@ -115,7 +88,7 @@ class SourceWalletSelector extends StatelessWidget {
|
||||
return DropdownMenuItem<_SourceOptionKey>(
|
||||
value: _ledgerKey(ledger.ledgerAccountRef),
|
||||
child: Text(
|
||||
'${ledger.name} - ${_ledgerBalance(ledger)}',
|
||||
'${_ledgerDisplayName(ledger, l10n)} - ${_ledgerBalance(ledger)}',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
@@ -157,6 +130,20 @@ class SourceWalletSelector extends StatelessWidget {
|
||||
_SourceOptionKey _ledgerKey(String ledgerAccountRef) =>
|
||||
(type: PaymentSourceType.ledger, ref: ledgerAccountRef);
|
||||
|
||||
String _walletDisplayName(Wallet wallet, AppLocalizations l10n) {
|
||||
final name = wallet.name.trim();
|
||||
if (name.isNotEmpty) return name;
|
||||
|
||||
return l10n.paymentTypeWallet;
|
||||
}
|
||||
|
||||
String _ledgerDisplayName(LedgerAccount ledger, AppLocalizations l10n) {
|
||||
final name = ledger.name.trim();
|
||||
if (name.isNotEmpty) return name;
|
||||
|
||||
return l10n.paymentTypeLedger;
|
||||
}
|
||||
|
||||
String _walletBalance(Wallet wallet) {
|
||||
final symbol = currencyCodeToSymbol(wallet.currency);
|
||||
return '$symbol ${amountToString(wallet.balance)}';
|
||||
|
||||
Reference in New Issue
Block a user