add: Zod validation schemas for form data and refactor server actions to use them

This commit is contained in:
Rasmus Q
2026-03-16 10:56:58 +00:00
parent 51df2d5777
commit 6a7b254bd7
2 changed files with 79 additions and 86 deletions
+39
View File
@@ -90,3 +90,42 @@ export function sanitizeToken(token: string | null | undefined): string {
}
return trimmed;
}
// Zod schemas for type-safe form validation
import { z } from 'zod';
export const currencySchema = z.enum(['DKK', 'EUR', 'USD', 'SEK', 'NOK', 'GBP']);
export const itemSchema = z.object({
title: z.string().min(1, 'Title is required').max(255),
description: z.string().max(2000).optional().nullable(),
link: z.string().url('Invalid URL').optional().nullable(),
imageUrl: z.string().url('Invalid image URL').optional().nullable(),
price: z.coerce.number().nonnegative().optional().nullable(),
currency: currencySchema.default('DKK'),
color: z.string().optional().nullable(),
order: z.coerce.number().int().nonnegative().optional()
});
export const updateItemSchema = itemSchema.extend({
id: z.string().min(1, 'Item ID is required')
});
export const wishlistSchema = z.object({
title: z.string().min(1, 'Title is required').max(255),
description: z.string().max(2000).optional().nullable(),
color: z.string().optional().nullable(),
theme: z.string().optional().nullable().transform((val) => val || 'none'),
endDate: z.coerce.date().optional().nullable()
});
export const reorderSchema = z.array(
z.object({
id: z.string(),
order: z.number().int().nonnegative()
})
);
export type ItemFormData = z.infer<typeof itemSchema>;
export type UpdateItemFormData = z.infer<typeof updateItemSchema>;
export type WishlistFormData = z.infer<typeof wishlistSchema>;