Skip to content

Add Export to .ics#17

Open
Copilot wants to merge 2 commits into
mainfrom
copilot/impressed-mackerel
Open

Add Export to .ics#17
Copilot wants to merge 2 commits into
mainfrom
copilot/impressed-mackerel

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 13, 2026

Implements client-side export of all event group date ranges as a standard iCalendar (.ics) file, resolving issue #11.

Changes

  • src/utils/icsExport.ts — new utility with two exports:

    • generateIcsContent(eventGroups): builds a VCALENDAR string with one all-day VEVENT per DateRange per group (SUMMARY = group name; DTEND is exclusive per RFC 5545; group names escaped per RFC 5545 §3.3.11)
    • downloadIcsFile(content, filename?): triggers browser download as pocketcal.ics via a text/calendar Blob
  • src/components/Sidebar.tsx — adds "Export to .ics" button above "Go Pro" in footerGroups(); disabled when no groups have any ranges

  • src/components/icons/DownloadIcon.tsx — new icon following existing icon component conventions

// One VEVENT emitted per DateRange per EventGroup
lines.push(`SUMMARY:${escapeIcsText(group.name)}`);
lines.push(`DTSTART;VALUE=DATE:${dtstart}`);
lines.push(`DTEND;VALUE=DATE:${dtend}`); // exclusive: day after range.end

No new dependencies — uses date-fns (already in use) and nanoid (already in use) for date formatting and UID generation respectively.

Original prompt

Implement the plan in a new branch and make a pull request that fixes #11

**Chronological Review:** 1. User requested implementation of issue #11 - "Export to .ics" feature 2. Agent fetched GitHub issue #11 from cassidoo/pocketcal repo - confirmed it's about exporting calendar to .ics file 3. Agent launched background explore agent (agent-0) to analyze codebase 4. Agent read git remotes to find correct repo owner (cassidoo) 5. Agent read `src/store.ts` directly while waiting for explore agent 6. Explore agent completed - provided comprehensive analysis of the codebase 7. Agent read `src/components/Sidebar.tsx` in parallel 8. Agent created the plan file and SQL todos 9. Agent exited plan mode

Intent Mapping:

  • User wants "Export to .ics" button above "Go Pro" button in sidebar
  • Events in export: one per group's date ranges, title = group name, all-day events
  • This implements GitHub issue Add export to .ics #11

Technical Inventory:

  • React 19 + TypeScript + Vite project
  • Zustand state management
  • date-fns for date utilities
  • lz-string for URL compression
  • nanoid for IDs
  • Key data structures: EventGroup (id, name, color, ranges[]), DateRange (start, end as ISO strings)
  • No existing export utilities

Code Archaeology:

  • src/store.ts: Zustand store with EventGroup, DateRange interfaces; all state management
  • src/components/Sidebar.tsx: Contains footerGroups() function with proButton and helpAndCopyButtons
  • Go Pro button is in Sidebar.tsx line 116, inside footerGroups() function
  • Plan saved to: C:\Users\cassi\.copilot\session-state\62a1b4f0-ea87-4a9f-a58c-09a7a89ff6e1\plan.md

Progress Assessment:

  • Plan created ✅
  • SQL todos inserted ✅ (create-ics-util, add-sidebar-button with dependency)
  • Implementation NOT yet started

Context Validation:

  • All key file paths, data structures, and component details captured
  • Footer structure understood: proButton div + helpAndCopyButtons div; export button goes above proButton
  • iCal format details specified in plan

Recent Commands Analysis:

  • Last actions: created plan.md, inserted SQL todos, called exit_plan_mode
  • exit_plan_mode returned "Plan approved! Exited plan mode. Now in interactive mode"
  • User asked for summary - no additional implementation done yet
1. Conversation Overview: - Primary Objectives: Implement GitHub issue #11 — add an "Export to .ics" button above the "Go Pro" button in the sidebar that exports all selected date ranges as all-day calendar events, with each event titled after its group name. - Session Context: Planning phase only — agent explored the codebase, fetched the GitHub issue, created a structured plan file, inserted SQL todos, and exited plan mode. No implementation code has been written yet. - User Intent Evolution: User provided a clear, specific request (button placement, event title = group name, all-day events). No clarification was needed; agent proceeded directly to planning.
  1. Technical Foundation:

    • React 19 + TypeScript + Vite: Core framework and build tool for the pocketcal project at C:\Users\cassi\Documents\github\pocketcal
    • Zustand: State management library (src/store.ts); all app state is in one store accessed via useStore() hook
    • date-fns: Date utility library already in use (formatISO, parseISO, eachDayOfInterval, etc.)
    • nanoid: Already used for generating unique IDs (event group IDs); will be reused for iCal VEVENT UIDs
    • lz-string: URL compression for shareable links (not relevant to this feature)
    • iCalendar (.ics) format: Will be generated client-side as a string — no new npm packages needed
  2. Codebase Status:

    • src/store.ts:
      • Purpose: Single Zustand store containing all app state and actions
      • Current State: Unmodified; contains EventGroup/DateRange interfaces and all state logic
      • Key Code Segments:
        export interface DateRange {
          start: string; // ISO date string e.g. "2024-01-15"
          end: string;   // ISO date string e.g. "2024-01-20"
        }
        export interface EventGroup {
          id: string;
          name: string;   // This becomes SUMMARY in .ics
          color: string;
          ranges: DateRange[];
        }
        // State: eventGroups: EventGroup[], selectedGroupId: string | null
      • Dependencies: All components import from here via useStore()
    • src/components/Sidebar.tsx:
      • Purpose: Left sidebar panel containing event groups list, settings, and footer buttons
      • Current State: Unmodified; contains the Go Pro button that the export button must be placed above
      • Key Code Segments:
        const footerGroups = () => {
          let proButton = (
            <div className="sidebar-footer-buttons">
              <button className="footer-button" onClick={() => setShowLicenseModal(true)}>
                {isProUser ? "Thanks for going Pro!" : "Go Pro"}
              </button>
            </div>

...

Created from Copilot CLI via the copilot delegate command.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 13, 2026

Deploy Preview for pocketcal ready!

Name Link
🔨 Latest commit 3369af9
🔍 Latest deploy log https://app.netlify.com/projects/pocketcal/deploys/69b4960a3b70ab00087671c7
😎 Deploy Preview https://deploy-preview-17--pocketcal.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Co-authored-by: cassidoo <1454517+cassidoo@users.noreply.github.com>
Copilot AI changed the title [WIP] [11] Fix export to .ics feature in sidebar Add Export to .ics Mar 13, 2026
Copilot AI requested a review from cassidoo March 13, 2026 22:56
@cassidoo cassidoo marked this pull request as ready for review March 13, 2026 23:00
@github-actions
Copy link
Copy Markdown

This pull request is now considered stale! 😭

@github-actions github-actions Bot added the stale label May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add export to .ics

2 participants