timetracker/.tasks/done/TT-006-timer-feature-ui.md
2026-08-03 21:51:48 +02:00

76 lines
3.2 KiB
Markdown

# TT-006 — Timer Feature UI
**Type:** Story
**Priority:** High
**Labels:** ui, feature, timer
**Depends on:** TT-005
**Blocks:**
---
## Summary
Implement the fully functional Timer screen. This is the primary screen of the
app — users will spend most of their time here.
## UI Specification
### TimerScreen layout
```
┌──────────────────────────────┐
│ AppBar: "Timer" │
├──────────────────────────────┤
│ │
│ [Project Picker Chip] │
│ │
│ 00:00:00 ← elapsed │
│ │
│ [Note TextField] │
│ │
│ ● START / ■ STOP │
│ │
│ [Discard] (only running) │
│ │
│ ── Recent entries ──────── │
│ Today: 2h 30m │
│ [ Entry 1 ] │
│ [ Entry 2 ] │
└──────────────────────────────┘
```
### Widgets to build
| Widget | File | Description |
|--------|------|-------------|
| `TimerScreen` | `timer_screen.dart` | Root screen |
| `TimerDisplay` | `widgets/timer_display.dart` | Large elapsed time counter `HH:MM:SS` |
| `TimerControls` | `widgets/timer_controls.dart` | Start/Stop/Discard FAB area |
| `ProjectPickerSheet` | `widgets/project_picker_sheet.dart` | BottomSheet to select project |
| `ProjectPickerChip` | `widgets/project_picker_chip.dart` | Tappable chip showing selected project |
| `TodaySummaryCard` | `widgets/today_summary_card.dart` | Total hours today |
## Behaviour
- On mount: `TimerNotifier.build()` already restores running state
- Elapsed display updates every second via `ref.watch(timerNotifierProvider)`
- Tapping project chip → opens `ProjectPickerSheet`
- START disabled if no project selected
- STOP saves entry; DISCARD deletes it
- "Recent entries" shows today's completed entries (last 5)
## Acceptance Criteria
- [ ] `TimerDisplay` shows `00:00:00` when idle, live elapsed when running
- [ ] Project chip is required before START is enabled
- [ ] Note field is editable while timer is running
- [ ] STOP → entry appears in recent list immediately (reactive stream)
- [ ] DISCARD shows confirmation dialog before deleting
- [ ] `TodaySummaryCard` updates when entries change
- [ ] Widget test: idle state renders START button
- [ ] Widget test: running state renders STOP + DISCARD buttons
- [ ] Widget test: tapping STOP calls `timerNotifier.stop()`
## Files to create / modify
- `lib/features/timer/presentation/timer_screen.dart` (replace stub)
- `lib/features/timer/presentation/widgets/timer_display.dart`
- `lib/features/timer/presentation/widgets/timer_controls.dart`
- `lib/features/timer/presentation/widgets/project_picker_chip.dart`
- `lib/features/timer/presentation/widgets/project_picker_sheet.dart`
- `lib/features/timer/presentation/widgets/today_summary_card.dart`
- `test/features/timer/timer_screen_test.dart`