admin: Superforms + Zod validation, three-address-defaults schema, profiles toast fix
- Add Superforms + Zod 4 for all admin form validation - Replace address isDefault with three separate boolean defaults (Mailing, Billing, Shipping) - Update profiles page with three-checkbox address form and toast improvements - Convert all admin page server actions to pass request directly to crud - Export superFormErrorsToFieldErrors helper for profiles server actions - Regenerate Prisma client for new schema fields
This commit is contained in:
@@ -14,7 +14,8 @@ export const load: PageServerLoad = async ({ params, parent }) => {
|
||||
where: { id: params.id },
|
||||
include: {
|
||||
solfeggioFrequency: true,
|
||||
category: { include: { parent: true } }
|
||||
category: { include: { parent: true } },
|
||||
subscriptionLevel: true
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -19,27 +19,35 @@
|
||||
</a>
|
||||
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold text-gray-900 dark:text-gray-100">{data.proclamation.name}</h1>
|
||||
<h1 class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||
{data.proclamation.name}
|
||||
</h1>
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">{categoryBreadcrumb}</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div class="rounded-lg border border-purple-200 bg-purple-50 px-4 py-2 dark:border-gray-700 dark:bg-gray-800">
|
||||
<div
|
||||
class="rounded-lg border border-purple-200 bg-purple-50 px-4 py-2 dark:border-gray-700 dark:bg-gray-800"
|
||||
>
|
||||
<p class="text-xs font-medium text-purple-600 dark:text-gray-400">Frequency</p>
|
||||
<p class="text-sm font-semibold text-purple-900 dark:text-gray-100">
|
||||
{data.proclamation.solfeggioFrequency.value} Hz —
|
||||
{data.proclamation.solfeggioFrequency.name}
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg border border-gray-200 bg-gray-50 px-4 py-2 dark:border-gray-700 dark:bg-gray-800">
|
||||
<p class="text-xs font-medium text-gray-500 dark:text-gray-400">Price</p>
|
||||
<div
|
||||
class="rounded-lg border border-gray-200 bg-gray-50 px-4 py-2 dark:border-gray-700 dark:bg-gray-800"
|
||||
>
|
||||
<p class="text-xs font-medium text-gray-500 dark:text-gray-400">Level</p>
|
||||
<p class="text-sm font-semibold text-gray-900 dark:text-gray-100">
|
||||
${data.proclamation.price.toFixed(2)}
|
||||
{data.proclamation.subscriptionLevel?.name ?? 'Standard'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="prose max-w-none rounded-lg border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-900 dark:prose-invert">
|
||||
<div
|
||||
class="prose max-w-none rounded-lg border border-gray-200 bg-white p-6 dark:border-gray-700 dark:bg-gray-900 dark:prose-invert"
|
||||
>
|
||||
{@html data.proclamation.content}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -21,9 +21,9 @@ describe('(protected)/admin/proclamations/[id] page server load', () => {
|
||||
it('throws 404 when proclamation is not found', async () => {
|
||||
findUnique.mockResolvedValue(null);
|
||||
|
||||
const err = await Promise.resolve(
|
||||
load({ params: { id: 'nonexistent' } } as any)
|
||||
).catch((e: unknown) => e);
|
||||
const err = await Promise.resolve(load({ params: { id: 'nonexistent' } } as any)).catch(
|
||||
(e: unknown) => e
|
||||
);
|
||||
expect(isHttpError(err, 404)).toBe(true);
|
||||
});
|
||||
|
||||
@@ -44,7 +44,8 @@ describe('(protected)/admin/proclamations/[id] page server load', () => {
|
||||
where: { id: 'proc-1' },
|
||||
include: {
|
||||
solfeggioFrequency: true,
|
||||
category: { include: { parent: true } }
|
||||
category: { include: { parent: true } },
|
||||
subscriptionLevel: true
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user