import z from "zod/v3"; import { validateFile } from "~/features/file"; import { CoreSchema } from "./core.schema"; class UsersSchema extends CoreSchema { // Zod schema for validation create = z .object({ email: z.string().min(1, "Email là bắt buộc").email("Email không hợp lệ"), username: z .string() .min(1, "Tên đăng nhập là bắt buộc") .min(3, "Tên đăng nhập phải có ít nhất 3 ký tự") .regex( /^[a-zA-Z0-9_]+$/, "Tên đăng nhập chỉ được chứa chữ cái, số và dấu gạch dưới" ), first_name: z .string() .min(1, "Họ là bắt buộc") .min(2, "Họ phải có ít nhất 2 ký tự"), last_name: z .string() .min(1, "Tên là bắt buộc") .min(2, "Tên phải có ít nhất 2 ký tự"), phone: z .string() .optional() .refine((val) => !val || /^[0-9+\-\s()]+$/.test(val), { message: "Số điện thoại không hợp lệ", }), avatar: z .any() .optional() .refine( (file) => { if (!file) return true; if (!(file instanceof File)) return true; const error = validateFile(file); return error === null; }, { message: "File không hợp lệ. Chỉ chấp nhận ảnh dưới 2MB", } ), is_login_enabled: z.boolean().default(false), active: z.boolean().default(true), roles: z .array(z.string()) // .min(1, "Phải chọn ít nhất một vai trò") .default([]), password: z.string().optional(), }) .refine( (data) => { if ( data.is_login_enabled && (!data.password || data.password.length < 6) ) { return false; } return true; }, { message: "Mật khẩu phải có ít nhất 6 ký tự khi cho phép đăng nhập", path: ["password"], } ); update = z .object({ email: z.string().email("Email không hợp lệ").optional(), username: z .string() .min(3, "Tên đăng nhập phải có ít nhất 3 ký tự") .regex( /^[a-zA-Z0-9_]+$/, "Tên đăng nhập chỉ được chứa chữ cái, số và dấu gạch dưới" ) .optional(), first_name: z.string().min(2, "Họ phải có ít nhất 2 ký tự").optional(), last_name: z.string().min(2, "Tên phải có ít nhất 2 ký tự").optional(), phone: z .union([z.string({ message: "Số điện thoại không hợp lệ" }), z.null()]) .optional() .refine((val) => !val || /^[0-9+\-\s()]+$/.test(val), { message: "Số điện thoại không hợp lệ", }), avatar: z .any() .optional() .refine( (file) => { if (!file) return true; if (!(file instanceof File)) return true; const error = validateFile(file); return error === null; }, { message: "File không hợp lệ. Chỉ chấp nhận ảnh dưới 2MB", } ), is_login_enabled: z.boolean().optional(), active: z.boolean().optional(), roles: z.array(z.string()).optional(), password: z.string().optional(), }) .refine( (data) => { if ( data.is_login_enabled && data.password && data.password.length < 6 ) { return false; } return true; }, { message: "Mật khẩu phải có ít nhất 6 ký tự khi cho phép đăng nhập", path: ["password"], } ); } export const usersSchema = new UsersSchema(); // ✅ Cách đơn giản và đúng: export type EmployeeFormData = z.infer;