listing-facebook/client/app/lib/schema/users.schema.ts

130 lines
3.9 KiB
TypeScript

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<typeof usersSchema.create>;