# 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
