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,60 +1,128 @@
|
||||
<script lang="ts">
|
||||
import Window from '$lib/components/containers/Window.svelte';
|
||||
import { authClient } from '$lib/auth-client';
|
||||
import { resolve } from '$app/paths';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { form }: PageProps = $props();
|
||||
</script>
|
||||
|
||||
<Window>
|
||||
<div class="dark:text-gray-100">
|
||||
{#if form?.success}
|
||||
<div class="mx-auto max-w-md text-center">
|
||||
<div
|
||||
class="rounded-lg border border-green-200 bg-green-50 p-6 text-green-700 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300"
|
||||
>
|
||||
<p class="text-lg font-medium">Account created!</p>
|
||||
<p class="mt-2">
|
||||
We've sent a verification email. Check your inbox and click the link to verify your
|
||||
email address, then log in.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-col items-start justify-center">
|
||||
{#if form?.error}
|
||||
<div
|
||||
class="mb-4 w-full rounded-lg border border-red-200 bg-red-50 p-3 text-red-700 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300"
|
||||
>
|
||||
{form.error}
|
||||
</div>
|
||||
{/if}
|
||||
<form method="POST" class="flex flex-col items-start">
|
||||
<input type="text" name="firstName" placeholder="First Name" required class="mb-2" />
|
||||
<input type="text" name="lastName" placeholder="Last Name" required class="mb-2" />
|
||||
<input type="email" name="email" placeholder="Email Address" required class="mb-2" />
|
||||
<input type="password" name="password" placeholder="Password" required class="mb-2" />
|
||||
<input
|
||||
type="password"
|
||||
name="password2"
|
||||
placeholder="Verify Password"
|
||||
required
|
||||
class="mb-2"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
class="mx-auto rounded-full bg-blue-600 px-6 py-2 text-white dark:bg-gray-700 dark:text-gray-100"
|
||||
>Submit</button
|
||||
>
|
||||
</form>
|
||||
<p class=" mx-auto my-6 text-center">Or</p>
|
||||
<button
|
||||
class="mx-auto"
|
||||
onclick={async () => {
|
||||
await authClient.signIn.social({ provider: 'google', callbackURL: '/account/setup' });
|
||||
}}><img src="light/web_light_sq_SU.svg" alt="Sign Up with Google" /></button
|
||||
>
|
||||
{#if form?.success}
|
||||
<div class="rounded-lg bg-green-50 px-4 py-6 text-center">
|
||||
<h1 class="text-xl font-bold text-slate-900">Account created!</h1>
|
||||
<p class="mt-3 text-sm text-slate-600">
|
||||
We've sent a verification email. Check your inbox and click the link to verify your email
|
||||
address, then log in.
|
||||
</p>
|
||||
<a
|
||||
href={resolve('/login')}
|
||||
class="mt-6 inline-flex h-11 items-center justify-center rounded-lg bg-indigo-600 px-6 text-sm font-medium text-white hover:bg-indigo-700"
|
||||
>
|
||||
Go to Login
|
||||
</a>
|
||||
</div>
|
||||
{:else}
|
||||
{#if form?.error}
|
||||
<div class="mb-4 rounded-lg bg-red-50 px-4 py-3 text-sm text-red-700" role="alert">
|
||||
{form.error}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<form method="POST" class="flex flex-col gap-4">
|
||||
<h1 class="text-2xl font-bold text-slate-900">Create Account</h1>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label for="firstName" class="text-sm font-medium text-slate-700"> First Name </label>
|
||||
<input
|
||||
id="firstName"
|
||||
type="text"
|
||||
name="firstName"
|
||||
placeholder="First Name"
|
||||
required
|
||||
class="h-11 w-full rounded-lg border-slate-300 px-3 text-sm text-slate-900 focus:border-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label for="lastName" class="text-sm font-medium text-slate-700"> Last Name </label>
|
||||
<input
|
||||
id="lastName"
|
||||
type="text"
|
||||
name="lastName"
|
||||
placeholder="Last Name"
|
||||
required
|
||||
class="h-11 w-full rounded-lg border-slate-300 px-3 text-sm text-slate-900 focus:border-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label for="email" class="text-sm font-medium text-slate-700"> Email Address </label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="Email Address"
|
||||
required
|
||||
class="h-11 w-full rounded-lg border-slate-300 px-3 text-sm text-slate-900 focus:border-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label for="password" class="text-sm font-medium text-slate-700"> Password </label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
required
|
||||
class="h-11 w-full rounded-lg border-slate-300 px-3 text-sm text-slate-900 focus:border-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-1.5">
|
||||
<label for="password2" class="text-sm font-medium text-slate-700"> Verify Password </label>
|
||||
<input
|
||||
id="password2"
|
||||
type="password"
|
||||
name="password2"
|
||||
placeholder="Verify Password"
|
||||
required
|
||||
class="h-11 w-full rounded-lg border-slate-300 px-3 text-sm text-slate-900 focus:border-indigo-500 focus:ring-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="mt-1 flex h-11 w-full items-center justify-center rounded-lg bg-indigo-600 text-base font-medium text-white hover:bg-indigo-700"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-6 border-t border-slate-200 pt-6">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="h-px flex-1 bg-slate-200"></div>
|
||||
<span class="text-sm text-slate-500">Or</span>
|
||||
<div class="h-px flex-1 bg-slate-200"></div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onclick={async () => {
|
||||
await authClient.signIn.social({ provider: 'google', callbackURL: '/account/setup' });
|
||||
}}
|
||||
class="mt-4 flex h-11 w-full items-center justify-center rounded-lg border border-slate-300 bg-white hover:bg-slate-50"
|
||||
>
|
||||
<img src="light/web_light_sq_SU.svg" alt="Sign Up with Google" class="h-6" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="mt-6 text-center text-sm text-slate-500">
|
||||
Already have an account?
|
||||
<a href={resolve('/login')} class="font-medium text-indigo-600 hover:text-indigo-700">
|
||||
Login
|
||||
</a>
|
||||
</p>
|
||||
{/if}
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user