import { z } from "zod/v4"; import { LIMITS } from "@/lib/limits"; import { VIBES } from "@/lib/vibe"; const optionalTrimmed = (max: number, label: string) => z.preprocess( (val) => { if (val == null) return undefined; const s = String(val).trim(); return s === "" ? undefined : s; }, z.string().max(max, `${label} maksimal ${max} karakter`).optional() ); const interestSchema = z .string() .trim() .min(2, "Minat minimal 2 karakter") .max( LIMITS.MAX_PROFILE_INTEREST_LENGTH, `Setiap minat maksimal ${LIMITS.MAX_PROFILE_INTEREST_LENGTH} karakter` ) .regex( /^[a-zA-Z0-9 \-]+$/, "Minat hanya boleh huruf, angka, spasi, atau strip" ); export const updateProfileSchema = z.object({ bio: optionalTrimmed(LIMITS.MAX_PROFILE_BIO_LENGTH, "Bio"), city: optionalTrimmed(LIMITS.MAX_PROFILE_CITY_LENGTH, "Kota"), instagram: z.preprocess( (val) => { if (val == null) return undefined; const s = String(val).trim().replace(/^@/, ""); return s === "" ? undefined : s; }, z .string() .max( LIMITS.MAX_PROFILE_INSTAGRAM_LENGTH, `Instagram maksimal ${LIMITS.MAX_PROFILE_INSTAGRAM_LENGTH} karakter` ) .regex( /^[a-zA-Z0-9._]+$/, "Username Instagram hanya boleh huruf, angka, titik, atau underscore" ) .optional() ), interests: z .array(interestSchema) .max( LIMITS.MAX_PROFILE_INTERESTS_COUNT, `Maksimal ${LIMITS.MAX_PROFILE_INTERESTS_COUNT} minat` ) .default([]), vibe: z.preprocess( (val) => { if (val == null) return undefined; const s = String(val).trim(); return s === "" ? undefined : s; }, z.enum([...VIBES]).optional() ), }); export type UpdateProfileInput = z.infer;