import { connectDB } from '../../utils/mongoose.js' import Event from '../../models/event' export default defineEventHandler(async (event) => { await connectDB() const member = await requireAuth(event) try { const events = await Event.find({ 'registrations.memberId': member._id, isCancelled: { $ne: true }, }) .select('title slug description startDate endDate location') .sort({ startDate: 1 }) const ical = generateICalendar(events, member) setHeader(event, 'Content-Type', 'text/calendar; charset=utf-8') setHeader(event, 'Cache-Control', 'no-cache, no-store, must-revalidate') setHeader(event, 'Pragma', 'no-cache') setHeader(event, 'Expires', '0') return ical } catch (error) { console.error('Error generating calendar:', error) if (error.statusCode) { throw error } throw createError({ statusCode: 500, statusMessage: 'Failed to generate calendar', }) } }) function generateICalendar(events, member) { const now = new Date() const timestamp = now .toISOString() .replace(/[-:]/g, '') .replace(/\.\d{3}/, '') let ical = [ 'BEGIN:VCALENDAR', 'VERSION:2.0', 'PRODID:-//Ghost Guild//Events Calendar//EN', 'CALSCALE:GREGORIAN', 'METHOD:PUBLISH', 'X-WR-CALNAME:Ghost Guild - My Events', 'X-WR-TIMEZONE:UTC', 'X-WR-CALDESC:Your registered Ghost Guild events', 'REFRESH-INTERVAL;VALUE=DURATION:PT1H', 'X-PUBLISHED-TTL:PT1H', ] events.forEach((evt) => { const eventStart = new Date(evt.startDate) const eventEnd = new Date(evt.endDate) const dtstart = eventStart .toISOString() .replace(/[-:]/g, '') .replace(/\.\d{3}/, '') const dtend = eventEnd .toISOString() .replace(/[-:]/g, '') .replace(/\.\d{3}/, '') const dtstamp = timestamp const description = (evt.description || '') .replace(/\n/g, '\\n') .replace(/,/g, '\\,') const eventUrl = `https://ghostguild.org/events/${evt.slug || evt._id}` ical.push('BEGIN:VEVENT') ical.push(`UID:${evt._id}@ghostguild.org`) ical.push(`DTSTAMP:${dtstamp}`) ical.push(`DTSTART:${dtstart}`) ical.push(`DTEND:${dtend}`) ical.push(`SUMMARY:${evt.title}`) ical.push(`DESCRIPTION:${description}\\n\\nView event: ${eventUrl}`) ical.push(`LOCATION:${evt.location || 'Online'}`) ical.push(`URL:${eventUrl}`) ical.push('STATUS:CONFIRMED') ical.push('END:VEVENT') }) ical.push('END:VCALENDAR') return ical.join('\r\n') }