import { db } from '$lib/server/db'; import { character, devilFruit, arc, type Status } from '$lib/server/db/schema'; import { eq, sql } from 'drizzle-orm'; import { fail } from '@sveltejs/kit'; import type { PageServerLoad, Actions } from './$types'; // Helper function to normalize data (parse JSON arrays) const normalizeArray = (value: any): any => { if (!value) return value; if (Array.isArray(value)) return value; if (typeof value === 'string' && value.includes('[')) { try { return JSON.parse(value); } catch { return value; } } return value; }; export const load: PageServerLoad = async () => { let [characters, devilFruits, arcs, statusesData, gendersData] = await Promise.all([ db .select({ id: character.id, name: character.name, gender: character.gender, age: character.age, affiliations: normalizeArray(character.affiliations), devilFruitId: character.devilFruitId, hakiObservation: character.hakiObservation, hakiArmament: character.hakiArmament, hakiConqueror: character.hakiConqueror, bounty: character.bounty, height: character.height, origin: character.origin, firstAppearance: character.firstAppearance, pictureUrl: character.pictureUrl, epithets: normalizeArray(character.epithets), status: character.status, url: character.url, arcId: character.arcId, isInDailyMode: character.isInDailyMode, arcName: arc.name, devilFruitName: devilFruit.name, devilFruitType: devilFruit.type }) .from(character) .leftJoin(arc, eq(character.arcId, arc.id)) .leftJoin(devilFruit, eq(character.devilFruitId, devilFruit.id)) .orderBy(character.name), db.select().from(devilFruit).orderBy(devilFruit.name), db.select().from(arc).orderBy(arc.name), db.selectDistinct({ status: character.status }) .from(character) .where(sql`${character.status} IS NOT NULL AND ${character.status} != ''`), db.selectDistinct({ gender: character.gender }) .from(character) .where(sql`${character.gender} IS NOT NULL AND ${character.gender} != ''`) ]); return { characters, devilFruits, arcs, availableStatuses: statusesData .map(s => s.status) .filter((s): s is Status => !!s) .sort((a, b) => a.localeCompare(b)), availableGenders: gendersData .map(g => g.gender) .filter((g): g is string => !!g) .sort((a, b) => a.localeCompare(b)) }; }; export const actions: Actions = { delete: async ({ request, locals }) => { if (!locals.user?.isAdmin) { return fail(401, { error: 'Unauthorized' }); } const formData = await request.formData(); const id = formData.get('id') as string; if (!id) { return fail(400, { error: 'Character ID is required' }); } try { await db.delete(character).where(eq(character.id, id)); return { success: true }; } catch (error) { console.error('Character delete error:', error); return fail(500, { error: 'Failed to delete character' }); } }, toggleDailyMode: async ({ request, locals }) => { if (!locals.user?.isAdmin) { return fail(401, { error: 'Unauthorized' }); } const formData = await request.formData(); const id = formData.get('id') as string; const isInDailyMode = formData.get('isInDailyMode') === 'true'; if (!id) { return fail(400, { error: 'Character ID is required' }); } try { await db.update(character) .set({ isInDailyMode }) .where(eq(character.id, id)); return { success: true }; } catch (error) { console.error('Toggle daily mode error:', error); return fail(500, { error: 'Failed to toggle daily mode' }); } } };