94 lines
2.5 KiB
JavaScript
94 lines
2.5 KiB
JavaScript
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')
|
|
}
|