Files
rental_income_tracker/lib/screens/settings_screen.dart
T

124 lines
4.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rental_income_tracker/state/rent_controller.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({super.key});
@override
State<SettingsScreen> createState() => _SettingsScreenState();
}
class _SettingsScreenState extends State<SettingsScreen> {
final TextEditingController _rentController = TextEditingController();
@override
void didChangeDependencies() {
super.didChangeDependencies();
final controller = context.read<RentController>();
_rentController.text = controller.settings.rentUsd.toStringAsFixed(2);
}
@override
void dispose() {
_rentController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Consumer<RentController>(
builder: (context, controller, _) {
return Scaffold(
appBar: AppBar(title: const Text('Settings')),
body: ListView(
padding: const EdgeInsets.all(16),
children: <Widget>[
TextField(
controller: _rentController,
keyboardType: const TextInputType.numberWithOptions(
decimal: true,
),
decoration: const InputDecoration(
labelText: 'Monthly rent (USD)',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 12),
FilledButton(
onPressed: () async {
final value = double.tryParse(_rentController.text.trim());
if (value == null || value <= 0) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Enter a valid rent amount.'),
),
);
return;
}
await controller.updateRentUsd(value);
if (!context.mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Rent updated.')),
);
},
child: const Text('Save rent amount'),
),
const SizedBox(height: 12),
SwitchListTile(
title: const Text('Unit occupied'),
subtitle: const Text(
'When turned off, current and future months are marked Not occupied and reminders stop.',
),
value: controller.settings.occupied,
onChanged: (value) async {
await controller.setOccupied(value);
},
),
const Divider(height: 24),
FilledButton.icon(
onPressed: () async {
await controller.backfillLastYear();
if (!context.mounted) {
return;
}
if (controller.errorMessage == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Backfill finished for last year.'),
),
);
}
},
icon: const Icon(Icons.history),
label: const Text('Backfill last year (one click)'),
),
const SizedBox(height: 12),
FilledButton.icon(
onPressed: () async {
final path = await controller.exportJson();
if (!context.mounted) {
return;
}
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Exported to $path')));
},
icon: const Icon(Icons.download),
label: const Text('Export JSON'),
),
const SizedBox(height: 16),
const Text(
'ForexRateAPI key is configured in code constant forexRateApiKey.',
),
],
),
);
},
);
}
}