155 lines
4.1 KiB
Dart
155 lines
4.1 KiB
Dart
// Flutter
|
|
import 'package:flutter/material.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<ProjectionPage> createState() => _ProjectionPageState();
|
|
}
|
|
|
|
class _ProjectionPageState extends State<ProjectionPage> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget expenseSummary = SummaryCardForTotals(
|
|
list: DatabaseHelper.instance.getExpenses(),
|
|
summaryTypeLabel: "Expense",
|
|
);
|
|
|
|
return ListView(
|
|
children: [
|
|
expenseSummary,
|
|
SummaryCard(
|
|
name: "Income Totals",
|
|
leftText: "left",
|
|
middleText: "middle",
|
|
rightText: "right",
|
|
),
|
|
SummaryCard(
|
|
name: "Asset Totals",
|
|
leftText: "left",
|
|
middleText: "middle",
|
|
rightText: "right",
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class SummaryCardForTotals extends StatelessWidget {
|
|
const SummaryCardForTotals({
|
|
super.key,
|
|
required this.list,
|
|
required this.summaryTypeLabel,
|
|
});
|
|
|
|
final Future<List<TrackedItem>> list;
|
|
final String summaryTypeLabel;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return FutureBuilder<List<TrackedItem>>(
|
|
future: list,
|
|
builder: (
|
|
BuildContext context,
|
|
AsyncSnapshot<List<TrackedItem>> snapshot,
|
|
) {
|
|
if (!snapshot.hasData) {
|
|
return Text('Loading $summaryTypeLabel Section...');
|
|
}
|
|
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,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|