---
phase: 02-rooms-and-tasks
plan: 03
subsystem: ui
tags: [riverpod, flutter, task-crud, frequency-picker, effort-selector, overdue-highlighting, german-localization]

# Dependency graph
requires:
  - phase: 02-rooms-and-tasks
    provides: TasksDao with CRUD and stream queries, FrequencyInterval presets, EffortLevel enum, formatRelativeDate German formatter
provides:
  - TaskListScreen showing tasks sorted by due date with empty state
  - TaskRow with checkbox completion, overdue coral highlighting, relative German dates
  - TaskFormScreen for create/edit with frequency presets, custom intervals, effort selector
  - tasksInRoomProvider StreamProvider.family wrapping TasksDao
  - TaskActions AsyncNotifier for task mutations
  - 19 German localization keys for task UI
affects: [02-rooms-and-tasks, 03-daily-plan]

# Tech tracking
tech-stack:
  added: []
  patterns: [manual-stream-provider-family-for-drift-types, choice-chip-frequency-selector, segmented-button-effort-picker, custom-frequency-number-plus-unit]

key-files:
  created:
    - lib/features/tasks/presentation/task_providers.dart
    - lib/features/tasks/presentation/task_providers.g.dart
    - lib/features/tasks/presentation/task_form_screen.dart
    - lib/features/tasks/presentation/task_row.dart
  modified:
    - lib/features/tasks/presentation/task_list_screen.dart
    - lib/l10n/app_de.arb
    - lib/l10n/app_localizations.dart
    - lib/l10n/app_localizations_de.dart

key-decisions:
  - "tasksInRoomProvider defined as manual StreamProvider.family due to riverpod_generator InvalidTypeException with drift-generated Task type in family providers"
  - "Frequency selector uses ChoiceChip Wrap layout for 10 presets plus custom option for clean presentation on varying screen widths"
  - "TaskRow uses ListTile with middle-dot separator between relative date and frequency label"

patterns-established:
  - "Manual StreamProvider.family for drift-generated types that fail riverpod_generator"
  - "ChoiceChip Wrap for multi-option selection with custom fallback"
  - "Warm coral 0xFFE07A5F for overdue date text, onSurfaceVariant for normal dates"
  - "Long-press on task row triggers delete confirmation dialog"

requirements-completed: [TASK-01, TASK-02, TASK-03, TASK-04, TASK-05, TASK-06, TASK-07, TASK-08]

# Metrics
duration: 12min
completed: 2026-03-15
---

# Phase 2 Plan 03: Task Management UI Summary

**Task list screen with sorted due dates, task row with checkbox completion and overdue coral highlighting, full-screen create/edit form with 10 frequency presets plus custom intervals, and 3-way effort selector**

## Performance

- **Duration:** 12 min
- **Started:** 2026-03-15T20:57:40Z
- **Completed:** 2026-03-15T21:09:52Z
- **Tasks:** 2
- **Files modified:** 8

## Accomplishments
- Task providers connecting presentation layer to TasksDao with reactive stream queries and mutation notifier
- Task form screen supporting create and edit modes with name, frequency (10 presets + custom with number/unit picker), effort (segmented button), description, and date picker
- Task list screen with room name AppBar, sorted task list, empty state, and FAB for creation
- Task row displaying checkbox completion, overdue highlighting in warm coral, relative German dates, and frequency labels
- 19 new German localization keys covering task form, delete confirmation, and empty state

## Task Commits

Each task was committed atomically:

1. **Task 1: Create task providers, form screen with frequency and effort selectors** - `652ff01` (feat)
2. **Task 2: Build task list screen with task row, completion, and overdue highlighting** - `b535f57` (feat)

## Files Created/Modified
- `lib/features/tasks/presentation/task_providers.dart` - tasksInRoomProvider stream family + TaskActions AsyncNotifier for CRUD
- `lib/features/tasks/presentation/task_providers.g.dart` - Generated code for TaskActions provider
- `lib/features/tasks/presentation/task_form_screen.dart` - Full create/edit form with frequency presets, custom interval, effort selector, date picker
- `lib/features/tasks/presentation/task_row.dart` - Task row with checkbox, overdue highlighting, relative date, frequency label
- `lib/features/tasks/presentation/task_list_screen.dart` - Task list screen replacing placeholder with full reactive implementation
- `lib/l10n/app_de.arb` - 19 new task-related German localization keys
- `lib/l10n/app_localizations.dart` - Regenerated with task keys
- `lib/l10n/app_localizations_de.dart` - Regenerated with task keys

## Decisions Made
- Used manual `StreamProvider.family.autoDispose` for `tasksInRoomProvider` instead of `@riverpod` code generation because riverpod_generator throws `InvalidTypeException` when drift-generated `Task` type is used as return type in family providers
- Frequency selector uses `ChoiceChip` in a `Wrap` layout (not `DropdownButtonFormField`) for better visibility of all 10 preset options at a glance, with a separate custom option that expands to show number + unit picker
- Task row uses `ListTile` with middle-dot separator between relative date and frequency label for clean information density

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 3 - Blocking] Committed uncommitted Plan 02-02 Task 2 changes**
- **Found during:** Task 1 (pre-execution state check)
- **Issue:** Plan 02-02 Task 2 (rooms_screen, room_card, test update) was executed but not committed, causing dirty working tree
- **Fix:** Committed as `519a56b` before starting Plan 02-03 work
- **Files modified:** rooms_screen.dart, room_card.dart, app_shell_test.dart
- **Verification:** All tests pass after commit
- **Committed in:** 519a56b (separate from Plan 02-03)

**2. [Rule 3 - Blocking] Manual StreamProvider for drift Task type**
- **Found during:** Task 1 (build_runner code generation)
- **Issue:** `@riverpod Stream<List<Task>> tasksInRoom(Ref ref, int roomId)` fails with `InvalidTypeException: The type is invalid and cannot be converted to code` because riverpod_generator cannot handle drift-generated `Task` class in family provider return types
- **Fix:** Defined `tasksInRoomProvider` as manual `StreamProvider.family.autoDispose<List<Task>, int>` instead of code-generated
- **Files modified:** lib/features/tasks/presentation/task_providers.dart
- **Verification:** Build succeeds, dart analyze clean, all tests pass
- **Committed in:** 652ff01 (Task 1 commit)

---

**Total deviations:** 2 auto-fixed (both blocking issues)
**Impact on plan:** Both fixes necessary to unblock execution. Manual provider is functionally equivalent to generated version. No scope creep.

## Issues Encountered
- riverpod_generator 4.0.3 cannot generate code for `Stream<List<T>>` where `T` is a drift-generated `DataClass` in family providers. Workaround: define the provider manually using `StreamProvider.family.autoDispose`. This may be resolved in a future riverpod_generator release.

## User Setup Required

None - no external service configuration required.

## Next Phase Readiness
- Task CRUD UI complete, ready for template selection (02-04) to seed tasks from templates
- Task list feeds Phase 3 daily plan view with overdue/today/upcoming grouping
- All 59 existing tests continue to pass
- Full dart analyze clean on lib/ source code

## Self-Check: PASSED

All 8 key files verified present. Both task commits (652ff01, b535f57) verified in git log. 59 tests passing. dart analyze clean on lib/.

---
*Phase: 02-rooms-and-tasks*
*Completed: 2026-03-15*
