MotorSignal-App/lib/features/settings/settings_screen.dart

213 lines
8.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../services/sensor_fusion_service.dart';
import '../../services/map/map_provider_interface.dart';
import '../../services/map/map_providers.dart';
import '../../database/database.dart';
class SettingsScreen extends ConsumerWidget {
const SettingsScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final mapType = ref.watch(mapProviderTypeNotifierProvider);
return Scaffold(
appBar: AppBar(title: const Text('Settings')),
body: ListView(
padding: const EdgeInsets.all(16.0),
children: [
const Text(
'Map & Provider Settings',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.cyanAccent),
),
const SizedBox(height: 16),
Card(
clipBehavior: Clip.antiAlias,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Row(
children: [
Icon(Icons.map, color: Colors.cyanAccent),
SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Active Map Engine', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(height: 4),
Text('Select map rendering backend for live map, route preview, and replay.', style: TextStyle(fontSize: 13, color: Colors.white70)),
],
),
),
],
),
const SizedBox(height: 16),
SegmentedButton<AppMapType>(
segments: const [
ButtonSegment(
value: AppMapType.openStreetMap,
label: Text('OpenStreetMap (Primary)'),
icon: Icon(Icons.public),
),
ButtonSegment(
value: AppMapType.googleMaps,
label: Text('Google Maps'),
icon: Icon(Icons.map_outlined),
),
],
selected: {mapType},
onSelectionChanged: (Set<AppMapType> selection) {
ref
.read(mapProviderTypeNotifierProvider.notifier)
.setMapProviderType(selection.first);
},
),
],
),
),
),
const SizedBox(height: 32),
const Text(
'Sensors',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.cyanAccent),
),
const SizedBox(height: 16),
Card(
clipBehavior: Clip.antiAlias,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Icon(Icons.screen_rotation, color: Colors.cyanAccent),
const SizedBox(width: 12),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Calibrate Mount Angle',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
SizedBox(height: 4),
Text(
'Place the motorcycle perfectly upright and tap this to zero the lean angle sensor.',
style: TextStyle(fontSize: 13, color: Colors.white70, height: 1.3),
),
],
),
),
],
),
const SizedBox(height: 16),
Align(
alignment: Alignment.centerRight,
child: ElevatedButton(
onPressed: () async {
ref.read(sensorFusionServiceProvider).calibrateUpright();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Sensors Calibrated!')),
);
}
},
child: const Text('Calibrate'),
),
),
],
),
),
),
const SizedBox(height: 32),
const Text(
'Data',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.cyanAccent),
),
const SizedBox(height: 16),
Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () => context.go('/settings/diagnostics'),
child: const Padding(
padding: EdgeInsets.all(16.0),
child: Row(
children: [
Icon(Icons.monitor_heart, color: Colors.cyanAccent),
SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Sensor Diagnostics', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(height: 4),
Text('View raw IMU and GPS values.', style: TextStyle(fontSize: 13, color: Colors.white70)),
],
),
),
Icon(Icons.chevron_right, color: Colors.white54),
],
),
),
),
),
const SizedBox(height: 16),
Card(
clipBehavior: Clip.antiAlias,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Icon(Icons.delete_forever, color: Colors.redAccent),
const SizedBox(width: 12),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Clear Ride History', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(height: 4),
Text('Permanently delete all recorded rides and performance runs.', style: TextStyle(fontSize: 13, color: Colors.white70, height: 1.3)),
],
),
),
],
),
const SizedBox(height: 16),
Align(
alignment: Alignment.centerRight,
child: ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red.withValues(alpha: 0.2)),
onPressed: () async {
final db = ref.read(databaseProvider);
await db.delete(db.rides).go();
await db.delete(db.performanceRuns).go();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('All data cleared.')),
);
}
},
child: const Text('Clear', style: TextStyle(color: Colors.redAccent)),
),
),
],
),
),
),
],
),
);
}
}