import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:okane/screen.dart'; import 'package:okane/ui/pages/account/account.dart'; import 'package:okane/ui/pages/budgets/budget_details.dart'; import 'package:okane/ui/pages/budgets/budgets.dart'; 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 } typedef OkanePageBuilder = Widget Function(bool); class OkanePageItem { final OkanePage page; final IconData icon; final String label; final Widget child; final OkanePageBuilder? details; final bool showAccountName; const OkanePageItem( this.page, this.icon, this.label, this.child, this.details, this.showAccountName, ); bool _isEnabled(int? accountIndex) { if (showAccountName) { return accountIndex != null; } return true; } NavigationDestination toDestination(int? accountIndex) => NavigationDestination( icon: Icon(icon), label: label, enabled: _isEnabled(accountIndex), ); NavigationRailDestination toRailDestination(int? accountIndex) => NavigationRailDestination( icon: Icon(icon), label: Text(label), disabled: !_isEnabled(accountIndex), ); } final _pages = [ OkanePageItem( OkanePage.accounts, Icons.account_box, "Accounts", AccountListPage(isPage: false), null, false, ), OkanePageItem( OkanePage.transactions, Icons.monetization_on_rounded, "Transactions", TransactionListPage(), (_) => TransactionDetailsPage(), true, ), OkanePageItem( OkanePage.beneficiaries, Icons.person, "Beneficiaries", Container(), null, true, ), OkanePageItem( OkanePage.templates, Icons.list, "Templates", TemplateListPage(), null, true, ), OkanePageItem( OkanePage.budgets, Icons.pie_chart, "Budgets", BudgetListPage(), (_) => BudgetDetailsPage(), true, ), ]; class OkaneNavigationRail extends StatelessWidget { const OkaneNavigationRail({super.key}); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) => NavigationRail( onDestinationSelected: (i) => context.read().setPage(_pages[i].page), destinations: _pages .map((p) => p.toRailDestination(state.activeAccountIndex)) .toList(), selectedIndex: _pages.indexWhere((p) => p.page == state.activePage), ), ); } } class OkaneNavigationBar extends StatelessWidget { const OkaneNavigationBar({super.key}); @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) => NavigationBar( onDestinationSelected: (i) => context.read().setPage(_pages[i].page), destinations: _pages .map((p) => p.toDestination(state.activeAccountIndex)) .toList(), selectedIndex: _pages.indexWhere((p) => p.page == state.activePage), ), ); } } class OkaneNavigationDrawer extends StatelessWidget { const OkaneNavigationDrawer({super.key}); @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(), ), ), ); } } class OkaneNavigationLayout extends StatelessWidget { const OkaneNavigationLayout({super.key}); @override Widget build(BuildContext context) { final screenSize = getScreenSize(context); return BlocBuilder( builder: (_, state) => IndexedStack( index: _pages.indexWhere((p) => p.page == state.activePage), children: _pages .map( (p) => switch (screenSize) { ScreenSize.small => Column( children: [ SizedBox( height: 50, child: Padding( padding: EdgeInsets.all(8), child: Row( children: [ IconButton( icon: Icon(Icons.menu), onPressed: () { Scaffold.of(context).openDrawer(); }, ), if (p.showAccountName && state.activeAccountIndex != null) Padding( padding: EdgeInsets.only(left: 8), child: Text( state .accounts[state .activeAccountIndex!] .name!, style: Theme.of( context, ).textTheme.titleLarge, ), ), ], ), ), ), Expanded(child: p.child), ], ), ScreenSize.normal => Column( children: [ if (p.showAccountName && state.activeAccountIndex != null) 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(), ), ); } }