Skip to content
Snippets Groups Projects
Commit 38d82779 authored by Florian Schindler's avatar Florian Schindler
Browse files

tried adding functionality to top of home_view

TRIED bcs it not working, fixi dixi tomorrow, wenn ich nicht vergessen hab wie das alles funktioniert und was ich mir dabei gedacht hab
parent 2f140522
No related branches found
No related tags found
No related merge requests found
......@@ -29,7 +29,9 @@ class _TransactionListtileState extends State<TransactionListtile> {
key: UniqueKey(),
direction: DismissDirection.startToEnd,
onDismissed: (_) => {
locator.get<TransactionsController>().deleteTransaction(widget.transaction),
setState(() {
locator.get<TransactionsController>().deleteTransaction(widget.transaction);
}),
ScaffoldMessenger.of(context).removeCurrentSnackBar(),
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
......
......@@ -3,7 +3,9 @@ import 'package:fl_chart/fl_chart.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:trackeroo/frontend/utils/transaction_listtile.dart';
import 'package:trackeroo/frontend/views/onboarding_view.dart';
import 'package:trackeroo/logic/models/category.dart';
import 'package:trackeroo/logic/models/transaction.dart';
import 'package:trackeroo/logic/services/categories_controller.dart';
import 'package:trackeroo/logic/services/locator.dart';
import 'package:trackeroo/logic/services/transactions_controller.dart';
......@@ -28,176 +30,213 @@ class _HomeViewState extends State<HomeView> {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Balance',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5.0),
const Text(
'4932.32 €',
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.w300
),
),
const SizedBox(height: 10.0),
const Text(
'Overview',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: ValueListenableBuilder(
valueListenable: transContr.transactionsBox.listenable(),
builder: (context, Box<Transaction> box, widget) {
transContr.transactionsList = box.values.toList();
transContr.transactionsList.sort((b, a) => a.createdAt.compareTo(b.createdAt));
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Balance',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5.0),
Text(
transContr.balance.toStringAsFixed(2),
style: const TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.w300
),
),
const SizedBox(height: 10.0),
const Text(
'Overview',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.arrow_downward, color: Colors.green, size: 16.0),
Text('Income'),
const Row(
children: [
Icon(Icons.arrow_downward, color: Colors.green, size: 16.0),
Text('Income'),
],
),
Text('${transContr.income.toStringAsFixed(2)} €')
],
),
Text('1234.56€')
],
),
Center(
child: SizedBox(
height: 200.0,
width: 50.0,
child: PieChart(
PieChartData(
centerSpaceRadius: 50.0,
sections: [
buildPieChartSection(context, 93.302),
buildPieChartSection(context, 43.302),
buildPieChartSection(context, 104.302),
buildPieChartSection(context, 120.302),
buildPieChartSection(context, 110.302)
]
)
Center(
child: SizedBox(
height: 200.0,
width: 50.0,
child: PieChart(
PieChartData(
centerSpaceRadius: 0,
sections: transContr.transactionsList.isNotEmpty ? buildPieChartSectionList(context) : null,
),
swapAnimationDuration: const Duration(milliseconds: 500),
swapAnimationCurve: Curves.easeInOut,
),
),
),
),
),
const Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.arrow_upward, color: Colors.red, size: 16.0),
Text('Expenses'),
const Row(
children: [
Icon(Icons.arrow_upward, color: Colors.red, size: 16.0),
Text('Expenses'),
],
),
Text('${transContr.expenses.toStringAsFixed(2)} €')
],
),
Text('1234.56€')
],
),
],
),
const SizedBox(height: 10.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.daily;
}),
label: const Text('Daily'),
selected: timespanView == Timespan.daily,
showCheckmark: false
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.weekly;
}),
label: const Text('Weekly'),
selected: timespanView == Timespan.weekly,
showCheckmark: false
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.monthly;
}),
label: const Text('Montly'),
selected: timespanView == Timespan.monthly,
showCheckmark: false
const SizedBox(height: 10.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.daily;
}),
label: const Text('Daily'),
selected: timespanView == Timespan.daily,
showCheckmark: false
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.weekly;
}),
label: const Text('Weekly'),
selected: timespanView == Timespan.weekly,
showCheckmark: false
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.monthly;
}),
label: const Text('Montly'),
selected: timespanView == Timespan.monthly,
showCheckmark: false
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.yearly;
}),
label: const Text('Yearly'),
selected: timespanView == Timespan.yearly,
showCheckmark: false
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.all;
}),
label: const Text('All'),
selected: timespanView == Timespan.all,
showCheckmark: false
)
],
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.yearly;
}),
label: const Text('Yearly'),
selected: timespanView == Timespan.yearly,
showCheckmark: false
const SizedBox(height: 20.0),
const Text(
'Transactions',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold
),
),
FilterChip(
onSelected: (value) => setState(() {
timespanView = Timespan.all;
}),
label: const Text('All'),
selected: timespanView == Timespan.all,
showCheckmark: false
)
],
),
const SizedBox(height: 20.0),
const Text(
'Transactions',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5.0),
ValueListenableBuilder(
valueListenable: transContr.transactionsBox.listenable(),
builder: (context, Box<Transaction> box, widget) {
transContr.transactionsList = box.values.toList();
transContr.transactionsList.sort((b, a) => a.createdAt.compareTo(b.createdAt));
if(box.isEmpty) {
return const SizedBox(
height: 200.0,
child: Center(
child: Text('no existing transactions yet'),
),
);
}
return ListView.builder(
const SizedBox(height: 5.0),
box.isEmpty ? const SizedBox(
height: 200.0,
child: Center(
child: Text('no existing transactions yet'),
),
) : ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: transContr.transactionsList.length <= 25 ? transContr.transactionsList.length : 25,
itemBuilder: (context, index) => TransactionListtile(transaction: transContr.transactionsList[index])
);
},
),
FilledButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const OnboardingView())
);
},
child: const Text('onboarding')
),
],
),
FilledButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const OnboardingView())
);
},
child: const Text('onboarding')
),
],
);
}
),
),
);
}
PieChartSectionData buildPieChartSection(BuildContext context, double value) {
return PieChartSectionData(
value: value,
color: Theme.of(context).colorScheme.secondaryContainer
);
List<PieChartSectionData> buildPieChartSectionList(BuildContext context) {
List<PieChartSectionData> sectionList = [];
int elapsedDays = transContr.transactionsList.last.createdAt.difference(DateTime.now()).inDays;
if(elapsedDays <= 0) elapsedDays = 1;
double other = 0;
for (Category cat in locator.get<CategoriesController>().categories.values) {
double categorySum = 0;
double avg = 0;
for(Transaction tr in transContr.transactionsList) {
if(tr.categoryId == cat.id) {
categorySum += tr.amount;
}
}
if(timespanView == Timespan.daily) {
avg = categorySum / elapsedDays;
} else if(timespanView == Timespan.weekly) {
avg = categorySum / (elapsedDays / 7);
} else if(timespanView == Timespan.monthly) {
avg = categorySum / (elapsedDays / 30);
} else if(timespanView == Timespan.yearly) {
avg = categorySum / (elapsedDays / 365);
} else {
avg = categorySum;
}
bool meetsThreshold = (categorySum / transContr.balance) > 0.2;
if(!meetsThreshold) {
other += avg;
}
if(!avg.isNaN && meetsThreshold) {
sectionList.add(PieChartSectionData(
value: double.parse(avg.toStringAsFixed(2)),
color: Color(cat.colorValue),
radius: 100.0
));
}
}
sectionList.add(PieChartSectionData(
value: double.parse(other.toStringAsFixed(2)),
color: Colors.grey,
radius: 100.0
));
return sectionList;
}
}
......@@ -49,9 +49,23 @@ Future<void> setupLocatorService() async {
locator.registerLazySingleton<CategoriesController>(() => categoriesController);
Box<Transaction> transactionsBox = await Hive.openBox<Transaction>('transactions_box');
double balance = 0;
double income = 0;
double expenses = 0;
for(Transaction tr in transactionsBox.values.toList()) {
balance += tr.amount;
if(tr.amount.isNegative) {
expenses += tr.amount;
} else {
income += tr.amount;
}
}
TransactionsController transactionsController = TransactionsController(
transactionsBox: transactionsBox,
transactionsList: transactionsBox.values.toList()
transactionsList: transactionsBox.values.toList(),
balance: balance,
income: income,
expenses: expenses
);
locator.registerLazySingleton<TransactionsController>(() => transactionsController);
}
......@@ -4,11 +4,14 @@ import 'package:trackeroo/logic/models/transaction.dart';
import 'package:trackeroo/logic/services/categories_controller.dart';
import 'package:trackeroo/logic/services/locator.dart';
class TransactionsController {
TransactionsController({required this.transactionsBox, required this.transactionsList});
class TransactionsController extends ChangeNotifier {
TransactionsController({required this.transactionsBox, required this.transactionsList, required this.balance, required this.income, required this.expenses});
Box<Transaction> transactionsBox;
List<Transaction> transactionsList;
double balance;
double income;
double expenses;
late Transaction lastDeletedTransaction;
Future<bool> saveTransaction(Transaction transaction) async {
......@@ -18,6 +21,12 @@ class TransactionsController {
transaction.id = id;
await transactionsBox.put(transaction.id, transaction);
transactionsList = transactionsBox.values.toList();
balance += transaction.amount;
if(transaction.amount.isNegative) {
expenses += transaction.amount;
} else {
income += transaction.amount;
}
} catch (e) {
return false;
}
......@@ -39,6 +48,12 @@ class TransactionsController {
lastDeletedTransaction = transaction;
await transactionsBox.delete(transaction.id);
transactionsList = transactionsBox.values.toList();
balance -= transaction.amount;
if(transaction.amount.isNegative) {
expenses -= transaction.amount;
} else {
income -= transaction.amount;
}
} catch (e) {
return false;
}
......@@ -49,6 +64,13 @@ class TransactionsController {
try {
await transactionsBox.put(lastDeletedTransaction.id, lastDeletedTransaction);
transactionsList = transactionsBox.values.toList();
balance += lastDeletedTransaction.amount;
if(lastDeletedTransaction.amount.isNegative) {
expenses += lastDeletedTransaction.amount;
} else {
income += lastDeletedTransaction.amount;
}
} catch (e) {
return false;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment