From 28d74d058bd9c8b87d4dc5f907ddba48d0ce86a3 Mon Sep 17 00:00:00 2001 From: Arseni Date: Fri, 12 Dec 2025 19:29:10 +0300 Subject: [PATCH 1/2] Empty state for Recipient Adress Book --- .../lib/pages/address_book/page/empty.dart | 37 +++++++++++++++++++ .../lib/pages/address_book/page/page.dart | 24 ++++++++---- .../single/adress_book/placeholder.dart | 18 +++++++++ .../payouts/single/adress_book/widget.dart | 27 +++++++++----- 4 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 frontend/pweb/lib/pages/address_book/page/empty.dart create mode 100644 frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/placeholder.dart diff --git a/frontend/pweb/lib/pages/address_book/page/empty.dart b/frontend/pweb/lib/pages/address_book/page/empty.dart new file mode 100644 index 0000000..2efb88d --- /dev/null +++ b/frontend/pweb/lib/pages/address_book/page/empty.dart @@ -0,0 +1,37 @@ + +import 'package:flutter/material.dart'; + + +class RecipientAddressBookEmptyState extends StatelessWidget { + final String message; + final String actionLabel; + final VoidCallback onAction; + + const RecipientAddressBookEmptyState({ + required this.message, + required this.actionLabel, + required this.onAction, + }); + + @override + Widget build(BuildContext context) { + final textTheme = Theme.of(context).textTheme; + + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.contact_mail_outlined, size: 42), + const SizedBox(height: 12), + Text(message, style: textTheme.titleMedium), + const SizedBox(height: 12), + OutlinedButton.icon( + onPressed: onAction, + icon: const Icon(Icons.add), + label: Text(actionLabel), + ), + ], + ), + ); + } +} diff --git a/frontend/pweb/lib/pages/address_book/page/page.dart b/frontend/pweb/lib/pages/address_book/page/page.dart index e8de8a6..927a51d 100644 --- a/frontend/pweb/lib/pages/address_book/page/page.dart +++ b/frontend/pweb/lib/pages/address_book/page/page.dart @@ -5,6 +5,7 @@ import 'package:provider/provider.dart'; import 'package:pshared/models/recipient/recipient.dart'; import 'package:pshared/models/recipient/filter.dart'; import 'package:pshared/provider/recipient/provider.dart'; +import 'package:pweb/pages/address_book/page/empty.dart'; import 'package:pweb/pages/address_book/page/filter_button.dart'; import 'package:pweb/pages/address_book/page/header.dart'; @@ -72,6 +73,7 @@ class _RecipientAddressBookPageState extends State { final loc = AppLocalizations.of(context)!; final provider = context.watch(); _syncSearchField(provider); + final filteredRecipients = provider.filteredRecipients; if (provider.isLoading) { return const Center(child: CircularProgressIndicator()); @@ -124,15 +126,23 @@ class _RecipientAddressBookPageState extends State { height: RecipientAddressBookPage._expandedHeight, child: Padding( padding: const EdgeInsets.all(RecipientAddressBookPage._paddingAll), - child: RecipientAddressBookList( - filteredRecipients: provider.filteredRecipients, - onEdit: (recipient) => widget.onEditRecipient?.call(recipient), - onDelete: (recipient) => widget.onDeleteRecipient?.call(recipient), - onSelected: widget.onRecipientSelected, - ), + child: provider.recipients.isEmpty + ? RecipientAddressBookEmptyState( + message: loc.noRecipientsYet, + actionLabel: loc.addRecipient, + onAction: widget.onAddRecipient, + ) + : filteredRecipients.isEmpty + ? Center(child: Text(loc.noRecipientsFound)) + : RecipientAddressBookList( + filteredRecipients: filteredRecipients, + onEdit: (recipient) => widget.onEditRecipient?.call(recipient), + onDelete: (recipient) => widget.onDeleteRecipient?.call(recipient), + onSelected: widget.onRecipientSelected, + ), ), ), ], ); } -} +} \ No newline at end of file diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/placeholder.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/placeholder.dart new file mode 100644 index 0000000..821e7c2 --- /dev/null +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/placeholder.dart @@ -0,0 +1,18 @@ + +import 'package:flutter/material.dart'; + + +class AddressBookPlaceholder extends StatelessWidget { + final String text; + + const AddressBookPlaceholder({required this.text}); + + @override + Widget build(BuildContext context) => Center( + child: Text( + text, + style: Theme.of(context).textTheme.titleMedium, + textAlign: TextAlign.center, + ), + ); +} \ No newline at end of file diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/widget.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/widget.dart index 92e6911..905d94c 100644 --- a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/widget.dart +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/widget.dart @@ -7,6 +7,7 @@ import 'package:pshared/provider/recipient/provider.dart'; import 'package:pweb/pages/address_book/page/search.dart'; import 'package:pweb/pages/dashboard/payouts/single/adress_book/long_list/widget.dart'; +import 'package:pweb/pages/dashboard/payouts/single/adress_book/placeholder.dart'; import 'package:pweb/pages/dashboard/payouts/single/adress_book/short_list.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; @@ -58,6 +59,8 @@ class _AdressBookPayoutState extends State { Widget build(BuildContext context) { final loc = AppLocalizations.of(context)!; final provider = context.watch(); + final recipients = provider.recipients; + final filteredRecipients = provider.filteredRecipients; if (provider.isLoading) { return const Center(child: CircularProgressIndicator()); @@ -87,15 +90,19 @@ class _AdressBookPayoutState extends State { ), const SizedBox(height: _spacingBetween), Expanded( - child: _isExpanded - ? LongListAdressBookPayout( - filteredRecipients: provider.filteredRecipients, - onSelected: widget.onSelected, - ) - : ShortListAdressBookPayout( - recipients: provider.recipients, - onSelected: widget.onSelected, - ), + child: recipients.isEmpty + ? AddressBookPlaceholder(text: loc.noRecipientsYet) + : _isExpanded && filteredRecipients.isEmpty + ? AddressBookPlaceholder(text: loc.noRecipientsFound) + : _isExpanded + ? LongListAdressBookPayout( + filteredRecipients: filteredRecipients, + onSelected: widget.onSelected, + ) + : ShortListAdressBookPayout( + recipients: recipients, + onSelected: widget.onSelected, + ), ), ], ), @@ -103,4 +110,4 @@ class _AdressBookPayoutState extends State { ), ); } -} +} \ No newline at end of file From 82b2f88122972ebcdefe2b6c13b74e93d7f9e84c Mon Sep 17 00:00:00 2001 From: Arseni Date: Fri, 12 Dec 2025 19:39:36 +0300 Subject: [PATCH 2/2] Changed the spelling of the word adress) --- frontend/pweb/lib/app/router/payout_shell.dart | 2 +- .../pages/address_book/form/method_tile.dart | 8 ++++---- .../pweb/lib/pages/address_book/form/page.dart | 8 ++++---- .../pweb/lib/pages/address_book/form/view.dart | 2 +- .../address_book/page/recipient/item.dart | 2 +- .../{adress_book => address_book}/avatar.dart | 0 .../long_list/info_row.dart | 0 .../long_list/item.dart | 4 ++-- .../long_list/widget.dart | 6 +++--- .../placeholder.dart | 0 .../short_list.dart | 6 +++--- .../{adress_book => address_book}/widget.dart | 18 +++++++++--------- .../dashboard/payouts/single/form/header.dart | 2 +- .../pages/dashboard/payouts/single/widget.dart | 4 ++-- 14 files changed, 31 insertions(+), 31 deletions(-) rename frontend/pweb/lib/pages/dashboard/payouts/single/{adress_book => address_book}/avatar.dart (100%) rename frontend/pweb/lib/pages/dashboard/payouts/single/{adress_book => address_book}/long_list/info_row.dart (100%) rename frontend/pweb/lib/pages/dashboard/payouts/single/{adress_book => address_book}/long_list/item.dart (94%) rename frontend/pweb/lib/pages/dashboard/payouts/single/{adress_book => address_book}/long_list/widget.dart (77%) rename frontend/pweb/lib/pages/dashboard/payouts/single/{adress_book => address_book}/placeholder.dart (100%) rename frontend/pweb/lib/pages/dashboard/payouts/single/{adress_book => address_book}/short_list.dart (88%) rename frontend/pweb/lib/pages/dashboard/payouts/single/{adress_book => address_book}/widget.dart (84%) diff --git a/frontend/pweb/lib/app/router/payout_shell.dart b/frontend/pweb/lib/app/router/payout_shell.dart index a569a56..64be50c 100644 --- a/frontend/pweb/lib/app/router/payout_shell.dart +++ b/frontend/pweb/lib/app/router/payout_shell.dart @@ -92,7 +92,7 @@ RouteBase payoutShellRoute() => ShellRoute( pageBuilder: (context, _) { final recipient = context.read().currentObject; return NoTransitionPage( - child: AdressBookRecipientForm( + child: AddressBookRecipientForm( recipient: recipient, onSaved: (_) => context.goToPayout(PayoutDestination.recipients), ), 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 466ddcd..fb0dba7 100644 --- a/frontend/pweb/lib/pages/address_book/form/method_tile.dart +++ b/frontend/pweb/lib/pages/address_book/form/method_tile.dart @@ -7,7 +7,7 @@ import 'package:pweb/pages/payment_methods/form.dart'; import 'package:pweb/pages/payment_methods/icon.dart'; -class AdressBookPaymentMethodTile extends StatefulWidget { +class AddressBookPaymentMethodTile extends StatefulWidget { final PaymentType type; final String title; final MethodMap methods; @@ -18,7 +18,7 @@ class AdressBookPaymentMethodTile extends StatefulWidget { final double sizeM; final TextStyle? titleTextStyle; - const AdressBookPaymentMethodTile({ + const AddressBookPaymentMethodTile({ super.key, required this.type, required this.title, @@ -31,10 +31,10 @@ class AdressBookPaymentMethodTile extends StatefulWidget { }); @override - State createState() => _AdressBookPaymentMethodTileState(); + State createState() => _AddressBookPaymentMethodTileState(); } -class _AdressBookPaymentMethodTileState extends State { +class _AddressBookPaymentMethodTileState extends State { @override Widget build(BuildContext context) { final theme = Theme.of(context); diff --git a/frontend/pweb/lib/pages/address_book/form/page.dart b/frontend/pweb/lib/pages/address_book/form/page.dart index 0404025..f70804f 100644 --- a/frontend/pweb/lib/pages/address_book/form/page.dart +++ b/frontend/pweb/lib/pages/address_book/form/page.dart @@ -21,17 +21,17 @@ import 'package:pweb/utils/snackbar.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; -class AdressBookRecipientForm extends StatefulWidget { +class AddressBookRecipientForm extends StatefulWidget { final Recipient? recipient; final ValueChanged? onSaved; - const AdressBookRecipientForm({super.key, this.recipient, this.onSaved}); + const AddressBookRecipientForm({super.key, this.recipient, this.onSaved}); @override - State createState() => _AdressBookRecipientFormState(); + State createState() => _AddressBookRecipientFormState(); } -class _AdressBookRecipientFormState extends State { +class _AddressBookRecipientFormState extends State { final _formKey = GlobalKey(); late TextEditingController _nameCtrl; late TextEditingController _emailCtrl; diff --git a/frontend/pweb/lib/pages/address_book/form/view.dart b/frontend/pweb/lib/pages/address_book/form/view.dart index cda3213..6994504 100644 --- a/frontend/pweb/lib/pages/address_book/form/view.dart +++ b/frontend/pweb/lib/pages/address_book/form/view.dart @@ -103,7 +103,7 @@ class FormView extends StatelessWidget { ), SizedBox(height: spacingFields), ...PaymentType.values.map( - (p) => AdressBookPaymentMethodTile( + (p) => AddressBookPaymentMethodTile( type: p, title: getPaymentTypeLabel(context, p), methods: methods, 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 458ee0c..af5d7bb 100644 --- a/frontend/pweb/lib/pages/address_book/page/recipient/item.dart +++ b/frontend/pweb/lib/pages/address_book/page/recipient/item.dart @@ -6,7 +6,7 @@ import 'package:pweb/pages/address_book/page/recipient/actions.dart'; import 'package:pweb/pages/address_book/page/recipient/info_column.dart'; import 'package:pweb/pages/address_book/page/recipient/payment_row.dart'; import 'package:pweb/pages/address_book/page/recipient/status.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/avatar.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/avatar.dart'; class RecipientAddressBookItem extends StatefulWidget { diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/avatar.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/avatar.dart similarity index 100% rename from frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/avatar.dart rename to frontend/pweb/lib/pages/dashboard/payouts/single/address_book/avatar.dart diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/info_row.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/info_row.dart similarity index 100% rename from frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/info_row.dart rename to frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/info_row.dart diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/item.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/item.dart similarity index 94% rename from frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/item.dart rename to frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/item.dart index 555bdbf..827b741 100644 --- a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/item.dart +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/item.dart @@ -6,8 +6,8 @@ import 'package:pshared/models/recipient/recipient.dart'; import 'package:pshared/provider/organizations.dart'; import 'package:pshared/provider/recipient/pmethods.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/avatar.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/long_list/info_row.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/avatar.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/long_list/info_row.dart'; import 'package:pweb/utils/payment/label.dart'; diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/widget.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/widget.dart similarity index 77% rename from frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/widget.dart rename to frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/widget.dart index 5f9f664..38120b9 100644 --- a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/long_list/widget.dart +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/long_list/widget.dart @@ -2,14 +2,14 @@ import 'package:flutter/material.dart'; import 'package:pshared/models/recipient/recipient.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/long_list/item.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/long_list/item.dart'; -class LongListAdressBookPayout extends StatelessWidget { +class LongListAddressBookPayout extends StatelessWidget { final List filteredRecipients; final ValueChanged? onSelected; - const LongListAdressBookPayout({ + const LongListAddressBookPayout({ super.key, required this.filteredRecipients, this.onSelected, diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/placeholder.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/placeholder.dart similarity index 100% rename from frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/placeholder.dart rename to frontend/pweb/lib/pages/dashboard/payouts/single/address_book/placeholder.dart diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/short_list.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/short_list.dart similarity index 88% rename from frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/short_list.dart rename to frontend/pweb/lib/pages/dashboard/payouts/single/address_book/short_list.dart index 8486f1c..69b378b 100644 --- a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/short_list.dart +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/short_list.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:pshared/models/recipient/recipient.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/avatar.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/avatar.dart'; -class ShortListAdressBookPayout extends StatelessWidget { +class ShortListAddressBookPayout extends StatelessWidget { final List recipients; final ValueChanged onSelected; - const ShortListAdressBookPayout({ + const ShortListAddressBookPayout({ super.key, required this.recipients, required this.onSelected, diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/widget.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/widget.dart similarity index 84% rename from frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/widget.dart rename to frontend/pweb/lib/pages/dashboard/payouts/single/address_book/widget.dart index 905d94c..ad8fdb7 100644 --- a/frontend/pweb/lib/pages/dashboard/payouts/single/adress_book/widget.dart +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/address_book/widget.dart @@ -6,26 +6,26 @@ import 'package:pshared/models/recipient/recipient.dart'; import 'package:pshared/provider/recipient/provider.dart'; import 'package:pweb/pages/address_book/page/search.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/long_list/widget.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/placeholder.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/short_list.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/long_list/widget.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/placeholder.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/short_list.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; -class AdressBookPayout extends StatefulWidget { +class AddressBookPayout extends StatefulWidget { final ValueChanged onSelected; - const AdressBookPayout({ + const AddressBookPayout({ super.key, required this.onSelected, }); @override - State createState() => _AdressBookPayoutState(); + State createState() => _AddressBookPayoutState(); } -class _AdressBookPayoutState extends State { +class _AddressBookPayoutState extends State { static const double _expandedHeight = 400; static const double _collapsedHeight = 200; static const double _cardMargin = 1; @@ -95,11 +95,11 @@ class _AdressBookPayoutState extends State { : _isExpanded && filteredRecipients.isEmpty ? AddressBookPlaceholder(text: loc.noRecipientsFound) : _isExpanded - ? LongListAdressBookPayout( + ? LongListAddressBookPayout( filteredRecipients: filteredRecipients, onSelected: widget.onSelected, ) - : ShortListAdressBookPayout( + : ShortListAddressBookPayout( recipients: recipients, onSelected: widget.onSelected, ), diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/form/header.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/form/header.dart index c895ebf..a83223a 100644 --- a/frontend/pweb/lib/pages/dashboard/payouts/single/form/header.dart +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/form/header.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:pshared/models/recipient/recipient.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/avatar.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/avatar.dart'; class RecipientHeader extends StatelessWidget{ diff --git a/frontend/pweb/lib/pages/dashboard/payouts/single/widget.dart b/frontend/pweb/lib/pages/dashboard/payouts/single/widget.dart index b7c3198..8336d55 100644 --- a/frontend/pweb/lib/pages/dashboard/payouts/single/widget.dart +++ b/frontend/pweb/lib/pages/dashboard/payouts/single/widget.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:pshared/models/payment/type.dart'; import 'package:pshared/models/recipient/recipient.dart'; -import 'package:pweb/pages/dashboard/payouts/single/adress_book/widget.dart'; +import 'package:pweb/pages/dashboard/payouts/single/address_book/widget.dart'; import 'package:pweb/pages/dashboard/payouts/single/new_recipient/payout.dart'; @@ -25,7 +25,7 @@ class SinglePayoutForm extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - AdressBookPayout(onSelected: onRecipientSelected), + AddressBookPayout(onSelected: onRecipientSelected), const SizedBox(height: _spacingBetweenAddressAndForm), SinglePayout(onGoToPayment: onGoToPayment), const SizedBox(height: _bottomSpacing),