Files
fete/specs/009-list-events/spec.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

11 KiB

Feature Specification: Event List on Home Page

Feature Branch: 009-list-events Created: 2026-03-08 Status: Draft Input: User description: "man kann auf der hauptseite eine liste an events sehen, sofern sie im localstorage gespeichert sind"

User Scenarios & Testing (mandatory)

User Story 1 - View My Events (Priority: P1)

As a returning user, I want to see a list of events I have previously created or interacted with (RSVP'd to) on the home page, so I can quickly navigate back to them without needing to remember or bookmark individual event links.

The home page displays all events stored in the browser's local storage. Each event entry shows the event title and date/time. Tapping an event navigates to its detail page.

Why this priority: This is the core value of the feature — without the list, the home page remains a dead end for returning users.

Independent Test: Can be fully tested by creating an event (or simulating localStorage entries), returning to the home page, and verifying all stored events appear in a list with correct titles and dates.

Acceptance Scenarios:

  1. Given the user has 3 events stored in localStorage, When they visit the home page, Then all 3 events are displayed in a list showing title and date/time for each.
  2. Given the user has events stored in localStorage, When they tap on an event in the list, Then they are navigated to the event detail page (/events/:eventToken).
  3. Given the user has events stored in localStorage, When they visit the home page, Then events are sorted by date/time (nearest upcoming event first, past events last).

User Story 2 - Empty State (Priority: P2)

As a new user with no stored events, I see an inviting empty state on the home page that encourages me to create my first event or explains how to get started.

Why this priority: First-time users need clear guidance. The empty state is the first impression for new users.

Independent Test: Can be tested by clearing localStorage and visiting the home page — the empty state message and "Create Event" call-to-action should be visible.

Acceptance Scenarios:

  1. Given no events are stored in localStorage, When the user visits the home page, Then an empty state message is displayed (e.g., "No events yet") with a prominent "Create Event" button.
  2. Given the user has at least one event stored, When they visit the home page, Then the empty state message is not shown — the event list is displayed instead.

User Story 3 - Remove Event from List (Priority: P3)

As a user, I want to remove an event from my personal list so I can keep my home page tidy and only show events I still care about.

Why this priority: Housekeeping capability. Without removal, the list grows indefinitely and becomes cluttered over time.

Independent Test: Can be tested by having multiple events in localStorage, removing one from the list, and verifying it disappears from the home page while the others remain.

Acceptance Scenarios:

  1. Given the user has events in their list, When they tap the delete icon on an event card, Then a confirmation prompt appears asking if they are sure. 1b. Given the user has events in their list, When they swipe an event card to the left, Then a confirmation prompt appears asking if they are sure.
  2. Given the confirmation prompt is shown, When the user confirms removal, Then the event is removed from localStorage and disappears from the list immediately.
  3. Given the confirmation prompt is shown, When the user cancels, Then the event remains in the list unchanged.

User Story 4 - Past Events Appear Faded (Priority: P2)

As a user, I want events whose date/time has passed to appear visually faded or muted in the list, so I can immediately focus on upcoming events without past events cluttering my attention.

The fading should feel modern and polished — not a blunt grey-out, but a subtle reduction in contrast and saturation that makes past events recede visually while remaining readable and tappable.

Why this priority: Without this, past and upcoming events look identical, making the list harder to scan. This is essential for usability once a user has accumulated several events.

Independent Test: Can be tested by having both future and past events in localStorage and verifying that past events display with reduced visual prominence while remaining interactive.

Acceptance Scenarios:

  1. Given the user has a past event (dateTime before now) in localStorage, When they view the home page, Then the event appears with reduced visual prominence (muted colors, lower contrast) compared to upcoming events.
  2. Given the user has a past event in the list, When they tap on it, Then it still navigates to the event detail page — it remains fully interactive.
  3. Given the user has both past and upcoming events, When they view the home page, Then upcoming events appear first (full visual prominence), followed by past events (faded), creating a clear visual hierarchy.

User Story 5 - Visual Distinction for Event Roles (Priority: P3)

As a user, I want to see at a glance whether I am the organizer of an event or just an attendee, so I can quickly identify my responsibilities.

Why this priority: Nice-to-have clarity. The data is already available in localStorage (presence of organizerToken), so surfacing it improves usability at low effort.

Independent Test: Can be tested by having both created events (with organizerToken) and RSVP'd events (with rsvpToken) in localStorage, and verifying they display different visual indicators.

Acceptance Scenarios:

  1. Given the user has a created event (organizerToken present) in localStorage, When they view the home page, Then the event shows a visual indicator marking them as the organizer (e.g., a badge or label).
  2. Given the user has an event with an RSVP (rsvpToken present, no organizerToken) in localStorage, When they view the home page, Then the event shows a visual indicator marking them as an attendee.

Edge Cases

  • What happens when localStorage data is corrupted or contains invalid entries? Events with missing required fields (eventToken, title, dateTime) are silently excluded from the list.
  • What happens when localStorage is unavailable (e.g., private browsing with storage disabled)? The empty state is shown with the "Create Event" button — the app remains functional.
  • What happens when an event's date/time has passed? The event remains in the list but appears visually faded.
  • What happens when the user has a very large number of stored events (e.g., 50+)? The list scrolls naturally. No pagination is needed at this scale since localStorage entries are lightweight.

Requirements (mandatory)

Functional Requirements

  • FR-001: System MUST display a list of all events stored in the browser's local storage on the home page.
  • FR-002: Each event entry MUST show the event title and the event date/time displayed as a relative time label (e.g., "in 3 days", "yesterday") using Intl.RelativeTimeFormat.
  • FR-003: Each event entry MUST be tappable/clickable and navigate to the event detail page (/events/:eventToken).
  • FR-004: Events MUST be sorted by date/time with nearest upcoming events first and past events last.
  • FR-005: System MUST display an empty state with a "Create Event" call-to-action when no events are stored.
  • FR-006a: Users MUST be able to remove individual events from their local list via a visible delete icon on each event card (primary mechanism, implemented first).
  • FR-006b: Users MUST be able to remove individual events via swipe-to-delete gesture (secondary mechanism, implemented separately after FR-006a).
  • FR-007: System MUST show a confirmation prompt before removing an event from the list.
  • FR-008: System MUST visually distinguish events where the user is the organizer from events where the user is an attendee.
  • FR-009: System MUST display past events (dateTime before current time) with reduced visual prominence — muted colors and lower contrast — while keeping them readable and interactive.
  • FR-010: System MUST gracefully handle corrupted or incomplete localStorage entries by excluding invalid events from the list.
  • FR-011: The "Create Event" button MUST remain accessible on the home page even when events are listed, implemented as a Floating Action Button (FAB) fixed at the bottom-right corner.

Key Entities

  • Stored Event: A locally persisted reference to an event the user has interacted with. Contains: event token (unique identifier for navigation), title, date/time, expiry date, and optionally an organizer token (if created by this user) or RSVP token and name (if the user RSVP'd).

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: Users can see all their stored events on the home page within 1 second of page load.
  • SC-002: Users can navigate from the home page to any event detail page in a single tap/click.
  • SC-003: Users can remove an unwanted event from their list in under 3 seconds (including confirmation).
  • SC-004: New users (no stored events) see a clear call-to-action to create their first event.
  • SC-005: Users can distinguish their role (organizer vs. attendee) for each event at a glance without opening the event.

Clarifications

Session 2026-03-08

  • Q: How does the user trigger event removal? → A: Two mechanisms — visible delete icon on each event card (primary, implemented first) and swipe-to-delete gesture (secondary, implemented separately after).
  • Q: Placement of "Create Event" button when events exist? → A: Floating Action Button (FAB) fixed at bottom-right corner.
  • Q: Date/time display format in event list? → A: Relative time labels ("in 3 days", "yesterday") via Intl.RelativeTimeFormat.

Assumptions

  • The existing useEventStorage composable and StoredEvent interface provide all necessary data for the event list (no backend API calls needed for listing).
  • The event list is purely client-side — there is no server-side "my events" endpoint. Privacy is preserved because events are only known to the user's browser.
  • The event list uses Intl.RelativeTimeFormat for relative time labels (FR-002), while the event detail view uses Intl.DateTimeFormat for absolute date/time display. Both use the browser's locale (navigator.language).
  • The "Create Event" flow (spec 006) already saves events to localStorage, so no changes to event creation are needed.
  • The RSVP flow (spec 008) already saves RSVP data to localStorage, so no changes to RSVP are needed.