import { z } from "zod"; export const projectTypeSchema = z.enum(["PORTFOLIO", "APP", "WEBSITE", "DESIGN"]); export const publishStatusSchema = z.enum(["DRAFT", "PUBLISHED", "ARCHIVED"]); const optionalText = (max: number) => z.string().trim().max(max).optional(); const optionalUrl = z.union([z.literal(""), z.string().trim().url().max(500)]).optional(); const mediaPath = z.string().trim().regex(/^\/api\/uploads\/(images|audios)\/[^/]+$/, "Use an uploaded media path."); const optionalMediaPath = z.union([z.literal(""), mediaPath]).optional(); export const projectSchema = z.object({ type: projectTypeSchema, slug: z .string() .trim() .min(1, "Slug is required.") .max(100, "Slug must be 100 characters or fewer.") .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Use lowercase letters, numbers, and hyphens only."), titleAr: z.string().trim().min(1, "Arabic title is required.").max(160), titleEn: z.string().trim().min(1, "English title is required.").max(160), summaryAr: optionalText(300), summaryEn: optionalText(300), descAr: optionalText(4000), descEn: optionalText(4000), coverImage: optionalMediaPath, images: z.array(mediaPath).max(50, "You can add up to 50 images."), technologies: z.array(z.string().trim().min(1).max(60)).max(30, "You can add up to 30 technologies."), externalUrl: optionalUrl, repoUrl: optionalUrl, platform: optionalText(120), appStoreUrl: optionalUrl, testflightUrl: optionalUrl, appVersion: optionalText(80), supportUrl: optionalUrl, appPrivacyUrl: optionalUrl, status: publishStatusSchema, isFeatured: z.boolean(), sortOrder: z.number().int().min(0).max(9999), categoryId: z.union([z.literal(""), z.string().cuid()]).optional(), }); export const projectIdSchema = z.string().cuid("Invalid project id."); export const projectTypeFilterSchema = projectTypeSchema; export type ProjectInput = z.infer; export type ProjectTypeFilter = z.infer;