112 lines
4.3 KiB
Dart
112 lines
4.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import '../services/app_state.dart';
|
|
import '../services/onboarding_keys.dart';
|
|
import 'data_settings_screen.dart';
|
|
import 'ui_settings_screen.dart';
|
|
|
|
/// The "Settings" tab: a landing menu into submenus — [UiSettingsScreen]
|
|
/// (appearance) and [DataSettingsScreen] (cloud storage, photo handling,
|
|
/// advanced/purge) — plus a read-only summary of what's stored locally.
|
|
class SettingsScreen extends StatelessWidget {
|
|
const SettingsScreen({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final appState = context.watch<AppState>();
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('Settings')),
|
|
body: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
Card(
|
|
child: ListTile(
|
|
leading: const Icon(Icons.palette_outlined),
|
|
title: const Text('UI'),
|
|
subtitle: const Text('Appearance'),
|
|
trailing: const Icon(Icons.chevron_right),
|
|
onTap: () => Navigator.of(context).push(
|
|
MaterialPageRoute(builder: (_) => const UiSettingsScreen()),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Card(
|
|
key: OnboardingKeys.settingsDataMenuEntry,
|
|
child: ListTile(
|
|
leading: const Icon(Icons.storage_outlined),
|
|
title: const Text('Data'),
|
|
subtitle: const Text('Cloud storage, photo syncing, advanced'),
|
|
trailing: const Icon(Icons.chevron_right),
|
|
onTap: () => Navigator.of(context).push(
|
|
MaterialPageRoute(builder: (_) => const DataSettingsScreen()),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Card(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Ads', style: Theme.of(context).textTheme.titleMedium),
|
|
const SizedBox(height: 8),
|
|
if (appState.adsCurrentlyDisabled) ...[
|
|
Text(
|
|
'Ads are disabled until '
|
|
'${DateFormat.yMMMd().format(appState.adFreeUntil!.toLocal())}.',
|
|
style: Theme.of(context).textTheme.bodyMedium,
|
|
),
|
|
] else ...[
|
|
Text(
|
|
'This app shows a single ad, at most once per app session, right '
|
|
'before syncing your data to the cloud.',
|
|
style: Theme.of(context).textTheme.bodyMedium,
|
|
),
|
|
const SizedBox(height: 12),
|
|
if (appState.purchaseError != null) ...[
|
|
Text(
|
|
appState.purchaseError!,
|
|
style: TextStyle(color: Theme.of(context).colorScheme.error),
|
|
),
|
|
const SizedBox(height: 8),
|
|
],
|
|
FilledButton.icon(
|
|
onPressed: () => context.read<AppState>().buyAdFreeYear(),
|
|
icon: const Icon(Icons.block),
|
|
label: Text(
|
|
appState.adFreeYearPriceLabel == null
|
|
? 'Remove Ads for a Year'
|
|
: 'Remove Ads for a Year — ${appState.adFreeYearPriceLabel}',
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Card(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Summary', style: Theme.of(context).textTheme.titleMedium),
|
|
const SizedBox(height: 8),
|
|
Text('${appState.vehicles.length} vehicle(s)'),
|
|
Text('${appState.fuelEntries.length} fuel entries'),
|
|
Text('${appState.totalGallonsAllVehicles.toStringAsFixed(3)} total gallons logged'),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|