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,7 +202,11 @@ 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) {
accounts.add(accountToSave); if (accounts.isEmpty) {
accounts = [accountToSave];
} else {
accounts.add(accountToSave);
}
} }
await _metadataRepository.saveAccounts(accounts); await _metadataRepository.saveAccounts(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( ImportSettings(),
child: ListView( AccountSettings(),
children: const [ CategoriesSettings(),
ImportSettings(),
AccountSettings(),
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,8 +9,121 @@ class TransactionLine extends StatelessWidget {
const TransactionLine({super.key, required this.transaction, required this.subTotal}); const TransactionLine({super.key, required this.transaction, required this.subTotal});
List<Widget> _largeScreenLayout(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)
),
],
),
),
SizedBox(
width: 100,
child: Text(transaction.account),
),
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
)
),
],
),
)
];
}
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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800;
return InkWell( return InkWell(
onTap: () => TransactionAddDialog.show(context, transaction), onTap: () => TransactionAddDialog.show(context, transaction),
child: MergeSemantics( child: MergeSemantics(
@@ -19,48 +132,7 @@ class TransactionLine extends StatelessWidget {
margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10), margin: const EdgeInsets.symmetric(vertical: 2, horizontal: 10),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: smallVerticalScreen ? _smallScreenLayout(context) : _largeScreenLayout(context),
SizedBox(
width: 100,
child: Text(DateFormat('dd-MM-yyyy', 'fr_FR').format(transaction.date))
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
transaction.category,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18)
),
Text(transaction.description),
],
),
),
SizedBox(
width: 100,
child: Text(transaction.account),
),
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(
color: subTotal > 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.error
)
),
],
),
)
],
) )
) )
) )

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