Files
sendewerk/src/routes/sendungen/+page.server.ts
T
2026-10-21 23:52:05 +02:00

75 lines
2.3 KiB
TypeScript

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;