Files
sendico/frontend/pweb/lib/pages/address_book/form/page.dart
2025-12-09 21:02:37 +03:00

159 lines
4.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:provider/provider.dart';
import 'package:pshared/models/payment/methods/data.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pshared/models/recipient/status.dart';
import 'package:pshared/models/recipient/type.dart';
import 'package:pshared/provider/organizations.dart';
import 'package:pshared/provider/recipient/pmethods.dart';
import 'package:pshared/provider/recipient/provider.dart';
import 'package:pweb/pages/address_book/form/view.dart';
import 'package:pweb/services/posthog.dart';
import 'package:pweb/utils/error/snackbar.dart';
import 'package:pweb/utils/payment/label.dart';
import 'package:pweb/utils/snackbar.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class AdressBookRecipientForm extends StatefulWidget {
final Recipient? recipient;
final ValueChanged<Recipient?>? onSaved;
const AdressBookRecipientForm({super.key, this.recipient, this.onSaved});
@override
State<AdressBookRecipientForm> createState() => _AdressBookRecipientFormState();
}
class _AdressBookRecipientFormState extends State<AdressBookRecipientForm> {
final _formKey = GlobalKey<FormState>();
late TextEditingController _nameCtrl;
late TextEditingController _emailCtrl;
RecipientType _type = RecipientType.internal;
RecipientStatus _status = RecipientStatus.ready;
final MethodMap _methods = {};
late PaymentMethodsProvider _methodsProvider;
Future<void> _loadMethods() async {
_methodsProvider = PaymentMethodsProvider()..addListener(_onProviderChanged);
await _methodsProvider.loadMethods(
context.read<OrganizationsProvider>(),
widget.recipient?.id,
);
for (final m in _methodsProvider.methods) {
_methods[m.type] = switch (m.type) {
PaymentType.card => m.cardData,
PaymentType.iban => m.ibanData,
PaymentType.wallet => m.walletData,
PaymentType.bankAccount => m.bankAccountData,
PaymentType.cryptoAddress => m.cryptoAddressData,
};
}
}
@override
void initState() {
super.initState();
final r = widget.recipient;
_nameCtrl = TextEditingController(text: r?.name ?? '');
_emailCtrl = TextEditingController(text: r?.email ?? '');
_type = r?.type ?? RecipientType.internal;
_status = r?.status ?? RecipientStatus.ready;
_loadMethods();
}
Future<Recipient?> _doSave() async {
final recipients = context.read<RecipientsProvider>();
final methods = PaymentMethodsProvider();
final recipient = widget.recipient == null
? await recipients.create(
name: _nameCtrl.text,
email: _emailCtrl.text,
)
: widget.recipient!;
recipients.setCurrentObject(recipient.id);
//TODO : redesign work with recipients / payment methods
await methods.loadMethods(context.read<OrganizationsProvider>(), recipient.id);
for (final type in _methods.keys) {
final data = _methods[type]!;
final exising = methods.methods.firstWhereOrNull((m) => m.type == type);
if (exising != null) {
await methods.updateMethod(exising.copyWith(data: data));
} else {
await methods.create(
reacipientRef: recipient.id,
name: getPaymentTypeLabel(context, type),
data: data,
);
}
}
return recipient;
}
//TODO: Change when registration is ready
Future<void> _save() async {
if (!_formKey.currentState!.validate() || _methods.isEmpty) {
notifyUser(context, AppLocalizations.of(context)!.errorSaveRecipient);
return;
}
await PosthogService.recipientAddCompleted(
_type,
_status,
_methods.keys.toSet(),
);
final recipient = await executeActionWithNotification(
context: context,
action: _doSave,
errorMessage: AppLocalizations.of(context)!.errorSaveRecipient,
successMessage: AppLocalizations.of(context)!.recipientFormRule,
);
widget.onSaved?.call(recipient);
}
@override
void dispose() {
_methodsProvider.removeListener(_onProviderChanged);
_methodsProvider.dispose();
super.dispose();
}
void _onProviderChanged() => setState(() {});
@override
Widget build(BuildContext context) => FormView(
formKey: _formKey,
nameCtrl: _nameCtrl,
emailCtrl: _emailCtrl,
type: _type,
status: _status,
methods: _methods,
onTypeChanged: (t) => setState(() => _type = t),
onStatusChanged: (s) => setState(() => _status = s),
onMethodsChanged: (type, data) {
setState(() {
if (data != null) {
_methods[type] = data;
} else {
_methods.remove(type);
}
});
},
onSave: _save,
isEditing: widget.recipient != null,
onBack: () {
widget.onSaved?.call(null);
},
);
}