Fixed mobile layout

This commit is contained in:
2024-02-18 14:42:50 +01:00
parent b2175ddafd
commit 2006ebf5cb
10 changed files with 220 additions and 94 deletions

25
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,25 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "tunas",
"request": "launch",
"type": "dart"
},
{
"name": "tunas (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "tunas (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}

View File

@@ -202,8 +202,12 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
accountFound.color = accountToSave.color; accountFound.color = accountToSave.color;
accountFound.saving = accountToSave.saving; accountFound.saving = accountToSave.saving;
} catch (e) { } catch (e) {
if (accounts.isEmpty) {
accounts = [accountToSave];
} else {
accounts.add(accountToSave); accounts.add(accountToSave);
} }
}
await _metadataRepository.saveAccounts(accounts); await _metadataRepository.saveAccounts(accounts);
return accounts; return accounts;

View File

@@ -7,19 +7,19 @@ class BudgetsPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MediaQueryData mediaQuery = MediaQuery.of(context);
return Center( return Center(
child: Container( child: Container(
constraints: const BoxConstraints( constraints: const BoxConstraints(
maxWidth: 1000 maxWidth: 1000
), ),
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10), child: ListView(
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10), padding: mediaQuery.padding.copyWith(left: 10.0, right: 10.0, bottom: 100.0),
child: const Column( children: const [
children: [
BudgetsActions(), BudgetsActions(),
MonthDistribution() MonthDistribution()
], ]
) ),
) )
); );
} }

View File

@@ -8,34 +8,27 @@ class DataPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MediaQueryData mediaQuery = MediaQuery.of(context);
return Center( return Center(
child: Container( child: Container(
constraints: const BoxConstraints( constraints: const BoxConstraints(
maxWidth: 1000 maxWidth: 1000
), ),
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10), child: ListView(
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10), padding: mediaQuery.padding.copyWith(left: 10.0, right: 10.0, bottom: 100.0),
child: Column( children: const [
crossAxisAlignment: CrossAxisAlignment.start, Text(
children: [
const Text(
'Settings', 'Settings',
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
fontSize: 35, fontSize: 35,
), ),
), ),
Expanded(
child: ListView(
children: const [
ImportSettings(), ImportSettings(),
AccountSettings(), AccountSettings(),
CategoriesSettings(), CategoriesSettings(),
] ]
)
), ),
]
)
) )
); );
} }

View File

@@ -110,6 +110,7 @@ class StatsPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MediaQueryData mediaQuery = MediaQuery.of(context);
bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800; bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800;
return BlocProvider( return BlocProvider(
create: (context) => ChartBloc( create: (context) => ChartBloc(
@@ -118,6 +119,7 @@ class StatsPage extends StatelessWidget {
), ),
child: BlocBuilder<ChartBloc, ChartState>( child: BlocBuilder<ChartBloc, ChartState>(
builder: (context, state) => ListView( builder: (context, state) => ListView(
padding: mediaQuery.padding.copyWith(bottom: 100.0),
children: [ children: [
smallVerticalScreen ? _smallScreenHeader(state) : _largeScreenHeader(state), smallVerticalScreen ? _smallScreenHeader(state) : _largeScreenHeader(state),
SizedBox( SizedBox(

View File

@@ -26,7 +26,7 @@ class MonthlyCategoriesTotalChart extends StatelessWidget {
); );
} }
List<BarChartGroupData> _computeBarGroups(double barsSpace, double barsWidth, Map<String, Color> categoriesColors) { List<BarChartGroupData> _computeBarGroups(double barsSpace, double barsWidth, Map<String, Color> categoriesColors, bool smallVerticalScreen) {
var a = categoriesMonthlyTotals.entries var a = categoriesMonthlyTotals.entries
.map((entry) { .map((entry) {
return BarChartGroupData( return BarChartGroupData(
@@ -36,7 +36,7 @@ class MonthlyCategoriesTotalChart extends StatelessWidget {
_computeStack(barsWidth, entry.value.positives, categoriesColors), _computeStack(barsWidth, entry.value.positives, categoriesColors),
_computeStack(barsWidth, entry.value.negatives, categoriesColors), _computeStack(barsWidth, entry.value.negatives, categoriesColors),
], ],
showingTooltipIndicators: [0, 1] showingTooltipIndicators: smallVerticalScreen ? [] : [0, 1]
); );
}) })
.toList(); .toList();
@@ -66,6 +66,7 @@ class MonthlyCategoriesTotalChart extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800;
return BlocBuilder<CategoryBloc, CategoryState>( return BlocBuilder<CategoryBloc, CategoryState>(
builder: (context, state) => AspectRatio( builder: (context, state) => AspectRatio(
aspectRatio: 1.66, aspectRatio: 1.66,
@@ -77,7 +78,7 @@ class MonthlyCategoriesTotalChart extends StatelessWidget {
return BarChart( return BarChart(
BarChartData( BarChartData(
maxY: _computeMaxValue(), maxY: _computeMaxValue(),
barGroups: _computeBarGroups(barsSpace, barsWidth, state.categoriesColors), barGroups: _computeBarGroups(barsSpace, barsWidth, state.categoriesColors, smallVerticalScreen),
titlesData: FlTitlesData( titlesData: FlTitlesData(
topTitles: const AxisTitles( topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false) sideTitles: SideTitles(showTitles: false)

View File

@@ -8,11 +8,13 @@ class TransactionsPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MediaQueryData mediaQuery = MediaQuery.of(context);
return Center( return Center(
child: ConstrainedBox( child: Container(
constraints: const BoxConstraints( constraints: const BoxConstraints(
maxWidth: 1000 maxWidth: 1000
), ),
padding: mediaQuery.padding,
child: const Column( child: const Column(
children: [ children: [
TransactionsActions(), TransactionsActions(),

View File

@@ -9,20 +9,17 @@ class TransactionLine extends StatelessWidget {
const TransactionLine({super.key, required this.transaction, required this.subTotal}); const TransactionLine({super.key, required this.transaction, required this.subTotal});
@override List<Widget> _largeScreenLayout(BuildContext context) {
Widget build(BuildContext context) { return [
return InkWell(
onTap: () => TransactionAddDialog.show(context, transaction),
child: MergeSemantics(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10),
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox( SizedBox(
width: 100, width: 100,
child: Text(DateFormat('dd-MM-yyyy', 'fr_FR').format(transaction.date)) child: Text(
DateFormat('dd/MM/yyyy', 'fr_FR').format(transaction.date),
style: const TextStyle(
fontWeight: FontWeight.w300,
fontSize: 15
)
)
), ),
Expanded( Expanded(
child: Column( child: Column(
@@ -32,7 +29,10 @@ class TransactionLine extends StatelessWidget {
transaction.category, transaction.category,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18) style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18)
), ),
Text(transaction.description), Text(
transaction.description,
style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 15)
),
], ],
), ),
), ),
@@ -54,13 +54,85 @@ class TransactionLine extends StatelessWidget {
Text( Text(
NumberFormat('#######.00 €', 'fr_FR').format(subTotal), NumberFormat('#######.00 €', 'fr_FR').format(subTotal),
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 15,
color: subTotal > 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.error color: subTotal > 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.error
) )
), ),
], ],
), ),
) )
];
}
List<Widget> _smallScreenLayout(BuildContext context) {
return [
SizedBox(
width: 100,
child: Text(
DateFormat('dd/MM/yyyy', 'fr_FR').format(transaction.date),
style: const TextStyle(
fontWeight: FontWeight.w300,
fontSize: 15
)
)
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
transaction.category,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18)
),
Text(
transaction.description,
style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 15)
),
Text(
transaction.account,
style: const TextStyle(fontWeight: FontWeight.w300, fontSize: 15)
),
], ],
),
),
SizedBox(
width: 120,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
NumberFormat(transaction.value > 0 ? '+#######.00 €' : '#######.00 €', 'fr_FR').format(transaction.value),
style: TextStyle(
color: transaction.value > 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.error
)
),
Text(
NumberFormat('#######.00 €', 'fr_FR').format(subTotal),
style: TextStyle(
fontWeight: FontWeight.w300,
fontSize: 15,
color: subTotal > 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.error
)
),
],
),
)
];
}
@override
Widget build(BuildContext context) {
bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800;
return InkWell(
onTap: () => TransactionAddDialog.show(context, transaction),
child: MergeSemantics(
child: Container(
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10),
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: smallVerticalScreen ? _smallScreenLayout(context) : _largeScreenLayout(context),
) )
) )
) )

View File

@@ -23,7 +23,7 @@ class TransactionsActions extends StatelessWidget {
), ),
FilledButton.icon( FilledButton.icon(
onPressed: () => TransactionAddDialog.show(context, null), onPressed: () => TransactionAddDialog.show(context, null),
label: const Text('Add transaction'), label: const Text('Add'),
icon: const Icon( icon: const Icon(
Icons.add Icons.add
) )

View File

@@ -3,17 +3,8 @@ import 'package:flutter/material.dart';
class TransactionsHeader extends StatelessWidget { class TransactionsHeader extends StatelessWidget {
const TransactionsHeader({super.key}); const TransactionsHeader({super.key});
@override List<Widget> _largeScreenLayout() {
Widget build(BuildContext context) { return const [
return Container(
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10),
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10),
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.black))
),
child: const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox( SizedBox(
width: 100, width: 100,
child: Text('Date') child: Text('Date')
@@ -35,8 +26,44 @@ class TransactionsHeader extends StatelessWidget {
], ],
), ),
) )
];
}
List<Widget> _smallScreenLayout() {
return const [
SizedBox(
width: 100,
child: Text('Date')
),
Expanded(
child: Text('Description')
),
SizedBox(
width: 120,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text('Amount'),
Text('SubTotal'),
], ],
), ),
)
];
}
@override
Widget build(BuildContext context) {
bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800;
return Container(
padding: const EdgeInsets.symmetric(vertical: 9, horizontal: 10),
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10),
decoration: const BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.black))
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: smallVerticalScreen ? _smallScreenLayout() : _largeScreenLayout(),
),
); );
} }
} }