import { fail, redirect } from '@sveltejs/kit'; import type { Actions, PageServerLoad } from './$types'; import { requireUser } from '#lib/server/auth.js'; import { createPiece, deletePieceTemplate, duplicatePiece, getPiece, listPieceTemplates, savePiece, setPieceArchived, setPieceDeleted, setPieceFavorite, uploadPieceImage, type EditablePieceStatus, type PieceEditor } from '#lib/server/content.js'; import { fundusSearch, loadFundusWorkspace } from '#lib/server/fundus-workspace.js'; export const load: PageServerLoad = ({ locals, url }) => { requireUser(locals.user); const workspace = loadFundusWorkspace(url); const selectedId = url.searchParams.get('selected') ?? workspace.pieces[0]?.id ?? ''; return { ...workspace, selectedPiece: workspace.pieces.some((piece) => piece.id === selectedId) ? getPiece(selectedId) : null, templates: listPieceTemplates() }; }; function preservedInput(piece: PieceEditor, data: FormData) { return { ...piece, title: String(data.get('title') || ''), summary: String(data.get('summary') || ''), status: String(data.get('status') || piece.status) as EditablePieceStatus, formatId: String(data.get('formatId') || '') || null, durationSeconds: Math.round(Number(data.get('durationMinutes')) * 60), intro: String(data.get('intro') || ''), moderationNotes: String(data.get('moderationNotes') || ''), topicIds: piece.topicIds, categoryIds: piece.categoryIds, sources: piece.sources, tools: piece.tools.map((tool) => ({ toolId: tool.toolId, workUrl: tool.workUrl, note: tool.note })) }; } function actionError(cause: unknown) { const code = cause instanceof Error ? cause.message : ''; if (code === 'CONFLICT') return 'Das Piece wurde inzwischen geändert. Bitte Seite neu laden.'; if (code === 'NOT_FOUND') return 'Das Piece wurde nicht gefunden.'; return 'Die Aktion konnte nicht ausgeführt werden.'; } export const actions = { create: async ({ locals, request, url }) => { requireUser(locals.user); const data = await request.formData(); let id: string; try { id = createPiece(String(data.get('template') || 'blank')); } catch (cause) { return fail(400, { intent: 'create', error: actionError(cause) }); } redirect(303, `/fundus/${id}${fundusSearch(url)}`); }, deleteTemplate: async ({ locals, request }) => { requireUser(locals.user); const data = await request.formData(); try { deletePieceTemplate(String(data.get('templateId') || ''), Number(data.get('revision'))); return { intent: 'deleteTemplate', success: 'Vorlage gelöscht.' }; } catch (cause) { return fail(409, { intent: 'deleteTemplate', error: actionError(cause) }); } }, duplicate: async ({ locals, request, url }) => { requireUser(locals.user); const data = await request.formData(); let id: string; try { id = await duplicatePiece(String(data.get('pieceId') || '')); } catch (cause) { return fail(400, { intent: 'duplicate', error: actionError(cause) }); } redirect(303, `/fundus/${id}${fundusSearch(url)}`); }, archive: async ({ locals, request }) => { requireUser(locals.user); const data = await request.formData(); try { setPieceArchived(String(data.get('pieceId') || ''), Number(data.get('revision')), true); return { intent: 'archive', success: 'Piece archiviert.' }; } catch (cause) { return fail(409, { intent: 'archive', error: actionError(cause) }); } }, favorite: async ({ locals, request }) => { requireUser(locals.user); const data = await request.formData(); try { setPieceFavorite(String(data.get('pieceId') || ''), data.get('favorite') === '1'); return { intent: 'favorite', success: 'Favorit aktualisiert.' }; } catch (cause) { return fail(404, { intent: 'favorite', error: actionError(cause) }); } }, delete: async ({ locals, request }) => { requireUser(locals.user); const data = await request.formData(); try { setPieceDeleted(String(data.get('pieceId') || ''), Number(data.get('revision')), true); return { intent: 'delete', success: 'Piece gelöscht. Bestehende Streamfassungen bleiben erhalten.' }; } catch (cause) { return fail(409, { intent: 'delete', error: actionError(cause) }); } }, quickSave: async ({ locals, request }) => { requireUser(locals.user); const data = await request.formData(); const id = String(data.get('pieceId') || ''); const piece = getPiece(id); if (!piece || piece.status === 'archived') return fail(404, { intent: 'quickSave', error: 'Das Piece wurde nicht gefunden.' }); try { const saved = savePiece(id, Number(data.get('revision')), preservedInput(piece, data)); return { intent: 'quickSave', success: 'Schnelländerungen gespeichert.', ...saved }; } catch (cause) { return fail(409, { intent: 'quickSave', error: actionError(cause) }); } }, quickUpload: async ({ locals, request }) => { requireUser(locals.user); const data = await request.formData(); const image = data.get('image'); if (!(image instanceof File)) return fail(400, { intent: 'quickUpload', error: 'Bitte ein Bild auswählen.' }); try { await uploadPieceImage( String(data.get('pieceId') || ''), Number(data.get('revision')), image, String(data.get('altText') || ''), false ); return { intent: 'quickUpload', success: 'Bild hochgeladen.' }; } catch (cause) { return fail(400, { intent: 'quickUpload', error: actionError(cause) }); } } } satisfies Actions;