address book complete

This commit is contained in:
Stephan D
2025-12-05 10:27:55 +01:00
parent e854963fa6
commit 5e49ee3244
10 changed files with 72 additions and 27 deletions

View File

@@ -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",

View File

@@ -433,6 +433,14 @@
"@errorSaveRecipient": {
"description": "Сообщение об ошибке при неудачном сохранении получателя"
},
"recipientDeletedSuccessfully": "Получатель успешно удален",
"@recipientDeletedSuccessfully": {
"description": "Сообщение об успешном удалении получателя"
},
"errorDeleteRecipient": "Не удалось удалить получателя",
"@errorDeleteRecipient": {
"description": "Сообщение об ошибке при неудачном удалении получателя"
},
"errorSignUp": "Произошла ошибка при регистрации, попробуйте позже",
"companyDescription": "Описание компании",

View File

@@ -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';

View File

@@ -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';

View File

@@ -72,13 +72,16 @@ class _AdressBookRecipientFormState extends State<AdressBookRecipientForm> {
Future<Recipient?> _doSave() async {
final recipients = context.read<RecipientsProvider>();
final methods = context.read<PaymentMethodsProvider>();
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);
@@ -91,11 +94,6 @@ class _AdressBookRecipientFormState extends State<AdressBookRecipientForm> {
data: data,
);
}
await methods.create(
reacipientRef: recipient.id,
name: getPaymentTypeLabel(context, data.type),
data: data,
);
}
return recipient;
}

View File

@@ -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<PermissionsProvider>().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,
),
);
},
);
}
}

View File

@@ -18,12 +18,14 @@ class RecipientAddressBookPage extends StatefulWidget {
final ValueChanged<Recipient> onRecipientSelected;
final VoidCallback onAddRecipient;
final ValueChanged<Recipient>? onEditRecipient;
final ValueChanged<Recipient>? 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<RecipientAddressBookPage> {
child: RecipientAddressBookList(
filteredRecipients: provider.filteredRecipients,
onEdit: (recipient) => widget.onEditRecipient?.call(recipient),
onDelete: (recipient) => widget.onDeleteRecipient?.call(recipient),
onSelected: widget.onRecipientSelected,
),
),

View File

@@ -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,
),
],
);
}

View File

@@ -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<RecipientAddressBookItem> {
),
if (_isHovered)
RecipientActions(
onEdit: widget.onEdit, onDelete: widget.onDelete),
onEdit: widget.onEdit,
onDelete: widget.onDelete,
),
],
),
SizedBox(height: widget.spacingBottom),

View File

@@ -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<PermissionsProvider>();
final permissions = context.read<PermissionsProvider>();
if (!permissions.isReady) return Center(child: CircularProgressIndicator());
final provider = context.watch<PageSelectorProvider>();
@@ -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<RecipientsProvider>().delete(recipient.id),
successMessage: loc.recipientDeletedSuccessfully,
errorMessage: loc.errorDeleteRecipient,
),
);
break;