import { Handlers, PageProps } from 'fresh/server.ts'; import { FreshContextState } from '/lib/types.ts'; import { Calendar, CalendarEvent, CalendarEventModel, CalendarModel } from '/lib/models/calendar.ts'; import { convertFormDataToObject } from '/lib/utils/misc.ts'; import { updateIcs } from '/lib/utils/calendar.ts'; import { getFormDataField } from '/lib/form-utils.tsx'; import ViewCalendarEvent, { formFields } from '/islands/calendar/ViewCalendarEvent.tsx'; import { AppConfig } from '/lib/config.ts'; interface Data { calendarEvent: CalendarEvent; calendars: Calendar[]; error?: string; notice?: string; formData: Record; } export const handler: Handlers = { async GET(request, context) { if (!context.state.user) { return new Response('Redirect', { status: 303, headers: { 'Location': `/login` } }); } const calendarConfig = await AppConfig.getCalendarConfig(); if (!calendarConfig.enableCalDavServer) { throw new Error('CalDAV server is not enabled'); } let { calendarEventId } = context.params; const searchParams = new URL(request.url).searchParams; const calendarId = searchParams.get('calendarId') || undefined; if (!calendarId) { return new Response('Bad request', { status: 400 }); } // When editing a recurring event, we only allow the master if (calendarEventId.includes(':')) { calendarEventId = calendarEventId.split(':')[0]; } const calendarEvent = await CalendarEventModel.get(context.state.user.id, calendarId, calendarEventId); if (!calendarEvent) { return new Response('Not found', { status: 404 }); } const calendars = await CalendarModel.list(context.state.user.id); return await context.render({ calendarEvent, calendars, formData: {} }); }, async POST(request, context) { if (!context.state.user) { return new Response('Redirect', { status: 303, headers: { 'Location': `/login` } }); } const calendarConfig = await AppConfig.getCalendarConfig(); if (!calendarConfig.enableCalDavServer) { throw new Error('CalDAV server is not enabled'); } const { calendarEventId } = context.params; const searchParams = new URL(request.url).searchParams; const calendarId = searchParams.get('calendarId') || undefined; if (!calendarId) { return new Response('Bad request', { status: 400 }); } const calendarEvent = await CalendarEventModel.get(context.state.user.id, calendarId, calendarEventId); if (!calendarEvent) { return new Response('Not found', { status: 404 }); } const calendars = await CalendarModel.list(context.state.user.id); const formData = await request.formData(); const updateType = getFormDataField(formData, 'update-type') as 'raw' | 'ui'; calendarEvent.title = getFormDataField(formData, 'title'); calendarEvent.startDate = new Date(`${getFormDataField(formData, 'startDate')}:00.000Z`); calendarEvent.endDate = new Date(`${getFormDataField(formData, 'endDate')}:00.000Z`); calendarEvent.isAllDay = getFormDataField(formData, 'isAllDay') === 'true'; calendarEvent.status = getFormDataField(formData, 'status') as CalendarEvent['status']; calendarEvent.description = getFormDataField(formData, 'description') || undefined; calendarEvent.eventUrl = getFormDataField(formData, 'eventUrl') || undefined; calendarEvent.location = getFormDataField(formData, 'location') || undefined; calendarEvent.transparency = getFormDataField(formData, 'transparency') as CalendarEvent['transparency'] || 'opaque'; const rawIcs = getFormDataField(formData, 'ics'); try { if (!calendarEvent.title) { throw new Error(`Title is required.`); } formFields(calendarEvent, calendars, updateType).forEach((field) => { if (field.required) { const value = formData.get(field.name); if (!value) { throw new Error(`${field.label} is required`); } } }); let updatedIcs = ''; if (updateType === 'raw') { updatedIcs = rawIcs; } else if (updateType === 'ui') { if (!calendarEvent.title || !calendarEvent.startDate || !calendarEvent.endDate) { throw new Error(`Title, start date, and end date are required.`); } updatedIcs = updateIcs(calendarEvent.data || '', calendarEvent); } await CalendarEventModel.update(context.state.user.id, calendarEvent.url!, updatedIcs); return await context.render({ calendarEvent, calendars, notice: 'Event updated successfully!', formData: convertFormDataToObject(formData), }); } catch (error) { console.error(error); return await context.render({ calendarEvent, calendars, error: (error as Error).toString(), formData: convertFormDataToObject(formData), }); } }, }; export default function CalendarEventPage({ data }: PageProps) { return (
); }