From 5e49ee32441eadd10f12d2229a38a1a40a5ed75d Mon Sep 17 00:00:00 2001 From: Stephan D Date: Fri, 5 Dec 2025 10:27:55 +0100 Subject: [PATCH] address book complete --- frontend/pweb/lib/l10n/en.arb | 8 ++++++ frontend/pweb/lib/l10n/ru.arb | 8 ++++++ frontend/pweb/lib/main.dart | 1 - .../pages/address_book/form/method_tile.dart | 2 +- .../lib/pages/address_book/form/page.dart | 10 +++----- .../lib/pages/address_book/page/list.dart | 25 +++++++++++++++---- .../lib/pages/address_book/page/page.dart | 3 +++ .../address_book/page/recipient/actions.dart | 24 ++++++++++-------- .../address_book/page/recipient/item.dart | 8 +++--- frontend/pweb/lib/widgets/sidebar/page.dart | 10 +++++++- 10 files changed, 72 insertions(+), 27 deletions(-) diff --git a/frontend/pweb/lib/l10n/en.arb b/frontend/pweb/lib/l10n/en.arb index dd35628..df0f5dd 100644 --- a/frontend/pweb/lib/l10n/en.arb +++ b/frontend/pweb/lib/l10n/en.arb @@ -433,6 +433,14 @@ "@errorSaveRecipient": { "description": "Error message displayed when saving a recipient fails" }, + "recipientDeletedSuccessfully": "Recipient deleted successfully", + "@recipientDeletedSuccessfully": { + "description": "Success message displayed when a recipient is deleted" + }, + "errorDeleteRecipient": "Failed to delete recipient", + "@errorDeleteRecipient": { + "description": "Error message displayed when deleting a recipient fails" + }, "errorSignUp": "Error occured while signing up, try again later", "companyDescription": "Company Description", diff --git a/frontend/pweb/lib/l10n/ru.arb b/frontend/pweb/lib/l10n/ru.arb index f9ca079..0bd3b9f 100644 --- a/frontend/pweb/lib/l10n/ru.arb +++ b/frontend/pweb/lib/l10n/ru.arb @@ -433,6 +433,14 @@ "@errorSaveRecipient": { "description": "Сообщение об ошибке при неудачном сохранении получателя" }, + "recipientDeletedSuccessfully": "Получатель успешно удален", + "@recipientDeletedSuccessfully": { + "description": "Сообщение об успешном удалении получателя" + }, + "errorDeleteRecipient": "Не удалось удалить получателя", + "@errorDeleteRecipient": { + "description": "Сообщение об ошибке при неудачном удалении получателя" + }, "errorSignUp": "Произошла ошибка при регистрации, попробуйте позже", "companyDescription": "Описание компании", diff --git a/frontend/pweb/lib/main.dart b/frontend/pweb/lib/main.dart index 0272f0e..c75b50d 100644 --- a/frontend/pweb/lib/main.dart +++ b/frontend/pweb/lib/main.dart @@ -26,7 +26,6 @@ import 'package:pweb/providers/upload_history.dart'; import 'package:pweb/providers/wallets.dart'; import 'package:pweb/providers/wallet_transactions.dart'; // import 'package:pweb/services/amplitude.dart'; -// import 'package:pweb/services/amplitude.dart'; import 'package:pweb/services/operations.dart'; import 'package:pweb/services/payments/history.dart'; import 'package:pweb/services/wallet_transactions.dart'; diff --git a/frontend/pweb/lib/pages/address_book/form/method_tile.dart b/frontend/pweb/lib/pages/address_book/form/method_tile.dart index fb1de11..466ddcd 100644 --- a/frontend/pweb/lib/pages/address_book/form/method_tile.dart +++ b/frontend/pweb/lib/pages/address_book/form/method_tile.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:pshared/models/payment/methods/data.dart'; +import 'package:pshared/models/payment/methods/data.dart'; import 'package:pshared/models/payment/type.dart'; import 'package:pweb/pages/payment_methods/form.dart'; diff --git a/frontend/pweb/lib/pages/address_book/form/page.dart b/frontend/pweb/lib/pages/address_book/form/page.dart index 1db5c03..1568be3 100644 --- a/frontend/pweb/lib/pages/address_book/form/page.dart +++ b/frontend/pweb/lib/pages/address_book/form/page.dart @@ -72,13 +72,16 @@ class _AdressBookRecipientFormState extends State { Future _doSave() async { final recipients = context.read(); - final methods = context.read(); + 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(), recipient.id); for (final type in _methods.keys) { final data = _methods[type]!; final exising = methods.methods.firstWhereOrNull((m) => m.type == type); @@ -91,11 +94,6 @@ class _AdressBookRecipientFormState extends State { data: data, ); } - await methods.create( - reacipientRef: recipient.id, - name: getPaymentTypeLabel(context, data.type), - data: data, - ); } return recipient; } diff --git a/frontend/pweb/lib/pages/address_book/page/list.dart b/frontend/pweb/lib/pages/address_book/page/list.dart index 1555dc3..710d885 100644 --- a/frontend/pweb/lib/pages/address_book/page/list.dart +++ b/frontend/pweb/lib/pages/address_book/page/list.dart @@ -1,6 +1,11 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'package:pshared/models/permissions/action.dart' as perm; import 'package:pshared/models/recipient/recipient.dart'; +import 'package:pshared/models/resources.dart'; +import 'package:pshared/provider/permissions.dart'; import 'package:pweb/pages/address_book/page/recipient/item.dart'; @@ -19,9 +24,16 @@ class RecipientAddressBookList extends StatelessWidget { this.onDelete, }); + bool _checkPermissions(BuildContext context, Recipient recipient, perm.Action action) { + return context.read().canAccessResource( + ResourceType.recipients, + action: action, + objectRef: recipient.id, + ); + } + @override -Widget build(BuildContext context) { - return ListView.builder( + Widget build(BuildContext context) => ListView.builder( itemCount: filteredRecipients.length, itemBuilder: (context, index) { final recipient = filteredRecipients[index]; @@ -30,11 +42,14 @@ Widget build(BuildContext context) { child: RecipientAddressBookItem( recipient: recipient, onTap: () => onSelected?.call(recipient), - onEdit: () => onEdit?.call(recipient), - onDelete: () => onDelete?.call(recipient), + onEdit: _checkPermissions(context, recipient, perm.Action.update) + ? () => onEdit?.call(recipient) + : null, + onDelete: _checkPermissions(context, recipient, perm.Action.delete) + ? () => onDelete?.call(recipient) + : null, ), ); }, ); } -} diff --git a/frontend/pweb/lib/pages/address_book/page/page.dart b/frontend/pweb/lib/pages/address_book/page/page.dart index c23664d..e8de8a6 100644 --- a/frontend/pweb/lib/pages/address_book/page/page.dart +++ b/frontend/pweb/lib/pages/address_book/page/page.dart @@ -18,12 +18,14 @@ class RecipientAddressBookPage extends StatefulWidget { final ValueChanged onRecipientSelected; final VoidCallback onAddRecipient; final ValueChanged? onEditRecipient; + final ValueChanged? onDeleteRecipient; const RecipientAddressBookPage({ super.key, required this.onRecipientSelected, required this.onAddRecipient, this.onEditRecipient, + this.onDeleteRecipient, }); static const double _expandedHeight = 550; @@ -125,6 +127,7 @@ class _RecipientAddressBookPageState extends State { child: RecipientAddressBookList( filteredRecipients: provider.filteredRecipients, onEdit: (recipient) => widget.onEditRecipient?.call(recipient), + onDelete: (recipient) => widget.onDeleteRecipient?.call(recipient), onSelected: widget.onRecipientSelected, ), ), diff --git a/frontend/pweb/lib/pages/address_book/page/recipient/actions.dart b/frontend/pweb/lib/pages/address_book/page/recipient/actions.dart index 8007a83..21addf2 100644 --- a/frontend/pweb/lib/pages/address_book/page/recipient/actions.dart +++ b/frontend/pweb/lib/pages/address_book/page/recipient/actions.dart @@ -2,18 +2,22 @@ import 'package:flutter/material.dart'; class RecipientActions extends StatelessWidget { - final VoidCallback onEdit; - final VoidCallback onDelete; + final VoidCallback? onEdit; + final VoidCallback? onDelete; const RecipientActions({super.key, required this.onEdit, required this.onDelete}); @override - Widget build(BuildContext context) { - return Row( - children: [ - IconButton(icon: Icon(Icons.edit, color: Theme.of(context).colorScheme.primary), onPressed: onEdit), - IconButton(icon: Icon(Icons.delete, color: Theme.of(context).colorScheme.error), onPressed: onDelete), - ], - ); - } + Widget build(BuildContext context) => Row( + children: [ + IconButton( + icon: Icon(Icons.edit, color: Theme.of(context).colorScheme.primary), + onPressed: onEdit, + ), + IconButton( + icon: Icon(Icons.delete, color: Theme.of(context).colorScheme.error), + onPressed: onDelete, + ), + ], + ); } diff --git a/frontend/pweb/lib/pages/address_book/page/recipient/item.dart b/frontend/pweb/lib/pages/address_book/page/recipient/item.dart index f8b3917..458ee0c 100644 --- a/frontend/pweb/lib/pages/address_book/page/recipient/item.dart +++ b/frontend/pweb/lib/pages/address_book/page/recipient/item.dart @@ -12,8 +12,8 @@ import 'package:pweb/pages/dashboard/payouts/single/adress_book/avatar.dart'; class RecipientAddressBookItem extends StatefulWidget { final Recipient recipient; final VoidCallback onTap; - final VoidCallback onEdit; - final VoidCallback onDelete; + final VoidCallback? onEdit; + final VoidCallback? onDelete; final double borderRadius; final double elevation; @@ -82,7 +82,9 @@ class _RecipientAddressBookItemState extends State { ), if (_isHovered) RecipientActions( - onEdit: widget.onEdit, onDelete: widget.onDelete), + onEdit: widget.onEdit, + onDelete: widget.onDelete, + ), ], ), SizedBox(height: widget.spacingBottom), diff --git a/frontend/pweb/lib/widgets/sidebar/page.dart b/frontend/pweb/lib/widgets/sidebar/page.dart index 2df19e1..e6a76cf 100644 --- a/frontend/pweb/lib/widgets/sidebar/page.dart +++ b/frontend/pweb/lib/widgets/sidebar/page.dart @@ -4,6 +4,7 @@ import 'package:provider/provider.dart'; import 'package:pshared/models/resources.dart'; import 'package:pshared/provider/permissions.dart'; +import 'package:pshared/provider/recipient/provider.dart'; import 'package:pweb/pages/address_book/form/page.dart'; import 'package:pweb/pages/address_book/page/page.dart'; @@ -17,6 +18,7 @@ import 'package:pweb/pages/dashboard/dashboard.dart'; import 'package:pweb/providers/page_selector.dart'; import 'package:pweb/utils/logout.dart'; import 'package:pweb/widgets/appbar/app_bar.dart'; +import 'package:pweb/widgets/error/snackbar.dart'; import 'package:pweb/widgets/sidebar/destinations.dart'; import 'package:pweb/widgets/sidebar/sidebar.dart'; @@ -29,7 +31,7 @@ class PageSelector extends StatelessWidget { @override Widget build(BuildContext context) => PageViewLoader( child: Builder(builder: (BuildContext context) { - final permissions = context.watch(); + final permissions = context.read(); if (!permissions.isReady) return Center(child: CircularProgressIndicator()); final provider = context.watch(); @@ -68,6 +70,12 @@ class PageSelector extends StatelessWidget { provider.selectRecipient(recipient, fromList: true), onAddRecipient: provider.goToAddRecipient, onEditRecipient: provider.editRecipient, + onDeleteRecipient: (recipient) => executeActionWithNotification( + context: context, + action: () async => context.read().delete(recipient.id), + successMessage: loc.recipientDeletedSuccessfully, + errorMessage: loc.errorDeleteRecipient, + ), ); break;