import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/constants.dart'; import '../../data/models/task.dart'; import '../../providers/tasks_provider.dart'; class TasksListScreen extends ConsumerStatefulWidget { const TasksListScreen({super.key}); @override ConsumerState createState() => _TasksListScreenState(); } class _TasksListScreenState extends ConsumerState with SingleTickerProviderStateMixin { late final TabController _tabs; @override void initState() { super.initState(); _tabs = TabController(length: 3, vsync: this); } @override void dispose() { _tabs.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final tasksAsync = ref.watch(tasksProvider); return Scaffold( appBar: AppBar( title: const Text('Tasks'), bottom: TabBar( controller: _tabs, tabs: const [ Tab(text: 'To Do'), Tab(text: 'In Progress'), Tab(text: 'Done'), ], ), ), body: tasksAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Error: $e'), TextButton( onPressed: () => ref.invalidate(tasksProvider), child: const Text('Retry'), ), ], ), ), data: (tasks) { final todo = tasks.where((t) => t.status == TaskStatus.todo).toList(); final inProgress = tasks.where((t) => t.status == TaskStatus.inProgress).toList(); final done = tasks.where((t) => t.status == TaskStatus.done).toList(); return RefreshIndicator( onRefresh: () => ref.refresh(tasksProvider.future), child: TabBarView( controller: _tabs, children: [ _TaskList(tasks: todo), _TaskList(tasks: inProgress), _TaskList(tasks: done), ], ), ); }, ), floatingActionButton: FloatingActionButton( heroTag: 'tasks_fab', onPressed: () => context.push(Routes.taskNew), child: const Icon(Icons.add), ), ); } } class _TaskList extends ConsumerWidget { final List tasks; const _TaskList({required this.tasks}); @override Widget build(BuildContext context, WidgetRef ref) { if (tasks.isEmpty) { return const Center(child: Text('No tasks here.')); } return ListView.separated( itemCount: tasks.length, separatorBuilder: (_, _) => const Divider(height: 1), itemBuilder: (context, i) { final task = tasks[i]; return ListTile( leading: _priorityIcon(task.priority), title: Text(task.title), subtitle: task.dueDate != null ? Text('Due: ${task.dueDate!.toLocal().toString().substring(0, 10)}') : null, onTap: () => context.push( Routes.taskEdit.replaceFirst(':id', '${task.id}'), ), ); }, ); } Widget _priorityIcon(TaskPriority p) { final color = switch (p) { TaskPriority.high => Colors.red, TaskPriority.medium => Colors.orange, TaskPriority.low => Colors.green, TaskPriority.none => Colors.grey, }; return Icon(Icons.flag, color: color); } }