Files
nitrix a52d0cd1d3
All checks were successful
CI / backend-test (push) Successful in 58s
CI / frontend-test (push) Successful in 23s
CI / frontend-e2e (push) Successful in 1m9s
CI / build-and-publish (push) Has been skipped
Add temporal grouping to event list (Today/This Week/Next Week/Later/Past)
Group events into five temporal sections with section headers, date subheaders,
and context-aware time display (clock time for upcoming, relative for past).
Includes new useEventGrouping composable, SectionHeader and DateSubheader
components, full unit and E2E test coverage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 17:26:58 +01:00

9.6 KiB

Tasks: Event List Temporal Grouping

Input: Design documents from /specs/010-event-list-grouping/ Prerequisites: plan.md, spec.md, research.md, data-model.md

Tests: Included — spec.md references TDD (Constitution II), and research.md explicitly plans unit + E2E test updates.

Organization: Tasks are grouped by user story to enable independent implementation and testing of each story.

Format: [ID] [P?] [Story] Description

  • [P]: Can run in parallel (different files, no dependencies)
  • [Story]: Which user story this task belongs to (e.g., US1, US2, US3)
  • Include exact file paths in descriptions

Phase 1: Setup

Purpose: No new project setup needed — this is a frontend-only enhancement to an existing codebase. Phase 1 is empty.

(No tasks — existing project structure is sufficient.)


Phase 2: Foundational (Blocking Prerequisites)

Purpose: Create the core grouping composable and its types — all user stories depend on this logic.

CRITICAL: No user story work can begin until this phase is complete.

  • T001 Define SectionKey, EventSection, and DateGroup types in frontend/src/composables/useEventGrouping.ts
  • T002 Implement useEventGrouping composable with section classification, date grouping, and sorting logic in frontend/src/composables/useEventGrouping.ts
  • T003 Write unit tests for useEventGrouping covering all four sections, empty-section omission, sort order, and Sunday edge case in frontend/src/components/__tests__/useEventGrouping.spec.ts

Checkpoint: Grouping logic is fully tested and ready for consumption by UI components.


Phase 3: User Story 1 — Temporal Section Headers (Priority: P1) MVP

Goal: Events appear grouped under "Today", "This Week", "Later", and "Past" section headers. Empty sections are hidden.

Independent Test: Add events with various dates to localStorage, verify they appear under correct section headers.

Tests for User Story 1

NOTE: Write these tests FIRST, ensure they FAIL before implementation

  • T004 [P] [US1] Write unit tests for SectionHeader.vue rendering section label and emphasis flag in frontend/src/components/__tests__/SectionHeader.spec.ts
  • T005 [P] [US1] Update EventList.spec.ts tests to expect grouped section structure instead of flat list in frontend/src/components/__tests__/EventList.spec.ts

Implementation for User Story 1

  • T006 [P] [US1] Create SectionHeader.vue component with section label (<h2>) and aria-label in frontend/src/components/SectionHeader.vue
  • T007 [US1] Refactor EventList.vue template to use useEventGrouping, render <section> per temporal group with SectionHeader, and hide empty sections in frontend/src/components/EventList.vue
  • T008 [US1] Update E2E tests in home-events.spec.ts to verify section headers appear with correct events distributed across "Today", "This Week", "Later", "Past" in frontend/e2e/home-events.spec.ts

Checkpoint: Event list shows temporal section headers. All four acceptance scenarios pass.


Phase 4: User Story 2 — Date Subheaders Within Sections (Priority: P2)

Goal: Within each section (except "Today"), events are further grouped by date with formatted subheaders like "Wed, 12 Mar".

Independent Test: Add multiple events on different days within one section, verify date subheaders appear.

Tests for User Story 2

NOTE: Write these tests FIRST, ensure they FAIL before implementation

  • T009 [P] [US2] Write unit tests for DateSubheader.vue rendering formatted date label in frontend/src/components/__tests__/DateSubheader.spec.ts
  • T010 [P] [US2] Add unit tests to EventList.spec.ts verifying date subheaders appear within sections and are absent in "Today" in frontend/src/components/__tests__/EventList.spec.ts

Implementation for User Story 2

  • T011 [P] [US2] Create DateSubheader.vue component with formatted date (<h3>) using Intl.DateTimeFormat in frontend/src/components/DateSubheader.vue
  • T012 [US2] Update EventList.vue template to render DateSubheader within each section's date groups, skipping subheader for "Today" section (showSubheader flag) in frontend/src/components/EventList.vue
  • T013 [US2] Add E2E test scenarios for date subheaders: multiple days within a section, no subheader in "Today" in frontend/e2e/home-events.spec.ts

Checkpoint: Date subheaders render correctly within sections. "Today" section has no subheader.


Phase 5: User Story 3 — Enhanced Event Card Time Display (Priority: P2)

Goal: Event cards show clock time ("18:30") in Today/This Week/Later sections and relative time ("3 days ago") in Past section.

Independent Test: Check event cards display the correct time format based on which section they appear in.

Tests for User Story 3

NOTE: Write these tests FIRST, ensure they FAIL before implementation

  • T014 [P] [US3] Add unit tests to EventCard.spec.ts for timeDisplayMode prop: 'clock' renders formatted time, 'relative' renders relative time in frontend/src/components/__tests__/EventCard.spec.ts

Implementation for User Story 3

  • T015 [US3] Add timeDisplayMode prop ('clock' | 'relative') to EventCard.vue, render clock time via Intl.DateTimeFormat({ hour: '2-digit', minute: '2-digit' }) or existing formatRelativeTime() in frontend/src/components/EventCard.vue
  • T016 [US3] Update EventList.vue to pass timeDisplayMode="clock" for today/thisWeek/later sections and timeDisplayMode="relative" for past section in frontend/src/components/EventList.vue
  • T017 [US3] Add E2E test scenarios verifying clock time in future sections and relative time in past section in frontend/e2e/home-events.spec.ts

Checkpoint: Time display adapts to section context. All three acceptance scenarios pass.


Phase 6: User Story 4 — Today Section Visual Emphasis (Priority: P3)

Goal: The "Today" section header is visually more prominent (bolder, slightly larger, accent border) than other sections.

Independent Test: Visual verification that "Today" stands out compared to other section headers.

  • T018 [US4] Add .section--today CSS class to SectionHeader.vue with font-weight: 800, font-size: 1.1rem, and left border accent (#F06292) — triggered by emphasized prop in frontend/src/components/SectionHeader.vue
  • T019 [US4] Verify EventList.vue passes emphasized: true for the "Today" section (already set via EventSection.emphasized from data model) in frontend/src/components/EventList.vue
  • T020 [US4] Add visual E2E assertion checking that the "Today" section header has the emphasis CSS class applied in frontend/e2e/home-events.spec.ts

Checkpoint: "Today" section is visually distinct. Past events remain faded.


Phase 7: Polish & Cross-Cutting Concerns

Purpose: Final validation and regression checks.

  • T021 Run full unit test suite (cd frontend && npm run test:unit) and fix any regressions
  • T022 Run full E2E test suite and verify all existing functionality (swipe-to-delete, role badges, empty state, navigation) still works in frontend/e2e/home-events.spec.ts
  • T023 Verify accessibility: section headers are <h2>, date subheaders are <h3>, sections have aria-label, keyboard navigation works

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): Empty — no work needed
  • Foundational (Phase 2): No dependencies — can start immediately
  • US1 (Phase 3): Depends on Phase 2 (grouping composable)
  • US2 (Phase 4): Depends on Phase 3 (needs section structure in EventList)
  • US3 (Phase 5): Depends on Phase 3 (needs section context for time mode)
  • US4 (Phase 6): Depends on Phase 3 (needs SectionHeader component)
  • Polish (Phase 7): Depends on all user stories being complete

User Story Dependencies

  • US1 (P1): Can start after Foundational — no dependencies on other stories
  • US2 (P2): Depends on US1 (needs section structure in template to add subheaders)
  • US3 (P2): Depends on US1 (needs section context to determine time mode), independent of US2
  • US4 (P3): Depends on US1 (needs SectionHeader component), independent of US2/US3

Parallel Opportunities

  • Phase 2: T001 must precede T002; T003 can run after T002
  • Phase 3: T004 and T005 in parallel; T006 in parallel with tests; T007 after T006
  • Phase 4: T009 and T010 in parallel; T011 in parallel with tests; T012 after T011
  • Phase 5: T014 can start as soon as US1 is done; T015 after T014; T016 after T015
  • Phase 6: T018 can run in parallel with Phase 5 (different files)
  • US3 and US4 can run in parallel after US1 completes

Parallel Example: After US1 Completes

# These can run in parallel (different files, no dependencies):
Task: T009 [US2] Write DateSubheader unit tests
Task: T014 [US3] Write EventCard time mode unit tests
Task: T018 [US4] Add .section--today CSS to SectionHeader.vue

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 2: Foundational (grouping composable + tests)
  2. Complete Phase 3: User Story 1 (section headers in EventList)
  3. STOP and VALIDATE: Test US1 independently
  4. Deploy/demo if ready — list is already grouped with headers

Incremental Delivery

  1. Phase 2 → Grouping logic ready
  2. Add US1 → Section headers visible → Deploy/Demo (MVP!)
  3. Add US2 → Date subheaders within sections → Deploy/Demo
  4. Add US3 → Context-aware time display → Deploy/Demo
  5. Add US4 → Visual polish for "Today" → Deploy/Demo
  6. Each story adds value without breaking previous stories