Fixed issue with wallet form feild and made page selecor in dashboard into a router
This commit is contained in:
53
frontend/pweb/lib/app/router/payout_routes.dart
Normal file
53
frontend/pweb/lib/app/router/payout_routes.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'package:pweb/app/router/pages.dart';
|
||||
|
||||
import 'package:pweb/widgets/sidebar/destinations.dart';
|
||||
|
||||
|
||||
const _payoutBasePath = Pages.dashboard;
|
||||
|
||||
String payoutPath(PayoutDestination destination) {
|
||||
final base = routerPage(_payoutBasePath);
|
||||
switch (destination) {
|
||||
case PayoutDestination.dashboard:
|
||||
return base;
|
||||
case PayoutDestination.recipients:
|
||||
return '$base/recipients';
|
||||
case PayoutDestination.addrecipient:
|
||||
return '$base/recipients/add';
|
||||
case PayoutDestination.payment:
|
||||
return '$base/payment';
|
||||
case PayoutDestination.settings:
|
||||
return '$base/settings';
|
||||
case PayoutDestination.reports:
|
||||
return '$base/reports';
|
||||
case PayoutDestination.methods:
|
||||
return '$base/methods';
|
||||
case PayoutDestination.editwallet:
|
||||
return '$base/methods/edit';
|
||||
case PayoutDestination.sendPayout:
|
||||
return '$base/send';
|
||||
}
|
||||
}
|
||||
|
||||
PayoutDestination payoutDestinationFromLocation(String location) {
|
||||
final path = Uri.parse(location).path;
|
||||
|
||||
// Check longer paths first to avoid prefix collisions.
|
||||
for (final entry in _orderedRoutes) {
|
||||
if (path.startsWith(entry.value)) return entry.key;
|
||||
}
|
||||
|
||||
return PayoutDestination.dashboard;
|
||||
}
|
||||
|
||||
final List<MapEntry<PayoutDestination, String>> _orderedRoutes = [
|
||||
MapEntry(PayoutDestination.editwallet, payoutPath(PayoutDestination.editwallet)),
|
||||
MapEntry(PayoutDestination.addrecipient, payoutPath(PayoutDestination.addrecipient)),
|
||||
MapEntry(PayoutDestination.payment, payoutPath(PayoutDestination.payment)),
|
||||
MapEntry(PayoutDestination.recipients, payoutPath(PayoutDestination.recipients)),
|
||||
MapEntry(PayoutDestination.methods, payoutPath(PayoutDestination.methods)),
|
||||
MapEntry(PayoutDestination.reports, payoutPath(PayoutDestination.reports)),
|
||||
MapEntry(PayoutDestination.settings, payoutPath(PayoutDestination.settings)),
|
||||
MapEntry(PayoutDestination.sendPayout, payoutPath(PayoutDestination.sendPayout)),
|
||||
MapEntry(PayoutDestination.dashboard, payoutPath(PayoutDestination.dashboard)),
|
||||
];
|
||||
159
frontend/pweb/lib/app/router/payout_shell.dart
Normal file
159
frontend/pweb/lib/app/router/payout_shell.dart
Normal file
@@ -0,0 +1,159 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:pweb/app/router/pages.dart';
|
||||
import 'package:pweb/app/router/payout_routes.dart';
|
||||
import 'package:pweb/pages/address_book/form/page.dart';
|
||||
import 'package:pweb/pages/address_book/page/page.dart';
|
||||
import 'package:pweb/pages/dashboard/dashboard.dart';
|
||||
import 'package:pweb/pages/payout_page/page.dart';
|
||||
import 'package:pweb/pages/payout_page/wallet/edit/page.dart';
|
||||
import 'package:pweb/pages/payment_methods/page.dart';
|
||||
import 'package:pweb/pages/report/page.dart';
|
||||
import 'package:pweb/pages/settings/profile/page.dart';
|
||||
import 'package:pweb/providers/page_selector.dart';
|
||||
import 'package:pweb/widgets/sidebar/destinations.dart';
|
||||
import 'package:pweb/widgets/sidebar/page.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
|
||||
RouteBase payoutShellRoute() => ShellRoute(
|
||||
pageBuilder: (context, state, child) => NoTransitionPage(
|
||||
child: PageSelector(
|
||||
selected: payoutDestinationFromLocation(state.uri.toString()),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
name: Pages.dashboard.name,
|
||||
path: routerPage(Pages.dashboard),
|
||||
pageBuilder: (context, state) {
|
||||
final selector = context.read<PageSelectorProvider>();
|
||||
return NoTransitionPage(
|
||||
child: DashboardPage(
|
||||
onRecipientSelected: (recipient) {
|
||||
selector.selectRecipient(recipient);
|
||||
context.go(payoutPath(PayoutDestination.payment));
|
||||
},
|
||||
onGoToPaymentWithoutRecipient: (type) {
|
||||
selector.startPaymentWithoutRecipient(type);
|
||||
context.go(payoutPath(PayoutDestination.payment));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: 'payoutRecipients',
|
||||
path: payoutPath(PayoutDestination.recipients),
|
||||
pageBuilder: (context, state) {
|
||||
final selector = context.read<PageSelectorProvider>();
|
||||
return NoTransitionPage(
|
||||
child: RecipientAddressBookPage(
|
||||
onRecipientSelected: (recipient) {
|
||||
selector.selectRecipient(recipient, fromList: true);
|
||||
context.go(payoutPath(PayoutDestination.payment));
|
||||
},
|
||||
onAddRecipient: () {
|
||||
selector.goToAddRecipient();
|
||||
context.go(payoutPath(PayoutDestination.addrecipient));
|
||||
},
|
||||
onEditRecipient: (recipient) {
|
||||
selector.editRecipient(recipient, fromList: true);
|
||||
context.go(payoutPath(PayoutDestination.addrecipient));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: 'payoutAddRecipient',
|
||||
path: payoutPath(PayoutDestination.addrecipient),
|
||||
pageBuilder: (context, state) {
|
||||
final selector = context.read<PageSelectorProvider>();
|
||||
final recipient = selector.recipientProvider?.selectedRecipient;
|
||||
return NoTransitionPage(
|
||||
child: AdressBookRecipientForm(
|
||||
recipient: recipient,
|
||||
onSaved: (_) {
|
||||
selector.selectPage(PayoutDestination.recipients);
|
||||
context.go(payoutPath(PayoutDestination.recipients));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: 'payoutPayment',
|
||||
path: payoutPath(PayoutDestination.payment),
|
||||
pageBuilder: (context, state) {
|
||||
final selector = context.read<PageSelectorProvider>();
|
||||
return NoTransitionPage(
|
||||
child: PaymentPage(
|
||||
onBack: (_) {
|
||||
final destination = selector.goBackFromPayment();
|
||||
context.go(payoutPath(destination));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: 'payoutSettings',
|
||||
path: payoutPath(PayoutDestination.settings),
|
||||
pageBuilder: (context, state) => NoTransitionPage(
|
||||
child: const ProfileSettingsPage(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
name: 'payoutReports',
|
||||
path: payoutPath(PayoutDestination.reports),
|
||||
pageBuilder: (context, state) => NoTransitionPage(
|
||||
child: const OperationHistoryPage(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
name: 'payoutMethods',
|
||||
path: payoutPath(PayoutDestination.methods),
|
||||
pageBuilder: (context, state) {
|
||||
final selector = context.read<PageSelectorProvider>();
|
||||
return NoTransitionPage(
|
||||
child: PaymentConfigPage(
|
||||
onWalletTap: (wallet) {
|
||||
selector.selectWallet(wallet);
|
||||
context.go(payoutPath(PayoutDestination.editwallet));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: 'payoutEditWallet',
|
||||
path: payoutPath(PayoutDestination.editwallet),
|
||||
pageBuilder: (context, state) {
|
||||
final selector = context.read<PageSelectorProvider>();
|
||||
final wallet = selector.walletsProvider?.selectedWallet;
|
||||
if (wallet == null) {
|
||||
final loc = AppLocalizations.of(context)!;
|
||||
return NoTransitionPage(
|
||||
child: Center(child: Text(loc.noWalletSelected)),
|
||||
);
|
||||
}
|
||||
|
||||
return NoTransitionPage(
|
||||
child: WalletEditPage(
|
||||
onBack: () {
|
||||
selector.goBackFromWalletEdit();
|
||||
context.go(payoutPath(PayoutDestination.methods));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -1,17 +1,11 @@
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:pshared/provider/organizations.dart';
|
||||
|
||||
import 'package:pweb/app/router/pages.dart';
|
||||
import 'package:pweb/app/router/page_params.dart';
|
||||
import 'package:pweb/pages/2fa/page.dart';
|
||||
import 'package:pweb/pages/signup/page.dart';
|
||||
import 'package:pweb/pages/verification/page.dart';
|
||||
import 'package:pweb/widgets/sidebar/page.dart';
|
||||
import 'package:pweb/pages/login/page.dart';
|
||||
import 'package:pweb/pages/errors/not_found.dart';
|
||||
import 'package:pweb/pages/login/page.dart';
|
||||
import 'package:pweb/pages/signup/page.dart';
|
||||
import 'package:pweb/app/router/payout_shell.dart';
|
||||
|
||||
|
||||
GoRouter createRouter() => GoRouter(
|
||||
@@ -27,32 +21,29 @@ GoRouter createRouter() => GoRouter(
|
||||
path: routerPage(Pages.login),
|
||||
builder: (_, _) => const LoginPage(),
|
||||
),
|
||||
GoRoute(
|
||||
name: Pages.dashboard.name,
|
||||
path: routerPage(Pages.dashboard),
|
||||
builder: (_, _) => const PageSelector(),
|
||||
),
|
||||
GoRoute(
|
||||
name: Pages.sfactor.name,
|
||||
path: routerPage(Pages.sfactor),
|
||||
builder: (context, _) => TwoFactorCodePage(
|
||||
onVerificationSuccess: () {
|
||||
// trigger organization load
|
||||
context.read<OrganizationsProvider>().load();
|
||||
context.goNamed(Pages.dashboard.name);
|
||||
},
|
||||
),
|
||||
builder: (context, state) {
|
||||
final isFromSignup = state.uri.queryParameters['from'] == 'signup';
|
||||
|
||||
return TwoFactorCodePage(
|
||||
onVerificationSuccess: () {
|
||||
if (isFromSignup) {
|
||||
context.goNamed(Pages.login.name);
|
||||
} else {
|
||||
context.goNamed(Pages.dashboard.name);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: Pages.signup.name,
|
||||
path: routerPage(Pages.signup),
|
||||
builder: (_, _) => const SignUpPage(),
|
||||
),
|
||||
GoRoute(
|
||||
name: Pages.verify.name,
|
||||
path: '${routerPage(Pages.verify)}${routerAddParam(PageParams.token)}',
|
||||
builder: (_, state) => AccountVerificationPage(token: state.pathParameters[PageParams.token.name]!),
|
||||
),
|
||||
payoutShellRoute(),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -49,7 +49,8 @@ class _WalletFormState extends State<WalletForm> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newData != null && newData != oldData) {
|
||||
if (newData != null &&
|
||||
newData.walletId != _walletIdController.text) {
|
||||
_walletIdController.text = newData.walletId;
|
||||
}
|
||||
}
|
||||
@@ -67,4 +68,4 @@ class _WalletFormState extends State<WalletForm> {
|
||||
validator: (val) => (val?.isEmpty ?? true) ? l10n.enterWalletId : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:pweb/app/router/payout_routes.dart';
|
||||
import 'package:pweb/providers/page_selector.dart';
|
||||
import 'package:pweb/providers/wallets.dart';
|
||||
import 'package:pweb/widgets/sidebar/destinations.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
@@ -26,6 +30,7 @@ class SendPayoutButton extends StatelessWidget {
|
||||
|
||||
if (wallet != null) {
|
||||
pageSelectorProvider.startPaymentFromWallet(wallet);
|
||||
context.go(payoutPath(PayoutDestination.payment));
|
||||
}
|
||||
},
|
||||
child: Text(loc.payoutNavSendPayout),
|
||||
|
||||
@@ -45,6 +45,7 @@ class PageSelectorProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void selectPage(PayoutDestination dest) {
|
||||
if (_selected == dest) return;
|
||||
_selected = dest;
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -95,7 +96,7 @@ class PageSelectorProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void goBackFromPayment() {
|
||||
PayoutDestination goBackFromPayment() {
|
||||
_selected = _previousDestination ??
|
||||
(_cameFromRecipientList
|
||||
? PayoutDestination.recipients
|
||||
@@ -104,6 +105,7 @@ class PageSelectorProvider extends ChangeNotifier {
|
||||
_previousDestination = null;
|
||||
_cameFromRecipientList = false;
|
||||
notifyListeners();
|
||||
return _selected;
|
||||
}
|
||||
|
||||
void goBackFromWalletEdit() {
|
||||
@@ -186,4 +188,4 @@ class PageSelectorProvider extends ChangeNotifier {
|
||||
|
||||
Recipient? get selectedRecipient => recipientProvider?.selectedRecipient;
|
||||
Wallet? get selectedWallet => walletsProvider?.selectedWallet;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +1,46 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:pshared/models/resources.dart';
|
||||
|
||||
import 'package:pshared/provider/account.dart';
|
||||
import 'package:pshared/provider/permissions.dart';
|
||||
|
||||
import 'package:pweb/pages/address_book/form/page.dart';
|
||||
import 'package:pweb/pages/address_book/page/page.dart';
|
||||
import 'package:pweb/pages/payment_methods/page.dart';
|
||||
import 'package:pweb/pages/payout_page/page.dart';
|
||||
import 'package:pweb/pages/payout_page/wallet/edit/page.dart';
|
||||
import 'package:pweb/pages/report/page.dart';
|
||||
import 'package:pweb/pages/settings/profile/page.dart';
|
||||
import 'package:pweb/pages/dashboard/dashboard.dart';
|
||||
import 'package:pweb/providers/page_selector.dart';
|
||||
import 'package:pweb/app/router/pages.dart';
|
||||
import 'package:pweb/app/router/payout_routes.dart';
|
||||
import 'package:pweb/providers/account.dart';
|
||||
import 'package:pweb/providers/page_selector.dart';
|
||||
import 'package:pweb/providers/permissions.dart';
|
||||
import 'package:pweb/widgets/appbar/app_bar.dart';
|
||||
import 'package:pweb/widgets/sidebar/destinations.dart';
|
||||
import 'package:pweb/widgets/sidebar/sidebar.dart';
|
||||
|
||||
import 'package:pweb/generated/i18n/app_localizations.dart';
|
||||
|
||||
|
||||
class PageSelector extends StatelessWidget {
|
||||
const PageSelector({super.key});
|
||||
final PayoutDestination selected;
|
||||
final Widget child;
|
||||
|
||||
void _logout(BuildContext context) {
|
||||
const PageSelector({
|
||||
super.key,
|
||||
required this.selected,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
void _handleLogout(BuildContext context) {
|
||||
context.read<AccountProvider>().logout();
|
||||
context.read<PermissionsProvider>().clear();
|
||||
navigateAndReplace(context, Pages.login);
|
||||
}
|
||||
|
||||
void _goToDestination(BuildContext context, PayoutDestination destination) {
|
||||
context.go(payoutPath(destination));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final provider = context.watch<PageSelectorProvider>();
|
||||
final permissions = context.watch<PermissionsProvider>();
|
||||
final loc = AppLocalizations.of(context)!;
|
||||
final account = context.watch<AccountProvider>().account;
|
||||
|
||||
final bool restrictedAccess = !permissions.canRead(ResourceType.chainWallets);
|
||||
final allowedDestinations = restrictedAccess
|
||||
final allowedDestinations = permissions.isRecipient
|
||||
? <PayoutDestination>{
|
||||
PayoutDestination.settings,
|
||||
PayoutDestination.methods,
|
||||
@@ -46,78 +48,23 @@ class PageSelector extends StatelessWidget {
|
||||
}
|
||||
: PayoutDestination.values.toSet();
|
||||
|
||||
final selected = allowedDestinations.contains(provider.selected)
|
||||
? provider.selected
|
||||
: (restrictedAccess ? PayoutDestination.settings : PayoutDestination.dashboard);
|
||||
final safeSelected = allowedDestinations.contains(selected)
|
||||
? selected
|
||||
: (permissions.isRecipient ? PayoutDestination.settings : PayoutDestination.dashboard);
|
||||
|
||||
if (selected != provider.selected) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => provider.selectPage(selected));
|
||||
if (safeSelected != selected) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _goToDestination(context, safeSelected));
|
||||
}
|
||||
|
||||
Widget content;
|
||||
switch (selected) {
|
||||
case PayoutDestination.dashboard:
|
||||
content = DashboardPage(
|
||||
onRecipientSelected: (recipient) => provider.selectRecipient(recipient),
|
||||
onGoToPaymentWithoutRecipient: provider.startPaymentWithoutRecipient,
|
||||
);
|
||||
break;
|
||||
|
||||
case PayoutDestination.recipients:
|
||||
content = RecipientAddressBookPage(
|
||||
onRecipientSelected: (recipient) =>
|
||||
provider.selectRecipient(recipient, fromList: true),
|
||||
onAddRecipient: provider.goToAddRecipient,
|
||||
onEditRecipient: provider.editRecipient,
|
||||
);
|
||||
break;
|
||||
|
||||
case PayoutDestination.addrecipient:
|
||||
final recipient = provider.recipientProvider?.selectedRecipient;
|
||||
content = AdressBookRecipientForm(
|
||||
recipient: recipient,
|
||||
onSaved: (_) => provider.selectPage(PayoutDestination.recipients),
|
||||
);
|
||||
break;
|
||||
|
||||
case PayoutDestination.payment:
|
||||
content = PaymentPage(
|
||||
onBack: (_) => provider.goBackFromPayment(),
|
||||
);
|
||||
break;
|
||||
|
||||
case PayoutDestination.settings:
|
||||
content = ProfileSettingsPage();
|
||||
break;
|
||||
|
||||
case PayoutDestination.reports:
|
||||
content = OperationHistoryPage();
|
||||
break;
|
||||
|
||||
case PayoutDestination.methods:
|
||||
content = PaymentConfigPage(
|
||||
onWalletTap: provider.selectWallet,
|
||||
);
|
||||
break;
|
||||
|
||||
case PayoutDestination.editwallet:
|
||||
final wallet = provider.walletsProvider?.selectedWallet;
|
||||
content = wallet != null
|
||||
? WalletEditPage(
|
||||
onBack: provider.goBackFromWalletEdit,
|
||||
)
|
||||
: Center(child: Text(loc.noWalletSelected));
|
||||
break;
|
||||
|
||||
default:
|
||||
content = Text(selected.name);
|
||||
if (provider.selected != safeSelected) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => provider.selectPage(safeSelected));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: PayoutAppBar(
|
||||
title: Text(selected.localizedLabel(context)),
|
||||
title: Text(safeSelected.localizedLabel(context)),
|
||||
onAddFundsPressed: () {},
|
||||
onLogout: () => _logout(context),
|
||||
onLogout: () => _handleLogout(context),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(left: 200, top: 40, right: 200),
|
||||
@@ -126,11 +73,15 @@ class PageSelector extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
PayoutSidebar(
|
||||
selected: selected,
|
||||
onSelected: provider.selectPage,
|
||||
onLogout: () => _logout(context),
|
||||
selected: safeSelected,
|
||||
onSelected: (destination) => _goToDestination(context, destination),
|
||||
onLogout: () => _handleLogout(context),
|
||||
userName: account?.name,
|
||||
items: permissions.isRecipient
|
||||
? const [PayoutDestination.settings, PayoutDestination.methods]
|
||||
: null,
|
||||
),
|
||||
Expanded(child: content),
|
||||
Expanded(child: child),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user