# Tasks: iCal Download **Input**: Design documents from `/specs/019-ical-download/` **Prerequisites**: plan.md, spec.md **Tests**: TDD is mandated by the project constitution. Tests are written first and must fail before implementation. **Organization**: Single user story (US1). Foundational phase covers the two pure utility modules; US1 phase covers component integration. ## 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) - Include exact file paths in descriptions --- ## Phase 1: Foundational (Pure Utilities) **Purpose**: iCal generation and slug utility — pure functions with no UI dependencies ### Tests (RED) - [x] T001 [P] Write unit tests for slugify (umlaut transliteration, special chars, max length, empty input) in `frontend/src/utils/__tests__/slugify.spec.ts` - [x] T002 [P] Write unit tests for iCal generation (required fields, optional LOCATION/DESCRIPTION omission, UTF-8 text escaping, UID format, deterministic output, DTSTAMP) in `frontend/src/composables/__tests__/useIcalDownload.spec.ts` ### Implementation (GREEN) - [x] T003 Implement slugify utility in `frontend/src/utils/slugify.ts` — ASCII transliteration (ä→ae, ü→ue, ö→oe, ß→ss), lowercase, non-ASCII removal, hyphens for spaces/special chars, collapse consecutive hyphens, max 60 chars - [x] T004 Implement `generateIcs()` function and `useIcalDownload()` composable in `frontend/src/composables/useIcalDownload.ts` — RFC 5545 VEVENT with UID (`{eventToken}@fete`), DTSTAMP, DTSTART (UTC), SUMMARY, SEQUENCE:0, optional LOCATION/DESCRIPTION, Blob download with `text/calendar` MIME type, slugified filename **Checkpoint**: `npm run test:unit` passes — both utilities work in isolation --- ## Phase 2: User Story 1 — Download event as calendar file (Priority: P1) 🎯 MVP **Goal**: Calendar icon button in the bottom action bar for all user roles (attendee pre-RSVP, attendee post-RSVP, organizer). Tap triggers `.ics` download. Not shown for cancelled events. **Independent Test**: View any active event → tap calendar button → `.ics` file downloads → opens in calendar app. ### Tests (RED) - [x] T005 Write E2E test for calendar download button in `frontend/e2e/ical-download.spec.ts` — verify button visible for pre-RSVP visitor, post-RSVP attendee, and organizer; verify button NOT visible for cancelled event; verify download triggers with correct filename ### Implementation (GREEN) - [x] T006 [US1] Add calendar button and `calendar` emit to RsvpBar in `frontend/src/components/RsvpBar.vue` — pre-RSVP state: glow-border + glass-inner icon button after CTA; post-RSVP state: glassmorphic icon button right of status bar - [x] T007 [US1] Add calendar button for organizer view in `frontend/src/views/EventDetailView.vue` — fixed bottom position next to existing "Cancel event" button, consistent glassmorphic styling - [x] T008 [US1] Wire calendar download handler in `frontend/src/views/EventDetailView.vue` — import `useIcalDownload`, call on `@calendar` emit from RsvpBar and on organizer button click, pass event data **Checkpoint**: All acceptance scenarios pass — any user on an active event can download a valid `.ics` file with 1 tap --- ## Phase 3: Polish & Cross-Cutting Concerns - [ ] T009 Verify calendar button layout does not disrupt existing RsvpBar on 320px–768px viewports (visual check via `browser-interactive-testing` skill) --- ## Dependencies & Execution Order ### Phase Dependencies - **Foundational (Phase 1)**: No dependencies — can start immediately - **US1 (Phase 2)**: Depends on Phase 1 completion (T003, T004 must be done) - **Polish (Phase 3)**: Depends on Phase 2 completion ### Within Phases - T001 and T002 are parallel (different files) - T003 before T004 (`useIcalDownload` imports `slugify`) - T005 can be written before T006–T008 (TDD: test fails first) - T006 and T007 are parallel (different files) - T008 depends on T006 and T007 (wires them together) ### Parallel Opportunities ```text # Phase 1 tests (parallel): T001: slugify unit tests T002: iCal generation unit tests # Phase 2 implementation (parallel after T005): T006: RsvpBar calendar button T007: Organizer calendar button ``` --- ## Implementation Strategy ### MVP (Single Pass) 1. Complete Phase 1: Write tests → implement slugify → implement iCal generation 2. Complete Phase 2: Write E2E → add buttons to RsvpBar + organizer view → wire handler 3. Complete Phase 3: Visual verification 4. **DONE**: Single user story, single deliverable --- ## Notes - No backend changes required — all client-side - Zero new dependencies — hand-rolled iCal generation - `generateIcs()` must be a pure function (deterministic, no side effects) for easy testing - `useIcalDownload()` wraps `generateIcs()` + Blob download trigger - Calendar SVG icon: use a calendar outline matching the existing date/time meta icon style