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:
@@ -0,0 +1,86 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import AdminModal from '$lib/components/admin/AdminModal.svelte';
|
||||
import ProfileFields from './ProfileFields.svelte';
|
||||
|
||||
type ActionResult = {
|
||||
success?: boolean;
|
||||
action?: string;
|
||||
error?: string;
|
||||
fieldErrors?: Record<string, string>;
|
||||
} | null;
|
||||
|
||||
let {
|
||||
open = false,
|
||||
onClose,
|
||||
form
|
||||
}: {
|
||||
open?: boolean;
|
||||
onClose?: () => void;
|
||||
form?: ActionResult;
|
||||
} = $props();
|
||||
|
||||
let formError = $state('');
|
||||
let fieldErrors = $state<Record<string, string>>({});
|
||||
let successMessage = $state('');
|
||||
let lastForm = $state<ActionResult>(null);
|
||||
|
||||
$effect(() => {
|
||||
if (open) {
|
||||
formError = '';
|
||||
fieldErrors = {};
|
||||
successMessage = '';
|
||||
}
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (!form || form === lastForm) return;
|
||||
lastForm = form;
|
||||
|
||||
if (form.success) {
|
||||
formError = '';
|
||||
fieldErrors = {};
|
||||
successMessage = 'Profile created';
|
||||
setTimeout(() => onClose?.(), 1200);
|
||||
} else {
|
||||
successMessage = '';
|
||||
formError = form.error ?? '';
|
||||
fieldErrors = form.fieldErrors ?? {};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<AdminModal title="Create Profile" {open} {onClose}>
|
||||
{#if successMessage}
|
||||
<div
|
||||
class="mb-4 rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-700"
|
||||
>
|
||||
{successMessage}
|
||||
</div>
|
||||
{/if}
|
||||
{#if formError}
|
||||
<div class="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600">
|
||||
{formError}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<form method="POST" action="?/upsert" use:enhance>
|
||||
<ProfileFields record={null} {fieldErrors} />
|
||||
|
||||
<div class="mt-6 flex justify-end gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onclick={onClose}
|
||||
class="rounded-md border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-50"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium text-white transition hover:bg-indigo-700"
|
||||
>
|
||||
Create Profile
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</AdminModal>
|
||||
Reference in New Issue
Block a user