import { redirect } from '@sveltejs/kit'; import { createApiClient } from '$lib/api.server'; import type { components } from '$lib/generated/api'; type IncompleteDocumentDTO = components['schemas']['IncompleteDocumentDTO']; type StatsDTO = components['schemas']['StatsDTO']; type Document = components['schemas']['Document']; type SearchMatchData = components['schemas']['SearchMatchData']; export async function load({ url, fetch }) { const q = url.searchParams.get('q') || ''; const from = url.searchParams.get('from') || ''; const to = url.searchParams.get('to') || ''; const senderId = url.searchParams.get('senderId') || ''; const receiverId = url.searchParams.get('receiverId') || ''; const tags = url.searchParams.getAll('tag'); const VALID_SORTS = ['DATE', 'TITLE', 'SENDER', 'RECEIVER', 'UPLOAD_DATE'] as const; type ValidSort = (typeof VALID_SORTS)[number]; const rawSort = url.searchParams.get('sort') ?? 'DATE'; const sort: ValidSort = (VALID_SORTS as readonly string[]).includes(rawSort) ? (rawSort as ValidSort) : 'DATE'; const VALID_DIRS = ['asc', 'desc'] as const; type ValidDir = (typeof VALID_DIRS)[number]; const rawDir = url.searchParams.get('dir') ?? 'desc'; const dir: ValidDir = (VALID_DIRS as readonly string[]).includes(rawDir) ? (rawDir as ValidDir) : 'desc'; const tagQ = url.searchParams.get('tagQ') || ''; const isDashboard = !q && !from && !to && !senderId && !receiverId && !tags.length && !tagQ; const api = createApiClient(fetch); try { const [docsResult, personsResult] = await Promise.all([ isDashboard ? Promise.resolve(null) : api.GET('/api/documents/search', { params: { query: { q: q || undefined, from: from || undefined, to: to || undefined, senderId: senderId || undefined, receiverId: receiverId || undefined, tag: tags.length ? tags : undefined, tagQ: tagQ || undefined, sort, dir: dir || undefined } } }), api.GET('/api/persons') ]); if (personsResult.response.status === 401) { throw redirect(302, '/login'); } if (docsResult && docsResult.response.status === 401) { throw redirect(302, '/login'); } const searchResult = docsResult?.data as { documents?: Document[]; total?: number; matchData?: Record; } | null; const documents: Document[] = searchResult?.documents ?? []; const total: number = searchResult?.total ?? 0; const matchData: Record = searchResult?.matchData ?? {}; const allPersons = (personsResult.data ?? []) as { id: string; firstName: string; lastName: string; }[]; const senderObj = allPersons.find((p) => p.id === senderId); const receiverObj = allPersons.find((p) => p.id === receiverId); // Dashboard widgets — failures are isolated and don't crash the page let stats: StatsDTO | null = null; let incompleteDocs: IncompleteDocumentDTO[] = []; let recentDocs: Document[] = []; if (isDashboard) { const [statsResult, incompleteResult, recentResult] = await Promise.allSettled([ api.GET('/api/stats'), api.GET('/api/documents/incomplete', { params: { query: { size: 3 } } }), api.GET('/api/documents/recent-activity', { params: { query: { size: 5 } } }) ]); if (statsResult.status === 'fulfilled' && statsResult.value.response.ok) { stats = statsResult.value.data ?? null; } if (incompleteResult.status === 'fulfilled' && incompleteResult.value.response.ok) { incompleteDocs = incompleteResult.value.data ?? []; } if (recentResult.status === 'fulfilled' && recentResult.value.response.ok) { recentDocs = recentResult.value.data ?? []; } } return { isDashboard, documents, total, matchData, stats, incompleteDocs, recentDocs, initialValues: { senderName: senderObj?.displayName ?? '', receiverName: receiverObj?.displayName ?? '' }, filters: { q, from, to, senderId, receiverId, tags, sort, dir, tagQ }, error: null as string | null }; } catch (e) { if ((e as { status?: number }).status) throw e; console.error('Error loading data:', e); return { isDashboard, documents: [], total: 0, matchData: {} as Record, stats: null, incompleteDocs: [], recentDocs: [], initialValues: { senderName: '', receiverName: '' }, filters: { q, from, to, senderId, receiverId, tags, sort, dir, tagQ }, error: 'Daten konnten nicht geladen werden.' as string | null }; } }