Rebuild admin pages around DataTable/AdminModal; restructure categories/groups and v2 groups API
Remove the generic $lib/svelte-admin CRUD layer and AdminTable.svelte; each admin route now owns its own form/modal logic. Add DataTable.svelte, superform-errors.ts, and profile-specific modal/field components. Flatten proclamation categories/groups and drop subscription levels; add the v2 groups API; update v1/v2 endpoints, serializers, auth, and regenerated Prisma client with the new migrations. Document the overhaul plan in docs/ADMIN_OVERHAUL.md.
This commit is contained in:
@@ -1,18 +1,70 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { getModelConfig } from '$lib/svelte-admin/registry';
|
||||
import { loadRecords, upsertRecord, deleteRecord } from '$lib/svelte-admin/crud';
|
||||
import { prisma } from '$lib/db';
|
||||
import { superValidate } from 'sveltekit-superforms/server';
|
||||
import { zod4 } from 'sveltekit-superforms/adapters';
|
||||
import { z } from 'zod';
|
||||
import { superFormErrorsToFieldErrors } from '$lib/superform-errors';
|
||||
|
||||
const config = getModelConfig('solfeggio-frequencies')!;
|
||||
const SolfeggioSchema = z.object({
|
||||
name: z.string().min(1, 'Required').max(100, 'Too long'),
|
||||
value: z.coerce.number().int().min(1, 'Value must be a positive integer')
|
||||
});
|
||||
|
||||
export const load: PageServerLoad = async ({ locals }) => {
|
||||
return loadRecords(locals, config);
|
||||
export const load: PageServerLoad = async () => {
|
||||
const records = await prisma.solfeggioFrequency.findMany({ orderBy: { id: 'asc' } });
|
||||
return { records: records as unknown as Record<string, unknown>[] };
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
upsert: async ({ request, locals }) => {
|
||||
return upsertRecord(request, config, locals);
|
||||
upsert: async ({ request }) => {
|
||||
const formData = await request.formData();
|
||||
const form = await superValidate(formData, zod4(SolfeggioSchema));
|
||||
if (!form.valid) {
|
||||
const { error: formError, fieldErrors } = superFormErrorsToFieldErrors(
|
||||
form.errors as Record<string, unknown>
|
||||
);
|
||||
return { success: false, action: 'upsert', error: formError, fieldErrors };
|
||||
}
|
||||
|
||||
const rawId = formData.get('id')?.toString();
|
||||
const data = { name: form.data.name, value: form.data.value };
|
||||
|
||||
try {
|
||||
if (rawId) {
|
||||
await prisma.solfeggioFrequency.update({ where: { id: Number(rawId) }, data });
|
||||
} else {
|
||||
await prisma.solfeggioFrequency.create({ data });
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
if (e && typeof e === 'object' && 'code' in e && (e as { code: string }).code === 'P2002') {
|
||||
return {
|
||||
success: false,
|
||||
action: 'upsert',
|
||||
error: 'A frequency with that name or value already exists.'
|
||||
};
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
return { success: true, action: 'upsert' };
|
||||
},
|
||||
delete: async ({ request, locals }) => {
|
||||
return deleteRecord(request, config, locals);
|
||||
delete: async ({ request }) => {
|
||||
const formData = await request.formData();
|
||||
const rawId = formData.get('id')?.toString();
|
||||
if (!rawId) return { success: false, error: 'Missing id' };
|
||||
|
||||
try {
|
||||
await prisma.solfeggioFrequency.delete({ where: { id: Number(rawId) } });
|
||||
} catch (e: unknown) {
|
||||
if (e && typeof e === 'object' && 'code' in e && (e as { code: string }).code === 'P2003') {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Cannot delete: this frequency is used by proclamations.'
|
||||
};
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
return { success: true, action: 'delete' };
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user