diff --git a/trackeroo/lib/frontend/utils/onboarding/category_chip.dart b/trackeroo/lib/frontend/utils/onboarding/category_chip.dart new file mode 100644 index 0000000000000000000000000000000000000000..3ffa517adcfbfb38d7beab2555fc8b0a51e0ad33 --- /dev/null +++ b/trackeroo/lib/frontend/utils/onboarding/category_chip.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:trackeroo/logic/models/category.dart'; + +class CategoryChip extends StatelessWidget { + const CategoryChip({Key? key, required this.category}) : super(key: key); + + final Category category; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(right: 5.0), + child: ActionChip( + avatar: Icon( + IconData(category.iconCodePoint, fontFamily: category.iconFontFamily), + color: Color(category.colorValue), + ), + label: Text(category.title), + onPressed: () => {}, + ), + ); + } +} \ No newline at end of file diff --git a/trackeroo/lib/frontend/views/edit_transaction_view.dart b/trackeroo/lib/frontend/views/edit_transaction_view.dart index 5683e8c39f7586fcf9c9e8e5683470257ba71d72..20fc6cd922c600d5e5f68f64b29380ee0844dcfe 100644 --- a/trackeroo/lib/frontend/views/edit_transaction_view.dart +++ b/trackeroo/lib/frontend/views/edit_transaction_view.dart @@ -23,6 +23,7 @@ class _EditTransactionViewState extends State<EditTransactionView> { String categoryId = ''; DateTime dueDate = DateTime.now(); bool transExists = false; + double oldAmount = 0.0; bool isExpense = true; bool isScheduled = false; Timespan selectedTimespan = Timespan.none; @@ -31,6 +32,7 @@ class _EditTransactionViewState extends State<EditTransactionView> { void initState() { transExists = widget.transaction != null; if(transExists) { + oldAmount = widget.transaction!.amount; _titleController.text = widget.transaction!.title; isExpense = widget.transaction!.amount.isNegative; _amountController.text = widget.transaction!.amount.abs().toString(); @@ -240,7 +242,7 @@ class _EditTransactionViewState extends State<EditTransactionView> { widget.transaction!.title = _titleController.text; widget.transaction!.amount = isExpense ? -double.parse(_amountController.text) : double.parse(_amountController.text); widget.transaction!.categoryId = categoryId; - return await locator.get<TransactionsController>().updateTransaction(widget.transaction!); + return await locator.get<TransactionsController>().updateTransaction(oldAmount, widget.transaction!); } else { Transaction newTransaction = Transaction( title: _titleController.text, diff --git a/trackeroo/lib/frontend/views/home_view.dart b/trackeroo/lib/frontend/views/home_view.dart index ce71ad1626bcd88b005a3d6228b0d3dfd57c4e37..a9fe58b3c1c387cda8a357be2d5e235f95c0cb6d 100644 --- a/trackeroo/lib/frontend/views/home_view.dart +++ b/trackeroo/lib/frontend/views/home_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import 'package:trackeroo/frontend/utils/onboarding/category_chip.dart'; import 'package:trackeroo/frontend/utils/transaction_listtile.dart'; import 'package:trackeroo/frontend/views/onboarding_view.dart'; import 'package:trackeroo/logic/models/category.dart'; @@ -19,11 +20,9 @@ class HomeView extends StatefulWidget { } class _HomeViewState extends State<HomeView> { - Transaction trn = Transaction(title: "Bus Ticket VVS", amount: -5.32, categoryId: 'food_and_groceries', dueDate: DateTime.now()); - Transaction trp = Transaction(title: "Gehalt", amount: 1300, categoryId: 'leisure_and_entertainment', dueDate: DateTime.now()); - Timespan timespanView = Timespan.monthly; TransactionsController transContr = locator.get<TransactionsController>(); + List<Category> inChartShownCats = []; @override Widget build(BuildContext context) { @@ -84,7 +83,7 @@ class _HomeViewState extends State<HomeView> { width: 50.0, child: PieChart( PieChartData( - centerSpaceRadius: 0, + centerSpaceRadius: 30.0, sections: transContr.transactionsList.isNotEmpty ? buildPieChartSectionList(context) : null, ), swapAnimationDuration: const Duration(milliseconds: 500), @@ -106,6 +105,15 @@ class _HomeViewState extends State<HomeView> { ), ], ), + const SizedBox(height: 15.0), + AbsorbPointer( + absorbing: true, + child: Wrap( + children: [ + for(Category cat in inChartShownCats) CategoryChip(category: cat) + ], + ), + ), const SizedBox(height: 10.0), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -191,6 +199,7 @@ class _HomeViewState extends State<HomeView> { List<PieChartSectionData> buildPieChartSectionList(BuildContext context) { List<PieChartSectionData> sectionList = []; + inChartShownCats.clear(); int elapsedDays = transContr.transactionsList.last.createdAt.difference(DateTime.now()).inDays; if(elapsedDays <= 0) elapsedDays = 1; @@ -218,25 +227,79 @@ class _HomeViewState extends State<HomeView> { avg = categorySum; } - bool meetsThreshold = (categorySum / transContr.balance) > 0.2; + bool meetsThreshold = (categorySum.abs() / transContr.balance.abs()) > 0.06; if(!meetsThreshold) { other += avg; } if(!avg.isNaN && meetsThreshold) { + inChartShownCats.add(cat); sectionList.add(PieChartSectionData( - value: double.parse(avg.toStringAsFixed(2)), + value: double.parse(avg.toStringAsFixed(2)).abs(), + showTitle: true, + title: avg.toStringAsFixed(2), color: Color(cat.colorValue), - radius: 100.0 + radius: 70.0, + badgeWidget: Container( + height: 40.0, + width: 40.0, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + shape: BoxShape.circle, + ), + child: Center( + child: Icon( + IconData( + cat.iconCodePoint, + fontFamily: cat.iconFontFamily, + ), + color: Color(cat.colorValue), + ) + ) + ), + titlePositionPercentageOffset: .4, + titleStyle: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + badgePositionPercentageOffset: 1.1 )); } } - sectionList.add(PieChartSectionData( - value: double.parse(other.toStringAsFixed(2)), - color: Colors.grey, - radius: 100.0 - )); + if (other.abs() > 0) { + inChartShownCats.add(Category( + id: 'other', + title: 'Other', + iconCodePoint: Icons.category_rounded.codePoint, + colorValue: Colors.grey.value + )); + sectionList.add(PieChartSectionData( + value: double.parse(other.toStringAsFixed(2)).abs(), + showTitle: true, + title: other.toStringAsFixed(2), + color: Colors.grey, + radius: 70.0, + badgeWidget: Container( + height: 40.0, + width: 40.0, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + shape: BoxShape.circle + ), + child: const Center( + child: Icon( + Icons.category_rounded, + color: Colors.grey, + ) + ) + ), + titlePositionPercentageOffset: .4, + titleStyle: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + badgePositionPercentageOffset: 1.1 + )); +} return sectionList; } } diff --git a/trackeroo/lib/logic/services/transactions_controller.dart b/trackeroo/lib/logic/services/transactions_controller.dart index 5f631a8cc61eaf1e28cafa803708572cb18a8fbd..3b365c19d54c07500ca1dd20e042e897f79da1ce 100644 --- a/trackeroo/lib/logic/services/transactions_controller.dart +++ b/trackeroo/lib/logic/services/transactions_controller.dart @@ -19,21 +19,21 @@ class TransactionsController extends ChangeNotifier { locator.get<CategoriesController>().categories[transaction.categoryId]?.spendings += transaction.amount; int id = UniqueKey().hashCode; 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; } + await transactionsBox.put(transaction.id, transaction); + transactionsList = transactionsBox.values.toList(); } catch (e) { return false; } return true; } - Future<bool> updateTransaction(Transaction transaction) async { + Future<bool> updateTransaction(double oldAmount, Transaction transaction) async { try { await transactionsBox.put(transaction.id, transaction); transactionsList = transactionsBox.values.toList(); @@ -46,14 +46,14 @@ class TransactionsController extends ChangeNotifier { Future<bool> deleteTransaction(Transaction transaction) async { try { 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; } + await transactionsBox.delete(transaction.id); + transactionsList = transactionsBox.values.toList(); } catch (e) { return false; } @@ -62,8 +62,6 @@ class TransactionsController extends ChangeNotifier { Future<bool> undoLastDeletion() async { try { - await transactionsBox.put(lastDeletedTransaction.id, lastDeletedTransaction); - transactionsList = transactionsBox.values.toList(); balance += lastDeletedTransaction.amount; if(lastDeletedTransaction.amount.isNegative) { @@ -71,6 +69,8 @@ class TransactionsController extends ChangeNotifier { } else { income += lastDeletedTransaction.amount; } + await transactionsBox.put(lastDeletedTransaction.id, lastDeletedTransaction); + transactionsList = transactionsBox.values.toList(); } catch (e) { return false; }