Enhance AppSettings and RentController to manage not-occupied months, add lifetime summary to SettingsScreen, and update tests for compatibility
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -34,6 +34,12 @@ class HomeScreen extends StatelessWidget {
|
||||
selected: current == PaymentStatus.notPaid,
|
||||
onTap: () => Navigator.of(context).pop(PaymentStatus.notPaid),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Not occupied'),
|
||||
selected: current == PaymentStatus.notOccupied,
|
||||
onTap: () =>
|
||||
Navigator.of(context).pop(PaymentStatus.notOccupied),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Pending'),
|
||||
selected: current == PaymentStatus.pending,
|
||||
@@ -91,20 +97,6 @@ class HomeScreen extends StatelessWidget {
|
||||
RentController controller,
|
||||
RentTableRow row,
|
||||
) async {
|
||||
if (row.status == PaymentStatus.notOccupied) {
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Use Settings -> Unit occupied to manage not-occupied months.',
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final nextStatus = await _showStatusPicker(context, row.status);
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
@@ -114,8 +106,9 @@ class HomeScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
double? paidUsd;
|
||||
if (nextStatus == PaymentStatus.onTime ||
|
||||
nextStatus == PaymentStatus.late) {
|
||||
if (nextStatus == PaymentStatus.onTime) {
|
||||
paidUsd = controller.settings.rentUsd;
|
||||
} else if (nextStatus == PaymentStatus.late) {
|
||||
paidUsd = await _showPaidUsdDialog(
|
||||
context,
|
||||
initialValue: row.usdAmount ?? controller.settings.rentUsd,
|
||||
@@ -186,8 +179,11 @@ class HomeScreen extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
_YearSwitcher(
|
||||
year: controller.selectedYear,
|
||||
onPrevious: () =>
|
||||
controller.selectYear(controller.selectedYear - 1),
|
||||
onPrevious: controller.canSelectPreviousYear
|
||||
? () => controller.selectYear(
|
||||
controller.selectedYear - 1,
|
||||
)
|
||||
: null,
|
||||
onNext: controller.selectedYear < DateTime.now().year
|
||||
? () => controller.selectYear(
|
||||
controller.selectedYear + 1,
|
||||
@@ -282,7 +278,7 @@ class HomeScreen extends StatelessWidget {
|
||||
'Total: ${usdCurrency.format(totalUsd)} | ${sekCurrency.format(totalSek)}',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
FilledButton.icon(
|
||||
onPressed: () async {
|
||||
await controller.markCurrentMonthPaidManually();
|
||||
@@ -337,7 +333,7 @@ class _YearSwitcher extends StatelessWidget {
|
||||
});
|
||||
|
||||
final int year;
|
||||
final VoidCallback onPrevious;
|
||||
final VoidCallback? onPrevious;
|
||||
final VoidCallback? onNext;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rental_income_tracker/state/rent_controller.dart';
|
||||
|
||||
@@ -56,11 +57,45 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<RentController>(
|
||||
builder: (context, controller, _) {
|
||||
final summary = controller.buildLifetimeSummary();
|
||||
final usdCurrency = NumberFormat.currency(
|
||||
symbol: r'$',
|
||||
decimalDigits: 2,
|
||||
);
|
||||
final sekCurrency = NumberFormat.currency(
|
||||
symbol: 'SEK ',
|
||||
decimalDigits: 2,
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Settings')),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: <Widget>[
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'All-time totals (since May 2024)',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'${usdCurrency.format(summary.totalUsd)} | ${sekCurrency.format(summary.totalSek)}',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'Occupancy: ${summary.occupancyPercent.toStringAsFixed(1)}% (${summary.occupiedMonths}/${summary.totalTrackedMonths} months)',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextField(
|
||||
controller: _rentController,
|
||||
keyboardType: const TextInputType.numberWithOptions(
|
||||
|
||||
Reference in New Issue
Block a user