- Enlarge calendar priority dots to 10px with pulsing animation - Increase task tile checkbox and menu button containers to 48x48 - Add proper minVerticalPadding to task tiles (72dp height) - Update filter chips with MaterialTapTargetSize.padded - Increase navigation buttons to 48x48 with 28px icons - Update task form with 48dp height segmented button
157 lines
3.9 KiB
Dart
157 lines
3.9 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
|
|
import '../../../../core/errors/failures.dart';
|
|
import '../../../../core/logging/app_logger.dart';
|
|
import '../../domain/entities/task_entity.dart';
|
|
import '../../domain/enums/priority.dart';
|
|
import '../../domain/repositories/task_repository.dart';
|
|
|
|
enum TasksStatus { initial, loading, success, error }
|
|
|
|
enum TaskFilter { all, active, completed }
|
|
|
|
class DailyTasksViewModel extends ChangeNotifier {
|
|
final TaskRepository repository;
|
|
final AppLogger logger;
|
|
|
|
DailyTasksViewModel({
|
|
required this.repository,
|
|
required this.logger,
|
|
});
|
|
|
|
TasksStatus _status = TasksStatus.initial;
|
|
List<TaskEntity> _tasks = [];
|
|
Failure? _failure;
|
|
DateTime _selectedDate = DateTime.now();
|
|
TaskFilter _filter = TaskFilter.all;
|
|
|
|
TasksStatus get status => _status;
|
|
List<TaskEntity> get tasks => _filteredTasks;
|
|
Failure? get failure => _failure;
|
|
DateTime get selectedDate => _selectedDate;
|
|
TaskFilter get filter => _filter;
|
|
|
|
List<TaskEntity> get _filteredTasks {
|
|
List<TaskEntity> filtered;
|
|
switch (_filter) {
|
|
case TaskFilter.all:
|
|
filtered = List.from(_tasks);
|
|
break;
|
|
case TaskFilter.active:
|
|
filtered = _tasks.where((t) => !t.isDone).toList();
|
|
break;
|
|
case TaskFilter.completed:
|
|
filtered = _tasks.where((t) => t.isDone).toList();
|
|
break;
|
|
}
|
|
// Sort by priority: high first, then medium, then low
|
|
filtered.sort((a, b) => _priorityOrder(a.priority).compareTo(_priorityOrder(b.priority)));
|
|
return filtered;
|
|
}
|
|
|
|
int _priorityOrder(Priority priority) {
|
|
switch (priority) {
|
|
case Priority.high:
|
|
return 0;
|
|
case Priority.medium:
|
|
return 1;
|
|
case Priority.low:
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
int get totalCount => _tasks.length;
|
|
int get completedCount => _tasks.where((t) => t.isDone).length;
|
|
|
|
Future<void> loadTasks() async {
|
|
_status = TasksStatus.loading;
|
|
_failure = null;
|
|
notifyListeners();
|
|
|
|
final result = await repository.getTasksByDate(_selectedDate);
|
|
|
|
result.when(
|
|
success: (data) {
|
|
_tasks = data;
|
|
_status = TasksStatus.success;
|
|
logger.info('Loaded ${data.length} tasks');
|
|
},
|
|
error: (failure) {
|
|
_failure = failure;
|
|
_status = TasksStatus.error;
|
|
logger.error('Failed to load tasks: ${failure.message}');
|
|
},
|
|
);
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
void setSelectedDate(DateTime date) {
|
|
_selectedDate = DateTime(date.year, date.month, date.day);
|
|
loadTasks();
|
|
}
|
|
|
|
void previousDay() {
|
|
setSelectedDate(_selectedDate.subtract(const Duration(days: 1)));
|
|
}
|
|
|
|
void nextDay() {
|
|
setSelectedDate(_selectedDate.add(const Duration(days: 1)));
|
|
}
|
|
|
|
void setFilter(TaskFilter filter) {
|
|
_filter = filter;
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> toggleTask(String id) async {
|
|
final result = await repository.toggleTaskStatus(id);
|
|
|
|
result.when(
|
|
success: (updatedTask) {
|
|
final index = _tasks.indexWhere((t) => t.id == id);
|
|
if (index != -1) {
|
|
_tasks[index] = updatedTask;
|
|
notifyListeners();
|
|
}
|
|
},
|
|
error: (failure) {
|
|
_failure = failure;
|
|
notifyListeners();
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> deleteTask(String id) async {
|
|
final result = await repository.deleteTask(id);
|
|
|
|
result.when(
|
|
success: (_) {
|
|
_tasks.removeWhere((t) => t.id == id);
|
|
notifyListeners();
|
|
},
|
|
error: (failure) {
|
|
_failure = failure;
|
|
notifyListeners();
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> rescheduleToTomorrow(String id) async {
|
|
final tomorrow = _selectedDate.add(const Duration(days: 1));
|
|
final result = await repository.rescheduleTask(id, tomorrow);
|
|
|
|
result.when(
|
|
success: (_) {
|
|
_tasks.removeWhere((t) => t.id == id);
|
|
notifyListeners();
|
|
logger.info('Task rescheduled to tomorrow');
|
|
},
|
|
error: (failure) {
|
|
_failure = failure;
|
|
notifyListeners();
|
|
},
|
|
);
|
|
}
|
|
}
|