import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/tracker.dart'; import '../services/tracker_service.dart'; import '../widgets/theme.dart'; import '../widgets/tracker_tile.dart'; import 'create_tracker_screen.dart'; import 'tracker_screen.dart'; class HomeScreen extends ConsumerWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final AsyncValue> state = ref.watch(trackerServiceProvider); return Scaffold( appBar: AppBar(title: const Text('My Bible Tracker')), body: state.when( loading: () => const Center(child: CircularProgressIndicator()), error: (Object error, StackTrace stack) => Center(child: Text('Something went wrong:\n$error')), data: (List trackers) { if (trackers.isEmpty) { return const _EmptyState(); } return ListView.separated( padding: const EdgeInsets.all(AppTokens.spaceL), itemCount: trackers.length, separatorBuilder: (_, __) => const SizedBox(height: AppTokens.spaceM), itemBuilder: (BuildContext context, int index) { final Tracker tracker = trackers[index]; return TrackerTile( tracker: tracker, onTap: () => Navigator.of(context).push( MaterialPageRoute( builder: (_) => TrackerScreen(trackerId: tracker.id), ), ), onLongPress: () => _showTrackerMenu(context, ref, tracker), ); }, ); }, ), floatingActionButton: FloatingActionButton.extended( onPressed: () => Navigator.of(context).push( MaterialPageRoute(builder: (_) => const CreateTrackerScreen()), ), icon: const Icon(Icons.add), label: const Text('New Tracker'), ), ); } Future _showTrackerMenu( BuildContext context, WidgetRef ref, Tracker tracker, ) async { final _TrackerMenuAction? action = await showModalBottomSheet<_TrackerMenuAction>( context: context, showDragHandle: true, builder: (BuildContext context) { return SafeArea( child: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( leading: const Icon(Icons.edit_outlined), title: const Text('Rename / recolor'), onTap: () => Navigator.of(context).pop(_TrackerMenuAction.edit), ), ListTile( leading: const Icon(Icons.refresh), title: const Text('Reset progress'), onTap: () => Navigator.of(context).pop(_TrackerMenuAction.reset), ), ListTile( leading: const Icon(Icons.delete_outline), iconColor: Theme.of(context).colorScheme.error, textColor: Theme.of(context).colorScheme.error, title: const Text('Delete'), onTap: () => Navigator.of(context).pop(_TrackerMenuAction.delete), ), const SizedBox(height: AppTokens.spaceS), ], ), ); }, ); if (action == null || !context.mounted) return; switch (action) { case _TrackerMenuAction.edit: await Navigator.of(context).push( MaterialPageRoute( builder: (_) => CreateTrackerScreen(existing: tracker), ), ); case _TrackerMenuAction.reset: await _confirmAndRun( context, title: 'Reset progress?', message: 'All checked chapters for "${tracker.name}" will be cleared.', destructive: true, run: () => ref.read(trackerServiceProvider.notifier).reset(tracker.id), ); case _TrackerMenuAction.delete: await _confirmAndRun( context, title: 'Delete tracker?', message: '"${tracker.name}" will be removed permanently.', destructive: true, run: () => ref.read(trackerServiceProvider.notifier).delete(tracker.id), ); } } Future _confirmAndRun( BuildContext context, { required String title, required String message, required bool destructive, required Future Function() run, }) async { final bool? confirmed = await showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: Text(title), content: Text(message), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('Cancel'), ), FilledButton( style: destructive ? FilledButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.error, ) : null, onPressed: () => Navigator.of(context).pop(true), child: const Text('Confirm'), ), ], ), ); if (confirmed ?? false) { await run(); } } } enum _TrackerMenuAction { edit, reset, delete } class _EmptyState extends StatelessWidget { const _EmptyState(); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(AppTokens.spaceXXL), child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.menu_book_outlined, size: 72, color: Theme.of(context).colorScheme.primary, ), const SizedBox(height: AppTokens.spaceL), Text( 'Start your first tracker', style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center, ), const SizedBox(height: AppTokens.spaceS), Text( 'Create a tracker to mark the chapters you have read. ' 'Read at your own pace — there are no deadlines.', textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], ), ), ); } }