// 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: /// - 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...'); } // Calculate the total fields based on item type. double dailyTotal = 0, monthlyTotal = 0, yearlyTotal = 0; bool isAsset = false; for (TrackedItem e in snapshot.data!) { if (e.type == ItemType.asset) { monthlyTotal += e.amount; isAsset = true; } else { dailyTotal += e.calcComparableAmountDaily(); monthlyTotal += e.calcComparableAmountYearly() / 12; yearlyTotal += e.calcComparableAmountYearly(); } } /* Determine what needs displayed for the item type. */ // Header String plural = snapshot.data!.length == 1 ? "" : "s"; String header = "$summaryTypeLabel Total"; header += isAsset ? "" : "s"; header += " (${snapshot.data!.length} Item$plural)"; // Total Fields String dailyEstimate = dailyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~", monthlyEstimate = monthlyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~", yearlyEstimate = yearlyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~"; String leftText = "", middleText = "", rightText = ""; if (isAsset) { middleText = "$monthlyEstimate${monthlyTotal.toStringAsFixed(2)}"; } else { leftText = "$dailyEstimate${dailyTotal.toStringAsFixed(2)} Daily"; middleText = "$monthlyEstimate${monthlyTotal.toStringAsFixed(2)} Monthly"; rightText = "$yearlyEstimate${yearlyTotal.toStringAsFixed(2)} Yearly"; } // Return the UI element. return SummaryCard( name: header, leftText: leftText, middleText: middleText, rightText: rightText, ); }); } } 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, ), ], ), ], ), ), ), ); } }