Files
sendico/frontend/pweb/lib/pages/payment_methods/page.dart
2025-12-25 19:24:45 +03:00

169 lines
5.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:provider/provider.dart';
import 'package:pshared/models/payment/methods/type.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pshared/provider/payment/flow.dart';
import 'package:pshared/provider/recipient/pmethods.dart';
import 'package:pshared/provider/recipient/provider.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pshared/provider/payment/wallets.dart';
import 'package:pweb/pages/payment_methods/payment_page/body.dart';
import 'package:pweb/widgets/sidebar/destinations.dart';
import 'package:pweb/services/posthog.dart';
class PaymentPage extends StatefulWidget {
final ValueChanged<Recipient?>? onBack;
final PaymentType? initialPaymentType;
final PayoutDestination fallbackDestination;
const PaymentPage({
super.key,
this.onBack,
this.initialPaymentType,
this.fallbackDestination = PayoutDestination.dashboard,
});
@override
State<PaymentPage> createState() => _PaymentPageState();
}
class _PaymentPageState extends State<PaymentPage> {
late final TextEditingController _searchController;
late final FocusNode _searchFocusNode;
@override
void initState() {
super.initState();
_searchController = TextEditingController();
_searchFocusNode = FocusNode();
WidgetsBinding.instance.addPostFrameCallback((_) => _initializePaymentPage());
}
@override
void dispose() {
_searchController.dispose();
_searchFocusNode.dispose();
super.dispose();
}
void _initializePaymentPage() {
final methodsProvider = context.read<PaymentMethodsProvider>();
_handleWalletAutoSelection(methodsProvider);
}
void _handleSearchChanged(String query) {
context.read<RecipientsProvider>().setQuery(query);
}
void _handleRecipientSelected(Recipient recipient) {
final recipientProvider = context.read<RecipientsProvider>();
final methodsProvider = context.read<PaymentMethodsProvider>();
final flowProvider = context.read<PaymentFlowProvider>();
recipientProvider.setCurrentObject(recipient.id);
flowProvider.reset(
recipient: recipient,
methodsProvider: methodsProvider,
preferredType: widget.initialPaymentType,
);
_clearSearchField();
}
void _handleRecipientCleared() {
final recipientProvider = context.read<RecipientsProvider>();
final methodsProvider = context.read<PaymentMethodsProvider>();
final flowProvider = context.read<PaymentFlowProvider>();
recipientProvider.setCurrentObject(null);
flowProvider.reset(
recipient: null,
methodsProvider: methodsProvider,
preferredType: widget.initialPaymentType,
);
_clearSearchField();
}
void _clearSearchField() {
_searchController.clear();
_searchFocusNode.unfocus();
context.read<RecipientsProvider>().setQuery('');
}
void _handleSendPayment() {
// TODO: Handle Payment logic
PosthogService.paymentInitiated(method: context.read<PaymentFlowProvider>().selectedType);
}
@override
Widget build(BuildContext context) {
final methodsProvider = context.watch<PaymentMethodsProvider>();
final recipientProvider = context.watch<RecipientsProvider>();
final recipient = recipientProvider.currentObject;
return ChangeNotifierProxyProvider2<RecipientsProvider, PaymentMethodsProvider, PaymentFlowProvider>(
create: (_) => PaymentFlowProvider(
initialType: widget.initialPaymentType ?? PaymentType.bankAccount,
),
update: (_, recipients, methods, flow) {
final provider = flow ?? PaymentFlowProvider(
initialType: widget.initialPaymentType ?? PaymentType.bankAccount,
);
final currentRecipient = recipients.currentObject;
provider.syncWith(
recipient: currentRecipient,
methodsProvider: methods,
preferredType: currentRecipient != null ? widget.initialPaymentType : null,
);
return provider;
},
child: PaymentPageBody(
onBack: widget.onBack,
fallbackDestination: widget.fallbackDestination,
recipient: recipient,
recipientProvider: recipientProvider,
methodsProvider: methodsProvider,
searchController: _searchController,
searchFocusNode: _searchFocusNode,
onSearchChanged: _handleSearchChanged,
onRecipientSelected: _handleRecipientSelected,
onRecipientCleared: _handleRecipientCleared,
onSend: _handleSendPayment,
),
);
}
void _handleWalletAutoSelection(PaymentMethodsProvider methodsProvider) {
final wallet = context.read<WalletsProvider>().selectedWallet;
if (wallet == null) return;
final matchingMethod = _getPaymentMethodForWallet(wallet, methodsProvider);
if (matchingMethod != null) {
methodsProvider.setCurrentObject(matchingMethod.id);
}
}
PaymentMethod? _getPaymentMethodForWallet(
Wallet wallet,
PaymentMethodsProvider methodsProvider,
) {
if (methodsProvider.methods.isEmpty) {
return null;
}
return methodsProvider.methods.firstWhereOrNull(
(method) =>
method.type == PaymentType.wallet &&
(method.description?.contains(wallet.walletUserID) ?? false),
);
}
}