import 'package:flutter/material.dart'; import '../models/models.dart'; import '../storage/local_storage.dart'; import '../theme.dart'; import 'about_screen.dart'; import 'saved_run_detail_screen.dart'; class SavedRunsScreen extends StatefulWidget { const SavedRunsScreen({super.key}); @override State createState() => _SavedRunsScreenState(); } class _SavedRunsScreenState extends State { List _savedRuns = []; bool _loading = true; @override void initState() { super.initState(); _loadSavedRuns(); } Future _loadSavedRuns() async { final runs = await LocalStorage.getSavedRuns(); setState(() { _savedRuns = runs; _loading = false; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Saved Runs'), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () => Navigator.pop(context), ), actions: [ IconButton( icon: const Icon(Icons.info_outline), onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => const AboutScreen()), ), ), ], ), body: _loading ? const Center(child: CircularProgressIndicator()) : _savedRuns.isEmpty ? _buildEmptyState() : _buildRunsList(), ); } Widget _buildEmptyState() { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.bookmark_outline, size: 64, color: AppColors.textSecondary.withAlpha(128), ), const SizedBox(height: 16), Text( 'No saved runs yet', style: Theme.of(context).textTheme.titleMedium?.copyWith( color: AppColors.textSecondary, ), ), const SizedBox(height: 8), Text( 'Save a calculation from the results screen to compare runs over time.', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: AppColors.textSecondary, ), textAlign: TextAlign.center, ), ], ), ), ); } Widget _buildRunsList() { return ListView.builder( padding: const EdgeInsets.all(16), itemCount: _savedRuns.length, itemBuilder: (context, index) { final run = _savedRuns[index]; return _buildRunCard(run); }, ); } Widget _buildRunCard(SavedRun run) { return Card( margin: const EdgeInsets.only(bottom: 12), child: InkWell( onTap: () => _openRunDetail(run), borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( run.label, style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 4), Text( run.displayDate, style: Theme.of(context).textTheme.bodySmall?.copyWith( color: AppColors.textSecondary, ), ), const SizedBox(height: 8), Text( run.dominantFactorSummary, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: AppColors.primary, ), ), ], ), ), IconButton( icon: const Icon(Icons.delete_outline), color: AppColors.error, onPressed: () => _confirmDelete(run), ), ], ), ), ), ); } void _openRunDetail(SavedRun run) async { await Navigator.push( context, MaterialPageRoute( builder: (_) => SavedRunDetailScreen(savedRun: run), ), ); // Refresh list in case label was edited _loadSavedRuns(); } void _confirmDelete(SavedRun run) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Delete Run?'), content: Text('Delete "${run.label}"? This cannot be undone.'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Cancel'), ), TextButton( onPressed: () { Navigator.pop(context); _deleteRun(run); }, style: TextButton.styleFrom(foregroundColor: AppColors.error), child: const Text('Delete'), ), ], ), ); } Future _deleteRun(SavedRun run) async { await LocalStorage.deleteSavedRun(run.id); _loadSavedRuns(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Run deleted')), ); } } }