From cf5dcfbc0f24800a90782bcd957792d2a3c9e19c Mon Sep 17 00:00:00 2001 From: "Alexander \"PapaTutuWawa" Date: Sun, 4 May 2025 19:47:11 +0200 Subject: [PATCH] Indicate the active account --- lib/ui/navigation.dart | 83 ++++++++++++++++++------ lib/ui/pages/budgets/budget_details.dart | 1 - lib/ui/widgets/account_indicator.dart | 23 +++++++ test/widget_test.dart | 30 +++++++++ 4 files changed, 115 insertions(+), 22 deletions(-) create mode 100644 lib/ui/widgets/account_indicator.dart create mode 100644 test/widget_test.dart diff --git a/lib/ui/navigation.dart b/lib/ui/navigation.dart index 3e332c3..16c6b8b 100644 --- a/lib/ui/navigation.dart +++ b/lib/ui/navigation.dart @@ -8,6 +8,7 @@ import 'package:okane/ui/pages/template_list.dart'; import 'package:okane/ui/pages/transaction_details.dart'; import 'package:okane/ui/pages/transaction_list.dart'; import 'package:okane/ui/state/core.dart'; +import 'package:okane/ui/widgets/account_indicator.dart'; enum OkanePage { accounts, transactions, beneficiaries, templates, budgets } @@ -19,6 +20,7 @@ class OkanePageItem { final String label; final Widget child; final OkanePageBuilder? details; + final bool showAccountName; const OkanePageItem( this.page, @@ -26,6 +28,7 @@ class OkanePageItem { this.label, this.child, this.details, + this.showAccountName, ); NavigationDestination toDestination() => @@ -42,6 +45,7 @@ final _pages = [ "Accounts", AccountListPage(isPage: false), null, + false, ), OkanePageItem( OkanePage.transactions, @@ -49,6 +53,7 @@ final _pages = [ "Transactions", TransactionListPage(), (_) => TransactionDetailsPage(), + true, ), OkanePageItem( OkanePage.beneficiaries, @@ -56,6 +61,7 @@ final _pages = [ "Beneficiaries", Container(), null, + true, ), OkanePageItem( OkanePage.templates, @@ -63,6 +69,7 @@ final _pages = [ "Templates", TemplateListPage(), null, + true, ), OkanePageItem( OkanePage.budgets, @@ -70,6 +77,7 @@ final _pages = [ "Budgets", BudgetListPage(), (_) => BudgetDetailsPage(), + true, ), ]; @@ -113,19 +121,25 @@ class OkaneNavigationDrawer extends StatelessWidget { @override Widget build(BuildContext context) { return BlocBuilder( - builder: (context, state) => Drawer( - child: ListView( - children: _pages.map((p) => ListTile( - title: Text(p.label), - leading: Icon(p.icon), - selected: p.page == state.activePage, - onTap: () { - context.read().setPage(p.page); - Navigator.of(context).pop(); - }, - )).toList(), + builder: + (context, state) => Drawer( + child: ListView( + children: + _pages + .map( + (p) => ListTile( + title: Text(p.label), + leading: Icon(p.icon), + selected: p.page == state.activePage, + onTap: () { + context.read().setPage(p.page); + Navigator.of(context).pop(); + }, + ), + ) + .toList(), + ), ), - ), ); } } @@ -158,6 +172,20 @@ class OkaneNavigationLayout extends StatelessWidget { Scaffold.of(context).openDrawer(); }, ), + + if (p.showAccountName) + Padding( + padding: EdgeInsets.only(left: 8), + child: Text( + state + .accounts[state.activeAccountIndex!] + .name!, + style: + Theme.of( + context, + ).textTheme.titleLarge, + ), + ), ], ), ), @@ -165,15 +193,28 @@ class OkaneNavigationLayout extends StatelessWidget { Expanded(child: p.child), ], ), - ScreenSize.normal => - p.details != null - ? Row( - children: [ - Expanded(child: p.child), - Expanded(child: p.details!(false)), - ], - ) - : p.child, + ScreenSize.normal => Column( + children: [ + if (p.showAccountName) + AccountIndicator( + accountName: + state + .accounts[state.activeAccountIndex!] + .name!, + ), + Expanded( + child: + p.details != null + ? Row( + children: [ + Expanded(child: p.child), + Expanded(child: p.details!(false)), + ], + ) + : p.child, + ), + ], + ), }, ) .toList(), diff --git a/lib/ui/pages/budgets/budget_details.dart b/lib/ui/pages/budgets/budget_details.dart index 755e885..ac4d8b5 100644 --- a/lib/ui/pages/budgets/budget_details.dart +++ b/lib/ui/pages/budgets/budget_details.dart @@ -1,6 +1,5 @@ import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get_it/get_it.dart'; import 'package:okane/database/collections/budget.dart'; diff --git a/lib/ui/widgets/account_indicator.dart b/lib/ui/widgets/account_indicator.dart new file mode 100644 index 0000000..4971288 --- /dev/null +++ b/lib/ui/widgets/account_indicator.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +class AccountIndicator extends StatelessWidget { + final String accountName; + + const AccountIndicator({super.key, required this.accountName}); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 50, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + accountName, + style: Theme.of(context).textTheme.titleLarge, + ), + ], + ) + ); + } +} \ No newline at end of file diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..9ace553 --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:okane/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}