Files
fete/specs/009-list-events/tasks.md
nitrix e56998b17c
All checks were successful
CI / backend-test (push) Successful in 57s
CI / frontend-test (push) Successful in 22s
CI / frontend-e2e (push) Successful in 1m4s
CI / build-and-publish (push) Has been skipped
Add event list feature (009-list-events)
Enable users to see all their saved events on the home screen, sorted
by date with upcoming events first. Key capabilities:

- EventCard with title, relative time display, and organizer/attendee
  role badge
- Sortable EventList with past-event visual distinction (faded style)
- Empty state when no events are stored
- Swipe-to-delete gesture with confirmation dialog
- Floating action button for quick event creation
- Rename router param :token → :eventToken across all views
- useRelativeTime composable (Intl.RelativeTimeFormat)
- useEventStorage: add validation, removeEvent(), reactive versioning
- Full E2E and unit test coverage for all new components

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:53:55 +01:00

216 lines
11 KiB
Markdown
Raw Permalink 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.
# Tasks: Event List on Home Page
**Input**: Design documents from `/specs/009-list-events/`
**Prerequisites**: plan.md, spec.md, research.md, data-model.md
**Tests**: Unit tests (Vitest) and E2E tests (Playwright) are included per constitution (Principle II: Test-Driven Methodology).
**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 (Shared Infrastructure)
**Purpose**: Composable extensions and utility functions shared across all user stories
- [x] T000 Rename router param `:token` to `:eventToken` in `frontend/src/router/index.ts` and update all references in `EventDetailView.vue`, `EventStubView.vue`, and their test files (consistency with `StoredEvent.eventToken` field name)
- [x] T001 Add `isValidStoredEvent` type guard and validation filter to `frontend/src/composables/useEventStorage.ts` (FR-010)
- [x] T002 Add `removeEvent(eventToken: string)` function to `frontend/src/composables/useEventStorage.ts` (needed by US3)
- [x] T003 [P] Create `useRelativeTime` composable in `frontend/src/composables/useRelativeTime.ts` (Intl.RelativeTimeFormat wrapper, FR-002)
- [x] T004 [P] Add unit tests for `isValidStoredEvent` and `removeEvent` in `frontend/src/composables/__tests__/useEventStorage.spec.ts`
- [x] T005 [P] Create unit tests for `useRelativeTime` in `frontend/src/composables/__tests__/useRelativeTime.spec.ts`
**Checkpoint**: Composable layer complete — all shared logic tested and available for components.
---
## Phase 2: User Story 1 — View My Events (Priority: P1) 🎯 MVP
**Goal**: Home page shows all stored events in a sorted list with title and relative time. Tapping navigates to event detail.
**Independent Test**: Simulate localStorage entries, visit home page, verify all events appear sorted with correct titles and relative times. Tap an event and verify navigation to `/events/:eventToken`.
### Unit Tests for User Story 1
- [x] T006 [P] [US1] Create unit tests for EventCard component in `frontend/src/components/__tests__/EventCard.spec.ts` — include test cases for `isPast` prop (faded styling) and role badge rendering (organizer vs. attendee)
- [x] T007 [P] [US1] Create unit tests for EventList component in `frontend/src/components/__tests__/EventList.spec.ts`
### Implementation for User Story 1
- [x] T008 [P] [US1] Create `EventCard.vue` component in `frontend/src/components/EventCard.vue` — displays title, relative time, role badge; emits click for navigation
- [x] T009 [US1] Create `EventList.vue` component in `frontend/src/components/EventList.vue` — reads events from composable, validates, sorts (upcoming asc, past desc), renders EventCard list
- [x] T010 [US1] Refactor `HomeView.vue` in `frontend/src/views/HomeView.vue` — integrate EventList, conditionally show list when events exist
- [x] T011 [US1] Add event card and list styles to `frontend/src/assets/main.css`
### E2E Tests for User Story 1
- [x] T012 [US1] Create E2E test file `frontend/e2e/home-events.spec.ts` — tests: events displayed with title and relative time, sorted correctly, click navigates to detail page
**Checkpoint**: MVP complete — returning users see their events and can navigate to details.
---
## Phase 3: User Story 2 — Empty State (Priority: P2)
**Goal**: New users with no stored events see an inviting empty state with a "Create Event" call-to-action.
**Independent Test**: Clear localStorage, visit home page, verify empty state message and "Create Event" button are visible.
### Unit Tests for User Story 2
- [x] T013 [P] [US2] Create unit tests for EmptyState component in `frontend/src/components/__tests__/EmptyState.spec.ts`
### Implementation for User Story 2
- [x] T014 [US2] Create `EmptyState.vue` component in `frontend/src/components/EmptyState.vue` — shows message and "Create Event" RouterLink
- [x] T015 [US2] Update `HomeView.vue` in `frontend/src/views/HomeView.vue` — show EmptyState when no valid events, show EventList otherwise
- [x] T016 [US2] Add empty state styles to `frontend/src/assets/main.css`
### E2E Tests for User Story 2
- [x] T017 [US2] Add E2E tests to `frontend/e2e/home-events.spec.ts` — tests: empty state shown when no events, hidden when events exist
**Checkpoint**: Home page handles both new and returning users.
---
## Phase 4: User Story 4 — Past Events Appear Faded (Priority: P2)
**Goal**: Events whose date/time has passed appear with reduced visual prominence (muted colors, lower contrast) while remaining interactive.
**Independent Test**: Have both future and past events in localStorage, verify past events display faded while remaining clickable.
### Implementation for User Story 4
- [x] T018 [US4] Add `.event-card--past` modifier class with `opacity: 0.6; filter: saturate(0.5)` to `frontend/src/components/EventCard.vue` or `frontend/src/assets/main.css`
- [x] T019 [US4] Pass `isPast` computed property to EventCard in `EventList.vue` and apply modifier class in `frontend/src/components/EventCard.vue`
### E2E Tests for User Story 4
- [x] T020 [US4] Add E2E tests to `frontend/e2e/home-events.spec.ts` — tests: past events have faded class, upcoming events do not, past events remain clickable
**Checkpoint**: Visual hierarchy distinguishes upcoming from past events.
---
## Phase 5: User Story 3 — Remove Event from List (Priority: P3)
**Goal**: Users can remove events from their local list via delete icon (and later swipe) with confirmation.
**Independent Test**: Have multiple events, remove one via delete icon, verify it disappears while others remain.
### Unit Tests for User Story 3
- [x] T021 [P] [US3] Create unit tests for ConfirmDialog component in `frontend/src/components/__tests__/ConfirmDialog.spec.ts`
### Implementation for User Story 3
- [x] T022 [US3] Create `ConfirmDialog.vue` component in `frontend/src/components/ConfirmDialog.vue` — teleport-to-body modal with confirm/cancel, focus trapping, Escape key
- [x] T023 [US3] Add delete icon button to `EventCard.vue` in `frontend/src/components/EventCard.vue` — emits `delete` event with eventToken (FR-006a)
- [x] T024 [US3] Wire delete flow in `EventList.vue` in `frontend/src/components/EventList.vue` — listen for delete event, show ConfirmDialog, call `removeEvent()` on confirm
- [x] T025 [US3] Add delete icon and confirm dialog styles to `frontend/src/assets/main.css`
### E2E Tests for User Story 3
- [x] T026 [US3] Add E2E tests to `frontend/e2e/home-events.spec.ts` — tests: delete icon visible, confirmation dialog appears, confirm removes event, cancel keeps event
**Checkpoint**: Users can manage their event list.
---
## Phase 6: User Story 5 — Visual Distinction for Event Roles (Priority: P3)
**Goal**: Events show a badge indicating whether the user is the organizer or an attendee.
**Independent Test**: Have events with organizerToken and rsvpToken in localStorage, verify different badges displayed.
### Implementation for User Story 5
- [x] T027 [US5] Add role badge (Organizer/Attendee) to `EventCard.vue` in `frontend/src/components/EventCard.vue` — derive from organizerToken/rsvpToken presence
- [x] T028 [US5] Add role badge styles to `frontend/src/assets/main.css`
### E2E Tests for User Story 5
- [x] T029 [US5] Add E2E tests to `frontend/e2e/home-events.spec.ts` — tests: organizer badge shown for events with organizerToken, attendee badge for events with rsvpToken only
**Checkpoint**: Role distinction visible at a glance.
---
## Phase 7: Polish & Cross-Cutting Concerns
**Purpose**: FAB, swipe gesture, accessibility, and final polish
- [x] T030 Create `CreateEventFab.vue` in `frontend/src/components/CreateEventFab.vue` — fixed FAB at bottom-right, navigates to `/create` (FR-011)
- [x] T031 Add FAB to `HomeView.vue` in `frontend/src/views/HomeView.vue` — visible when events exist (empty state has its own CTA)
- [x] T032 Add FAB styles to `frontend/src/assets/main.css`
- [x] T033 Implement swipe-to-delete gesture on EventCard in `frontend/src/components/EventCard.vue` — native Touch API (FR-006b)
- [x] T034 Accessibility review: verify ARIA labels, keyboard navigation (Tab/Enter/Escape), focus trapping in ConfirmDialog, WCAG AA contrast on faded cards
- [x] T035 Add E2E tests for FAB to `frontend/e2e/home-events.spec.ts` — tests: FAB visible when events exist, navigates to create page
---
## Dependencies & Execution Order
### Phase Dependencies
- **Phase 1 (Setup)**: No dependencies — start immediately
- **Phase 2 (US1)**: Depends on T001, T003 (validation + relative time composable)
- **Phase 3 (US2)**: Depends on T001 (validation); can run in parallel with US1
- **Phase 4 (US4)**: Depends on Phase 2 completion (EventCard must exist)
- **Phase 5 (US3)**: Depends on Phase 2 completion (EventList must exist) + T002 (removeEvent)
- **Phase 6 (US5)**: Depends on Phase 2 completion (EventCard must exist)
- **Phase 7 (Polish)**: Depends on Phases 26 completion
### User Story Dependencies
- **US1 (P1)**: Depends only on Phase 1 — no other story dependencies
- **US2 (P2)**: Depends only on Phase 1 — independent of US1 but shares HomeView
- **US4 (P2)**: Depends on US1 (extends EventCard with past styling)
- **US3 (P3)**: Depends on US1 (extends EventList with delete flow)
- **US5 (P3)**: Depends on US1 (extends EventCard with role badge)
### Parallel Opportunities
- T003 + T004 + T005 can all run in parallel (different files)
- T006 + T007 can run in parallel (different test files)
- T008 can run in parallel with T006/T007 (component vs test files)
- US4, US5 can start in parallel once US1 is done (both extend EventCard independently)
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup composables
2. Complete Phase 2: US1 — EventCard, EventList, HomeView refactor
3. **STOP and VALIDATE**: Test the event list end-to-end
4. Deploy/demo if ready
### Incremental Delivery
1. Phase 1 → Composable layer ready
2. Phase 2 (US1) → Event list works → MVP!
3. Phase 3 (US2) → Empty state for new users
4. Phase 4 (US4) → Past events faded
5. Phase 5 (US3) → Remove events from list
6. Phase 6 (US5) → Role badges
7. Phase 7 → FAB, swipe, accessibility polish
---
## Notes
- [P] tasks = different files, no dependencies
- [Story] label maps task to specific user story for traceability
- This is a **frontend-only** feature — no backend changes needed
- All data comes from existing `useEventStorage` composable (localStorage)
- E2E tests consolidated in single file `home-events.spec.ts` with separate `describe` blocks per story