// Flutter import 'package:flutter/material.dart'; import 'package:flutter_expense_tracker/models/item_type.dart'; // Local import '/db.dart'; import '/models/tracked_item.dart'; /// TODO: /// - Expenses (total number, totals by day / month / year) /// - Incomes (total number, totals by day / month / year) /// - Assets (total number, total by day / month / year) /// - Projected Assets in: /// - 1 week, 1 month, 1 quarter, 1 year /// - 1/2 year? 2 years? 5 years? Allow customization? class ProjectionPage extends StatefulWidget { const ProjectionPage({ super.key, }); @override State createState() => _ProjectionPageState(); } class _ProjectionPageState extends State { @override Widget build(BuildContext context) { Widget expenseSummary = SummaryCardForTotals( list: DatabaseHelper.instance.getExpenses(), summaryTypeLabel: ItemType.expense.title, ); Widget incomeSummary = SummaryCardForTotals( list: DatabaseHelper.instance.getIncomes(), summaryTypeLabel: ItemType.income.title, ); Widget assetSummary = SummaryCardForTotals( list: DatabaseHelper.instance.getAssets(), summaryTypeLabel: ItemType.asset.title, ); return ListView( children: [ expenseSummary, incomeSummary, assetSummary, ], ); } } class SummaryCardForTotals extends StatelessWidget { const SummaryCardForTotals({ super.key, required this.list, required this.summaryTypeLabel, }); final Future> list; final String summaryTypeLabel; @override Widget build(BuildContext context) { return FutureBuilder>( future: list, builder: ( BuildContext context, AsyncSnapshot> snapshot, ) { if (!snapshot.hasData) { return Text('Loading $summaryTypeLabel Section...'); } // TODO: Do not show all 3 sections or any text for Assets. double dailyTotal = 0, monthlyTotal = 0, yearlyTotal = 0; for (TrackedItem e in snapshot.data!) { dailyTotal += e.calcComparableAmountDaily(); monthlyTotal += e.calcComparableAmountYearly() / 12; yearlyTotal += e.calcComparableAmountYearly(); } String dailyEstimate = dailyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~", monthlyEstimate = monthlyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~", yearlyEstimate = yearlyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~"; return SummaryCard( name: "$summaryTypeLabel Totals", leftText: "$dailyEstimate${dailyTotal.toStringAsFixed(2)} Daily", middleText: "$monthlyEstimate${monthlyTotal.toStringAsFixed(2)} Monthly", rightText: "$yearlyEstimate${yearlyTotal.toStringAsFixed(2)} Yearly", ); }); } } class SummaryCard extends StatelessWidget { const SummaryCard({ super.key, required this.name, required this.leftText, required this.middleText, required this.rightText, }); final String name; final String leftText; final String middleText; final String rightText; @override Widget build(BuildContext context) { return Card( color: Theme.of(context).cardColor, child: Padding( padding: const EdgeInsets.all(8.0), child: Card( color: Theme.of(context).highlightColor, child: Column( children: [ Text( name, style: TextStyle( decoration: TextDecoration.underline, fontSize: 16), ), Row( children: [ Spacer( flex: 3, ), Text(leftText), Spacer( flex: 1, ), Text(middleText), Spacer( flex: 1, ), Text(rightText), Spacer( flex: 3, ), ], ), ], ), ), ), ); } }