Files

5.9 KiB

Phase 9: Task Creation UX - Context

Gathered: 2026-03-18 Status: Ready for planning

## Phase Boundary

Rework the frequency picker from a flat grid of 10 preset ChoiceChips + hidden "Custom" mode into an intuitive "Every [N] [unit]" picker with quick-select shortcut chips. The picker is inherently freeform — no separate "Custom" mode. All existing interval types and calendar-anchored scheduling behavior must continue working. No new scheduling logic, no new DB columns, no new screens.

## Implementation Decisions

Picker layout

  • Shortcut chips first (compact row), then the "Every [N] [unit]" picker row below
  • Tapping a chip highlights it AND populates the picker row (bidirectional sync)
  • Editing the picker manually deselects any highlighted chip
  • Both always reflect the same value — single source of truth
  • The picker row is always visible, not hidden behind a "Custom" toggle

Number input

  • Keep the existing TextFormField with digit-only filter
  • Same pattern as the current custom interval input (TextFormField + FilteringTextInputFormatter.digitsOnly)
  • Minimum value: 1 (no max limit — if someone wants every 999 days, let them)
  • Text field centered, compact width (~60px as current)

Unit selector

  • Keep SegmentedButton with 3 units: Tage (days), Wochen (weeks), Monate (months)
  • No "years" unit — yearly is handled as 12 months in the picker
  • Consistent with existing SegmentedButton pattern used for effort level selector

Shortcut chips

  • 4 shortcut chips: Täglich, Wöchentlich, Alle 2 Wochen, Monatlich
  • No quarterly/yearly shortcut chips — users type 3/12 months via the freeform picker
  • Drop all other presets (every 2 days, every 3 days, every 2 months, every 6 months) — the freeform picker handles arbitrary intervals naturally
  • Chips use ChoiceChip widget (existing pattern)

Preset removal

  • Remove the entire FrequencyInterval.presets static list from being used in the UI
  • The 10-chip Wrap grid is fully replaced by 4 shortcut chips + freeform picker
  • The "Benutzerdefiniert" (Custom) chip is removed — the picker is inherently freeform
  • _isCustomFrequency boolean state is no longer needed

Edit mode behavior

  • When editing an existing task, match the stored interval to a shortcut chip if possible
  • Daily task → highlight "Täglich" chip, picker shows "Alle 1 Tage"
  • Weekly task → highlight "Wöchentlich" chip, picker shows "Alle 1 Wochen"
  • Biweekly → highlight "Alle 2 Wochen" chip, picker shows "Alle 2 Wochen"
  • Monthly → highlight "Monatlich" chip, picker shows "Alle 1 Monate"
  • Any other interval (e.g., every 5 days, quarterly, yearly) → no chip highlighted, picker filled with correct values

DB mapping

  • Shortcut chips map to existing IntervalType enum values (daily, weekly, biweekly, monthly)
  • Freeform days → IntervalType.everyNDays with the entered value
  • Freeform weeks → IntervalType.everyNDays with value * 7
  • Freeform months → IntervalType.everyNMonths with the entered value
  • Calendar-anchored behavior (anchorDay) preserved for month-based intervals
  • No changes to IntervalType enum, no new DB values, no migration needed

Claude's Discretion

  • Exact chip styling and spacing within the Wrap
  • Animation/transition when syncing chip ↔ picker
  • Whether the "Alle" prefix label is part of the picker row or omitted
  • How to handle the edge case where user clears the number field (empty → treat as 1)
  • l10n string changes needed for new/modified labels
## Specific Ideas
  • User consistently prefers simplicity across phases ("just keep it simple" — Phase 8 pattern)
  • The key UX improvement: no more hunting through 10 chips or finding a hidden "Custom" mode — the picker is always there and always works
  • 4 common shortcuts for one-tap convenience, freeform picker for everything else
  • The current _buildCustomFrequencyInput method is essentially what becomes the primary picker — it already has the right structure

<code_context>

Existing Code Insights

Reusable Assets

  • _buildCustomFrequencyInput() in task_form_screen.dart:279-326: Already implements "Alle [N] [Tage|Wochen|Monate]" row with TextFormField + SegmentedButton — this becomes the primary picker
  • _CustomUnit enum (task_form_screen.dart:511): Already has days/weeks/months — reuse directly
  • _customIntervalController (task_form_screen.dart:35): Already exists for the number input
  • _resolveFrequency() (task_form_screen.dart:378-415): Already handles custom unit → IntervalType mapping — core logic stays the same
  • _loadExistingTask() (task_form_screen.dart:55-101): Already has edit-mode loading logic with preset matching — needs rework for new chip set
  • FrequencyInterval.presets (frequency.dart:50-61): Static list of 10 presets — UI no longer iterates this, but the model class stays for backward compat

Established Patterns

  • ChoiceChip in Wrap for multi-option selection (current frequency chips)
  • SegmentedButton for unit/level selection (effort level, custom unit)
  • TextFormField with FilteringTextInputFormatter for numeric input
  • ConsumerStatefulWidget with setState for form state management
  • German l10n strings in app_de.arb via AppLocalizations

Integration Points

  • task_form_screen.dart: Primary file — rework _buildFrequencySelector() method, simplify state variables
  • frequency.dart: FrequencyInterval.presets list is no longer iterated in UI but may still be used elsewhere (templates) — check before removing
  • app_de.arb / app_localizations.dart: May need new/updated l10n keys for shortcut chip labels
  • template_picker_sheet.dart / task_templates.dart: Templates create tasks with specific IntervalType values — no changes needed since DB mapping unchanged

</code_context>

## Deferred Ideas

None — discussion stayed within phase scope


Phase: 09-task-creation-ux Context gathered: 2026-03-18