import { useSignal } from '@preact/signals'; import { Calendar, CalendarEvent } from '/lib/types.ts'; import { capitalizeWord, convertObjectToFormData } from '/lib/utils/misc.ts'; import { FormField, generateFieldHtml } from '/lib/form-utils.tsx'; import { RequestBody as DeleteRequestBody, ResponseBody as DeleteResponseBody, } from '/routes/api/calendar/delete-event.tsx'; interface ViewCalendarEventProps { initialCalendarEvent: CalendarEvent; calendars: Calendar[]; formData: Record; error?: string; notice?: string; } export function formFields(calendarEvent: CalendarEvent, calendars: Calendar[]) { const fields: FormField[] = [ { name: 'title', label: 'Title', type: 'text', placeholder: 'Dentis', value: calendarEvent.title, required: true, }, { name: 'calendar_id', label: 'Calendar', type: 'select', value: calendarEvent.calendar_id, options: calendars.map((calendar) => ({ label: calendar.name, value: calendar.id })), required: true, }, { name: 'start_date', label: 'Start date', type: 'datetime-local', value: new Date(calendarEvent.start_date).toISOString().substring(0, 16), required: true, }, { name: 'end_date', label: 'End date', type: 'datetime-local', value: new Date(calendarEvent.end_date).toISOString().substring(0, 16), required: true, }, { name: 'is_all_day', label: 'All-day?', type: 'checkbox', placeholder: 'YYYYMMDD', value: 'true', required: false, checked: calendarEvent.is_all_day, }, { name: 'status', label: 'Status', type: 'select', value: calendarEvent.status, options: (['scheduled', 'pending', 'canceled'] as CalendarEvent['status'][]).map((status) => ({ label: capitalizeWord(status), value: status, })), required: true, }, { name: 'description', label: 'Description', type: 'textarea', placeholder: 'Just a regular check-up.', value: calendarEvent.extra.description, required: false, }, { name: 'url', label: 'URL', type: 'url', placeholder: 'https://example.com', value: calendarEvent.extra.url, required: false, }, { name: 'location', label: 'Location', type: 'text', placeholder: 'Birmingham, UK', value: calendarEvent.extra.location, required: false, }, // TODO: More fields, transparency, attendees, recurrence ]; return fields; } export default function viewCalendarEvent( { initialCalendarEvent, calendars, formData: formDataObject, error, notice }: ViewCalendarEventProps, ) { const isDeleting = useSignal(false); const calendarEvent = useSignal(initialCalendarEvent); const formData = convertObjectToFormData(formDataObject); async function onClickDeleteEvent() { if (confirm('Are you sure you want to delete this event?')) { if (isDeleting.value) { return; } isDeleting.value = true; try { const requestBody: DeleteRequestBody = { calendarIds: calendars.map((calendar) => calendar.id), calendarView: 'day', calendarStartDate: new Date().toISOString().substring(0, 10), calendarEventId: calendarEvent.value.id, calendarId: calendarEvent.value.calendar_id, }; const response = await fetch(`/api/calendar/delete-event`, { method: 'POST', body: JSON.stringify(requestBody), }); const result = await response.json() as DeleteResponseBody; if (!result.success) { throw new Error('Failed to delete event!'); } window.location.href = '/calendar'; } catch (error) { console.error(error); } isDeleting.value = false; } } return ( <>
View calendar
{error ? (

Failed to update!

{error}

) : null} {notice ? (

Success!

{notice}

) : null}
{formFields(calendarEvent.peek(), calendars).map((field) => generateFieldHtml(field, formData))}
{isDeleting.value ? ( <> Deleting... ) : null} {!isDeleting.value ? <>  : null}
); }