Skip to content

Commit

Permalink
feat: add pfi management (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
ethan-tbd authored May 21, 2024
1 parent 6ba12c1 commit 615949a
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 93 deletions.
157 changes: 103 additions & 54 deletions lib/features/account/account_page.dart
Original file line number Diff line number Diff line change
@@ -1,71 +1,120 @@
import 'package:didpay/features/account/account_did_page.dart';
import 'package:didpay/features/account/account_vc_page.dart';
import 'package:didpay/features/pfis/pfis_page.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:didpay/shared/theme/grid.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

// TODO(ethan-tbd): redesign AccountPage, https://github.com/TBD54566975/didpay/issues/130
class AccountPage extends StatelessWidget {
class AccountPage extends HookWidget {
const AccountPage({super.key});

@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: _buildAccountNavigation(context),
),
);
}
Widget build(BuildContext context) => Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: Grid.side,
vertical: Grid.xs,
),
child: Text(
Loc.of(context).account,
style: Theme.of(context).textTheme.bodyLarge,
),
),
Expanded(
child: ListView(
children: [
_buildMyPfisTile(context),
_buildMyDidTile(context),
_buildMyVcTile(context),
],
),
),
],
),
),
);

Widget _buildAccountNavigation(BuildContext context) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: Grid.side,
vertical: Grid.xs,
),
child: Text(
Loc.of(context).account,
style: Theme.of(context).textTheme.bodyLarge,
Widget _buildMyPfisTile(BuildContext context) => ListTile(
title: Text(
Loc.of(context).myPfis,
style: Theme.of(context).textTheme.bodyLarge,
),
trailing: const Icon(Icons.chevron_right),
leading: Container(
width: Grid.md,
height: Grid.md,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(Grid.xxs),
),
child: const Center(
child: Icon(Icons.currency_exchange),
),
),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const PfisPage(),
),
);
},
);

Widget _buildMyDidTile(BuildContext context) => ListTile(
title: Text(
Loc.of(context).myDid,
style: Theme.of(context).textTheme.bodyLarge,
),
trailing: const Icon(Icons.chevron_right),
leading: Container(
width: Grid.md,
height: Grid.md,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(Grid.xxs),
),
Expanded(
child: ListView(
children: [
ListTile(
title: Text(
Loc.of(context).myDid,
style: Theme.of(context).textTheme.bodyLarge,
),
trailing: const Icon(Icons.chevron_right),
leading: const Icon(Icons.text_snippet, size: Grid.md),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const AccountDidPage(),
),
);
},
),
ListTile(
title: Text(
Loc.of(context).myVc,
style: Theme.of(context).textTheme.bodyLarge,
),
trailing: const Icon(Icons.chevron_right),
leading: const Icon(Icons.person, size: Grid.md),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const AccountVCPage(),
),
);
},
),
],
child: const Center(
child: Icon(Icons.text_snippet),
),
),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const AccountDidPage(),
),
);
},
);

Widget _buildMyVcTile(BuildContext context) => ListTile(
title: Text(
Loc.of(context).myVc,
style: Theme.of(context).textTheme.bodyLarge,
),
trailing: const Icon(Icons.chevron_right),
leading: Container(
width: Grid.md,
height: Grid.md,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(Grid.xxs),
),
],
child: const Center(
child: Icon(Icons.person),
),
),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const AccountVCPage(),
),
);
},
);
}
4 changes: 2 additions & 2 deletions lib/features/app/app.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:didpay/features/app/app_tabs.dart';
import 'package:didpay/features/pfis/add_pfi_page.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:didpay/shared/theme/theme.dart';
import 'package:flutter/material.dart';
Expand All @@ -12,7 +12,7 @@ class App extends StatelessWidget {
title: 'DIDPay',
theme: lightTheme(context),
darkTheme: darkTheme(context),
home: const AppTabs(),
home: AddPfiPage(),
localizationsDelegates: Loc.localizationsDelegates,
supportedLocales: const [
Locale('en', ''),
Expand Down
40 changes: 5 additions & 35 deletions lib/features/app/app_tabs.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import 'package:didpay/features/account/account_page.dart';
import 'package:didpay/features/home/home_page.dart';
import 'package:didpay/features/pfis/pfi.dart';
import 'package:didpay/features/pfis/pfis_notifier.dart';
import 'package:didpay/features/send/send_page.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class _TabItem {
final String label;
Expand All @@ -16,18 +12,17 @@ class _TabItem {
_TabItem(this.label, this.icon, this.screen);
}

class AppTabs extends HookConsumerWidget {
class AppTabs extends HookWidget {
const AppTabs({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
Widget build(BuildContext context) {
final selectedIndex = useState(0);
final pfis = ref.read(pfisProvider);

final tabs = [
_TabItem(
'Home',
const Icon(Icons.home_outlined),
const Icon(Icons.home),
const HomePage(),
),
_TabItem(
Expand All @@ -37,7 +32,7 @@ class AppTabs extends HookConsumerWidget {
),
_TabItem(
'Account',
const Icon(Icons.person_outlined),
const Icon(Icons.person),
const AccountPage(),
),
];
Expand All @@ -51,7 +46,7 @@ class AppTabs extends HookConsumerWidget {
fixedColor: Theme.of(context).colorScheme.primary,
selectedFontSize: 12,
currentIndex: selectedIndex.value,
onTap: (index) => _onTabTapped(context, index, selectedIndex, pfis),
onTap: (index) => selectedIndex.value = index,
items: tabs
.map(
(tab) => BottomNavigationBarItem(
Expand All @@ -63,29 +58,4 @@ class AppTabs extends HookConsumerWidget {
),
);
}

void _onTabTapped(
BuildContext context,
int index,
ValueNotifier<int> selectedIndex,
List<Pfi> pfis,
) {
if (index == 1 && pfis.isEmpty) {
ScaffoldMessenger.of(context).removeCurrentSnackBar();

ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
Loc.of(context).mustAddPfiBeforeSending,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSecondary,
),
),
backgroundColor: Theme.of(context).colorScheme.secondary,
),
);
return;
}
selectedIndex.value = index;
}
}
3 changes: 2 additions & 1 deletion lib/features/payout/payout_details_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class PayoutDetailsPage extends HookConsumerWidget {
data: (rfq) =>
AsyncLoadingWidget(text: Loc.of(context).gettingYourQuote),
loading: () => AsyncLoadingWidget(
text: Loc.of(context).sendingYourRequest,),
text: Loc.of(context).sendingYourRequest,
),
error: (error, _) => AsyncErrorWidget(
text: error.toString(),
onRetry: () =>
Expand Down
69 changes: 69 additions & 0 deletions lib/features/pfis/pfi_modal.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import 'package:didpay/features/pfis/pfi.dart';
import 'package:didpay/features/pfis/pfis_notifier.dart';
import 'package:didpay/l10n/app_localizations.dart';
import 'package:didpay/shared/theme/grid.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class PfiModal {
static Future<dynamic> show(
BuildContext context,
WidgetRef ref,
Pfi pfi,
) =>
showModalBottomSheet(
useSafeArea: true,
isScrollControlled: true,
context: context,
builder: (context) => SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: Grid.sm),
child: Text(
pfi.did,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
Divider(
color: Theme.of(context).colorScheme.outlineVariant,
thickness: 0.25,
),
ListTile(
title: Center(
child: Text(
Loc.of(context).removePfi,
style:
TextStyle(color: Theme.of(context).colorScheme.error),
),
),
onTap: () async {
await ref.read(pfisProvider.notifier).remove(pfi);
// ignore: use_build_context_synchronously
Navigator.pop(context);
},
),
Divider(
color: Theme.of(context).colorScheme.outlineVariant,
thickness: 0.25,
),
ListTile(
title: Center(
child: Text(
Loc.of(context).cancel,
style: Theme.of(context).textTheme.bodyLarge,
),
),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
);
}
Loading

0 comments on commit 615949a

Please sign in to comment.