import { redirect } from '@sveltejs/kit'; import type { Actions, PageServerLoad } from './$types'; import { listBookSlugs, listTranslationJobs, type TranslationJob } from '$lib/server/pocketbase'; import { backendFetch } from '$lib/server/scraper'; import { log } from '$lib/server/logger'; export const load: PageServerLoad = async ({ locals }) => { if (locals.user?.role !== 'admin') { redirect(302, '/'); } // Stream jobs — navigation is instant, list populates shortly after. const jobs = listTranslationJobs().catch((e): TranslationJob[] => { log.warn('admin/translation', 'failed to load translation jobs', { err: String(e) }); return []; }); // Books list is needed immediately for the enqueue form, but use cache so // it's fast on repeat visits. const books = await listBookSlugs().catch((e): Awaited> => { log.warn('admin/translation', 'failed to load book slugs', { err: String(e) }); return []; }); return { books, jobs }; }; export const actions: Actions = { bulk: async ({ request, locals }) => { if (locals.user?.role !== 'admin') { return { success: false, error: 'Unauthorized' }; } const form = await request.formData(); const slug = form.get('slug')?.toString().trim() ?? ''; const lang = form.get('lang')?.toString().trim() ?? ''; const from = parseInt(form.get('from')?.toString() ?? '1', 10); const to = parseInt(form.get('to')?.toString() ?? '1', 10); if (!slug || !lang) { return { success: false, error: 'slug and lang are required' }; } if (isNaN(from) || isNaN(to) || from < 1 || to < from) { return { success: false, error: 'Invalid chapter range' }; } try { const res = await backendFetch('/api/admin/translation/bulk', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ slug, lang, from, to }) }); if (!res.ok) { const body = await res.text().catch(() => ''); log.error('admin/translation', 'bulk enqueue failed', { status: res.status, body }); return { success: false, error: `Backend error ${res.status}: ${body}` }; } const data = await res.json(); return { success: true, enqueued: data.enqueued as number }; } catch (e) { log.error('admin/translation', 'bulk enqueue fetch error', { err: String(e) }); return { success: false, error: String(e) }; } } };