import { fail, redirect } from '@sveltejs/kit'; import type { Actions, PageServerLoad } from './$types'; import { requireUser } from '#lib/server/auth.js'; import { createShow, listShows, listShowTemplates } from '#lib/server/shows.js'; function berlinLocalToUtc(value: string): string | null { if (!value) return null; const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/.exec(value); if (!match) throw new Error('INVALID_TIMESTAMP'); const parts = match.slice(1).map(Number); const localMilliseconds = Date.UTC(parts[0], parts[1] - 1, parts[2], parts[3], parts[4]); let candidate = localMilliseconds; for (let attempt = 0; attempt < 2; attempt += 1) { const formatted = new Intl.DateTimeFormat('en-CA', { timeZone: 'Europe/Berlin', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).formatToParts(new Date(candidate)); const read = (type: Intl.DateTimeFormatPartTypes) => Number(formatted.find((part) => part.type === type)?.value); const represented = Date.UTC( read('year'), read('month') - 1, read('day'), read('hour'), read('minute') ); candidate += localMilliseconds - represented; } return new Date(candidate).toISOString(); } export const load: PageServerLoad = ({ locals }) => { requireUser(locals.user); return { shows: listShows(), templates: listShowTemplates() }; }; export const actions = { create: async ({ locals, request }) => { requireUser(locals.user); const data = await request.formData(); const title = String(data.get('title') || ''); const startsAt = String(data.get('startsAt') || ''); const templateId = String(data.get('templateId') || '') || null; let id: string; try { id = createShow({ title, startsAtUtc: berlinLocalToUtc(startsAt), templateId }).id; } catch (cause) { const code = cause instanceof Error ? cause.message : ''; if (code === 'INVALID_TITLE') { return fail(400, { error: 'Bitte einen Titel eingeben.', title, startsAt, templateId }); } if (code === 'INVALID_TIMESTAMP') { return fail(400, { error: 'Bitte einen gültigen Termin eingeben.', title, startsAt, templateId }); } return fail(400, { error: 'Die Sendung konnte nicht angelegt werden.', title, startsAt, templateId }); } redirect(303, `/sendungen/${id}`); } } satisfies Actions;