leafittome/lib/features/today/application/due_tasks_provider.dart
cschlaefke 53ee30c598 Firestore und Auth: echte Daten statt Demo, Login mit E-Mail+Passwort, Security Rules
- Datenmodell: users/{uid}, households/{id} mit memberUids, plants/locations als Subcollections
- StreamProvider liefern Live-Daten, Repositories kapseln Schreibzugriffe
- Login-Screen mit Registrierung (legt Haushalt automatisch an), Logout in Einstellungen
- Router-Redirect bei Login/Logout, firestore.rules mit Haushalts-Prinzip
- Tests auf firebase_auth_mocks + fake_cloud_firestore umgestellt
- Verifiziert: analyze/test grün, Android-Debug-Build erfolgreich

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 22:53:09 +02:00

61 lines
2.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../plants/data/plants_provider.dart';
import '../../plants/domain/plant.dart';
import '../domain/due_task.dart';
DateTime _dateOnly(DateTime dt) => DateTime(dt.year, dt.month, dt.day);
DateTime? _nextDue(DateTime? lastDone, int intervalDays, DateTime today) {
// Noch nie erledigt → sofort fällig.
if (lastDone == null) return today;
return _dateOnly(lastDone).add(Duration(days: intervalDays));
}
Iterable<DueTask> _tasksForPlant(Plant plant, DateTime today) sync* {
final watering = _nextDue(plant.lastWatered, plant.wateringIntervalDays, today);
if (watering != null && !watering.isAfter(today)) {
yield DueTask(plant: plant, type: CareTaskType.watering, dueDate: watering);
}
final fertilizing =
_nextDue(plant.lastFertilized, plant.fertilizingIntervalDays, today);
if (fertilizing != null && !fertilizing.isAfter(today)) {
yield DueTask(
plant: plant, type: CareTaskType.fertilizing, dueDate: fertilizing);
}
}
/// Alle heute fälligen und überfälligen Aufgaben, Überfälliges zuerst.
final dueTasksProvider = Provider<List<DueTask>>((ref) {
final plants = ref.watch(plantsProvider).value ?? const [];
final today = _dateOnly(DateTime.now());
final tasks = [
for (final plant in plants) ..._tasksForPlant(plant, today),
];
tasks.sort((a, b) {
final byDate = a.dueDate.compareTo(b.dueDate);
if (byDate != 0) return byDate;
return a.plant.nickname.compareTo(b.plant.nickname);
});
return tasks;
});
/// Das nächste zukünftige Fälligkeitsdatum für den "Alles versorgt"-Screen
/// ("Nächste Aufgabe: Freitag").
final nextDueDateProvider = Provider<DateTime?>((ref) {
final plants = ref.watch(plantsProvider).value ?? const [];
final today = _dateOnly(DateTime.now());
DateTime? next;
for (final plant in plants) {
for (final candidate in [
_nextDue(plant.lastWatered, plant.wateringIntervalDays, today),
_nextDue(plant.lastFertilized, plant.fertilizingIntervalDays, today),
]) {
if (candidate == null || !candidate.isAfter(today)) continue;
if (next == null || candidate.isBefore(next)) next = candidate;
}
}
return next;
});