58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { z } from "zod/v4";
|
|
import { LIMITS } from "@/lib/limits";
|
|
|
|
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([]),
|
|
});
|
|
|
|
export type UpdateProfileInput = z.infer<typeof updateProfileSchema>;
|