74 lines
2.5 KiB
Dart
74 lines
2.5 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../../data/db/app_database.dart';
|
|
import '../../../data/repositories/task_repository.dart';
|
|
import '../../../data/repositories/user_repository.dart';
|
|
import '../../../domain/entities/task_entity.dart';
|
|
import '../../../domain/entities/task_status.dart';
|
|
import '../../../domain/entities/user_entity.dart';
|
|
|
|
// ── Infrastructure providers ──
|
|
|
|
/// Singleton Drift database instance.
|
|
final appDatabaseProvider = Provider<AppDatabase>((ref) {
|
|
final db = AppDatabase();
|
|
ref.onDispose(() => db.close());
|
|
return db;
|
|
});
|
|
|
|
/// Task repository backed by Drift.
|
|
final taskRepositoryProvider = Provider<TaskRepository>((ref) {
|
|
return TaskRepository(ref.watch(appDatabaseProvider));
|
|
});
|
|
|
|
/// User repository backed by Drift.
|
|
final userRepositoryProvider = Provider<UserRepository>((ref) {
|
|
return UserRepository(ref.watch(appDatabaseProvider));
|
|
});
|
|
|
|
/// Current user loaded from the database. Null if onboarding not complete.
|
|
final currentUserProvider = FutureProvider<UserEntity?>((ref) {
|
|
final repo = ref.watch(userRepositoryProvider);
|
|
return repo.getCurrentUser();
|
|
});
|
|
|
|
// ── Task list (reactive stream from DB) ──
|
|
|
|
/// All tasks for the current user, streamed from Drift.
|
|
final tasksProvider = StreamProvider<List<TaskEntity>>((ref) {
|
|
final user = ref.watch(currentUserProvider).value;
|
|
if (user == null) return Stream.value([]);
|
|
final repo = ref.watch(taskRepositoryProvider);
|
|
return repo.watchTasks(user.id);
|
|
});
|
|
|
|
/// Alias for [tasksProvider]. Returns all tasks — no date filtering in MVP.
|
|
/// Screens are responsible for splitting into pending/completed.
|
|
final todayTasksProvider = tasksProvider;
|
|
|
|
/// Pending tasks only, ordered by sort order.
|
|
final pendingTasksProvider = Provider<List<TaskEntity>>((ref) {
|
|
final tasks = ref.watch(tasksProvider).value ?? [];
|
|
return tasks
|
|
.where((t) => t.status == TaskStatus.pending)
|
|
.toList()
|
|
..sort((a, b) => a.sortOrder.compareTo(b.sortOrder));
|
|
});
|
|
|
|
/// Next zen task: first pending task sorted by energy level (lowest first).
|
|
final nextZenTaskProvider = Provider<TaskEntity?>((ref) {
|
|
final pending = ref.watch(pendingTasksProvider);
|
|
if (pending.isEmpty) return null;
|
|
final sorted = [...pending]
|
|
..sort((a, b) => a.energyLevel.compareTo(b.energyLevel));
|
|
return sorted.first;
|
|
});
|
|
|
|
/// Count of completed self-care tasks.
|
|
final selfCareCountProvider = Provider<int>((ref) {
|
|
final tasks = ref.watch(tasksProvider).value ?? [];
|
|
return tasks
|
|
.where((t) => t.isSelfCare && t.status == TaskStatus.done)
|
|
.length;
|
|
});
|