From b2175ddafd1c89c58ca403f90daf676c3e1501d4 Mon Sep 17 00:00:00 2001 From: gltron Date: Sun, 18 Feb 2024 12:59:45 +0100 Subject: [PATCH] Improved mobile layout --- lib/pages/budgets/budgets_page.dart | 4 +- .../budgets/widgets/budgets_actions.dart | 14 +- lib/pages/data/data_page.dart | 2 +- lib/pages/stats/stats_page.dart | 147 ++++++++++++------ lib/pages/stats/widgets/account_counters.dart | 2 +- .../widgets/categories_totals_chart.dart | 12 +- lib/pages/stats/widgets/global_counter.dart | 2 +- .../widgets/transactions_actions.dart | 55 +++++-- 8 files changed, 160 insertions(+), 78 deletions(-) diff --git a/lib/pages/budgets/budgets_page.dart b/lib/pages/budgets/budgets_page.dart index 3659a0a..210ec6c 100644 --- a/lib/pages/budgets/budgets_page.dart +++ b/lib/pages/budgets/budgets_page.dart @@ -8,10 +8,12 @@ class BudgetsPage extends StatelessWidget { @override Widget build(BuildContext context) { return Center( - child: ConstrainedBox( + child: Container( constraints: const BoxConstraints( maxWidth: 1000 ), + padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10), + margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10), child: const Column( children: [ BudgetsActions(), diff --git a/lib/pages/budgets/widgets/budgets_actions.dart b/lib/pages/budgets/widgets/budgets_actions.dart index 6b2b515..fece52b 100644 --- a/lib/pages/budgets/widgets/budgets_actions.dart +++ b/lib/pages/budgets/widgets/budgets_actions.dart @@ -9,24 +9,18 @@ class BudgetsActions extends StatelessWidget { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) => Container( - padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10), - margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10), - child: Row( + padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 0), + margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 0), + child: const Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text( + Text( 'Budgets', style: TextStyle( fontWeight: FontWeight.w900, fontSize: 35, ), ), - IconButton( - onPressed: () => null, - icon: const Icon( - Icons.add - ) - ), ], ) ) diff --git a/lib/pages/data/data_page.dart b/lib/pages/data/data_page.dart index 5bb857c..35db0ff 100644 --- a/lib/pages/data/data_page.dart +++ b/lib/pages/data/data_page.dart @@ -29,8 +29,8 @@ class DataPage extends StatelessWidget { child: ListView( children: const [ ImportSettings(), - CategoriesSettings(), AccountSettings(), + CategoriesSettings(), ] ) ), diff --git a/lib/pages/stats/stats_page.dart b/lib/pages/stats/stats_page.dart index 0f1c9db..0c806bc 100644 --- a/lib/pages/stats/stats_page.dart +++ b/lib/pages/stats/stats_page.dart @@ -14,8 +14,103 @@ import 'package:tunas/repositories/transactions/transactions_repository.dart'; class StatsPage extends StatelessWidget { const StatsPage({super.key}); + Widget _largeScreenHeader(ChartState state) { + return Center ( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), + constraints: const BoxConstraints( + maxWidth: 1000 + ), + child: Column( + children: [ + Row( + children: [ + Expanded( + flex: 2, + child: GlobalCounter(value: state.globalTotal) + ), + const SizedBox(width: 10), + Expanded( + flex: 1, + child: AccountCounter(accountsTotals: state.accountsTotals) + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const YearSelector(), + ProfitIndicator(profit: state.scoppedProfit) + ], + ), + ] + ) + ) + ); + } + + Widget _smallScreenHeader(ChartState state) { + return Center ( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), + constraints: const BoxConstraints( + maxWidth: 1000 + ), + child: Column( + children: [ + GlobalCounter(value: state.globalTotal), + AccountCounter(accountsTotals: state.accountsTotals), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ProfitIndicator(profit: state.scoppedProfit), + const YearSelector(), + ], + ), + ] + ) + ) + ); + } + + Widget _largeScreenTotalsCharts(ChartState state) { + return Center ( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 1500 + ), + child: SizedBox( + height: 450, + child: Row( + children: [ + CategoriesTotalsChart(categoriesTotals: state.scopedCategoriesPositiveTotals, categoriesTotalsPercents: state.scopedSimplifiedCategoriesPositiveTotalsPercents), + CategoriesTotalsChart(categoriesTotals: state.scopedCategoriesNegativeTotals, categoriesTotalsPercents: state.scopedSimplifiedCategoriesNegativeTotalsPercents), + ], + ) + ) + ) + ); + } + + Widget _smallScreenTotalsCharts(ChartState state) { + return Center ( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 1500 + ), + child: Column( + children: [ + CategoriesTotalsChart(categoriesTotals: state.scopedCategoriesPositiveTotals, categoriesTotalsPercents: state.scopedSimplifiedCategoriesPositiveTotalsPercents), + CategoriesTotalsChart(categoriesTotals: state.scopedCategoriesNegativeTotals, categoriesTotalsPercents: state.scopedSimplifiedCategoriesNegativeTotalsPercents), + ], + ) + ) + ); + } + @override Widget build(BuildContext context) { + bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800; return BlocProvider( create: (context) => ChartBloc( metadataRepository: RepositoryProvider.of(context), @@ -24,60 +119,16 @@ class StatsPage extends StatelessWidget { child: BlocBuilder( builder: (context, state) => ListView( children: [ - Center ( - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 1000 - ), - child: Column( - children: [ - Row( - children: [ - Expanded( - flex: 2, - child: GlobalCounter(value: state.globalTotal) - ), - Expanded( - flex: 1, - child: AccountCounter(accountsTotals: state.accountsTotals) - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const YearSelector(), - ProfitIndicator(profit: state.scoppedProfit) - ], - ), - ] - ) - ) - ), + smallVerticalScreen ? _smallScreenHeader(state) : _largeScreenHeader(state), SizedBox( - height: 200, + height: smallVerticalScreen ? 100 : 200, child: GlobalTotalChart(monthlyTotals: state.scopedMonthlyTotals) ), SizedBox( - height: 500, + height: smallVerticalScreen ? 200 : 500, child: MonthlyCategoriesTotalChart(categoriesMonthlyTotals: state.scopedCategoriesMonthlyTotals) ), - Center ( - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 1500 - ), - child: SizedBox( - height: 450, - child: OverflowBar( - children: [ - CategoriesTotalsChart(categoriesTotals: state.scopedCategoriesPositiveTotals, categoriesTotalsPercents: state.scopedSimplifiedCategoriesPositiveTotalsPercents), - CategoriesTotalsChart(categoriesTotals: state.scopedCategoriesNegativeTotals, categoriesTotalsPercents: state.scopedSimplifiedCategoriesNegativeTotalsPercents), - ], - ) - ) - ) - ), + smallVerticalScreen ? _smallScreenTotalsCharts(state) : _largeScreenTotalsCharts(state), ], ) ), diff --git a/lib/pages/stats/widgets/account_counters.dart b/lib/pages/stats/widgets/account_counters.dart index 3adb786..b734363 100644 --- a/lib/pages/stats/widgets/account_counters.dart +++ b/lib/pages/stats/widgets/account_counters.dart @@ -31,7 +31,7 @@ class AccountCounter extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(10), - margin: const EdgeInsets.all(20), + margin: const EdgeInsets.only(bottom: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: Theme.of(context).colorScheme.primaryContainer, diff --git a/lib/pages/stats/widgets/categories_totals_chart.dart b/lib/pages/stats/widgets/categories_totals_chart.dart index 700b2b4..cbf4dbd 100644 --- a/lib/pages/stats/widgets/categories_totals_chart.dart +++ b/lib/pages/stats/widgets/categories_totals_chart.dart @@ -11,7 +11,7 @@ class CategoriesTotalsChart extends StatelessWidget { const CategoriesTotalsChart({super.key, required this.categoriesTotals, required this.categoriesTotalsPercents}); - List _convertDataForChart(Map categoriesColors) { + List _convertDataForChart(Map categoriesColors, bool smallVerticalScreen) { return categoriesTotalsPercents .map((item) => PieChartSectionData( @@ -21,9 +21,10 @@ class CategoriesTotalsChart extends StatelessWidget { fontSize: 15, fontWeight: FontWeight.w300 ), + showTitle: !smallVerticalScreen, titlePositionPercentageOffset: 0.5, borderSide: const BorderSide(width: 0), - radius: 40, + radius: smallVerticalScreen ? 30 : 40, color: categoriesColors[item.label] )) .toList(); @@ -60,10 +61,11 @@ class CategoriesTotalsChart extends StatelessWidget { @override Widget build(BuildContext context) { + bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800; return BlocBuilder( builder: (context, state) => Container( height: 320, - width: 500, + width: smallVerticalScreen ? null : 500, padding: const EdgeInsets.all(10), margin: const EdgeInsets.all(20), decoration: BoxDecoration( @@ -84,11 +86,11 @@ class CategoriesTotalsChart extends StatelessWidget { Expanded( child: PieChart( PieChartData( - sections: _convertDataForChart(state.categoriesColors), + sections: _convertDataForChart(state.categoriesColors, smallVerticalScreen), borderData: FlBorderData( show: false ), - centerSpaceRadius: 50, + centerSpaceRadius: smallVerticalScreen ? 30 :50, sectionsSpace: 4 ) ), diff --git a/lib/pages/stats/widgets/global_counter.dart b/lib/pages/stats/widgets/global_counter.dart index 28cdc46..357548c 100644 --- a/lib/pages/stats/widgets/global_counter.dart +++ b/lib/pages/stats/widgets/global_counter.dart @@ -10,7 +10,7 @@ class GlobalCounter extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(10), - margin: const EdgeInsets.all(20), + margin: const EdgeInsets.only(bottom: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), color: Theme.of(context).colorScheme.primaryContainer, diff --git a/lib/pages/transactions/widgets/transactions_actions.dart b/lib/pages/transactions/widgets/transactions_actions.dart index 3e40c54..ac07abc 100644 --- a/lib/pages/transactions/widgets/transactions_actions.dart +++ b/lib/pages/transactions/widgets/transactions_actions.dart @@ -7,31 +7,64 @@ import 'package:tunas/pages/transactions/widgets/transaction_add_dialog.dart'; class TransactionsActions extends StatelessWidget { const TransactionsActions({super.key}); - @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) => Container( - padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10), - margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10), - child: Row( + Widget _smallScreenLayout(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text( + const Text ( 'Transactions', style: TextStyle( fontWeight: FontWeight.w900, fontSize: 35, ), ), - CategoryFilter(), - IconButton( + FilledButton.icon( onPressed: () => TransactionAddDialog.show(context, null), + label: const Text('Add transaction'), icon: const Icon( Icons.add ) ), ], - ) + ), + const CategoryFilter(), + ], + ); + } + + Widget _largeScreenLayout(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Transactions', + style: TextStyle( + fontWeight: FontWeight.w900, + fontSize: 35, + ), + ), + const CategoryFilter(), + IconButton( + onPressed: () => TransactionAddDialog.show(context, null), + icon: const Icon( + Icons.add + ) + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800; + return BlocBuilder( + builder: (context, state) => Container( + padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10), + margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10), + child: smallVerticalScreen ? _smallScreenLayout(context) : _largeScreenLayout(context), ) ); }