import { z } from 'zod' const CommunicationBarrierSchema = z .enum(['YA', 'TIDAK'], { required_error: 'Mohon lengkapi Status Hambatan Berkomunikasi', }) .transform((val) => val === 'YA') const IsNewBornSchema = z .enum(['YA', 'TIDAK'], { required_error: 'Mohon lengkapi status pasien', }) .transform((val) => val === 'YA') const ACCEPTED_UPLOAD_TYPES = ['image/jpeg', 'image/png', 'application/pdf'] const PatientSchema = z .object({ // Data Diri Pasien identityNumber: z.string().optional(), // .string({ // required_error: 'Mohon lengkapi NIK', // }) // .min(16, 'NIK harus berupa angka 16 digit') // .regex(/^\d+$/, 'NIK harus berupa angka 16 digit'), residentIdentityFile: z .any() .optional() .refine((f) => !f || f instanceof File, { message: 'Harus berupa file yang valid' }) .refine((f) => !f || ACCEPTED_UPLOAD_TYPES.includes(f.type), { message: 'Format file harus JPG, PNG, atau PDF', }) .refine((f) => !f || f.size <= 1 * 1024 * 1024, { message: 'Maksimal 1MB' }), familyIdentityFile: z .any() .optional() .refine((f) => !f || f instanceof File, { message: 'Harus berupa file yang valid' }) .refine((f) => !f || ACCEPTED_UPLOAD_TYPES.includes(f.type), { message: 'Format file harus JPG, PNG, atau PDF', }) .refine((f) => !f || f.size <= 1 * 1024 * 1024, { message: 'Maksimal 1MB' }), // .refine(f => ['image/jpeg', 'image/png'].includes(f.type), 'Hanya JPG/PNG') // Informasi Dasar // alias: z.string({ // required_error: 'Mohon pilih sapaan', // }), fullName: z.string({ required_error: 'Mohon lengkapi Nama', }), birthPlace: z .string({ required_error: 'Mohon lengkapi Tempat Lahir', }) .min(1, 'Mohon lengkapi Tempat Lahir'), birthDate: z .string({ required_error: 'Mohon lengkapi Tanggal Lahir', }) .refine( (date) => { // Jika kosong, return false untuk required validation if (!date || date.trim() === '') return false // Jika ada isi, validasi format tanggal try { const dateObj = new Date(date) // Cek apakah tanggal valid dan tahun >= 1900 return !isNaN(dateObj.getTime()) && dateObj.getFullYear() >= 1900 } catch { return false } }, { message: 'Mohon lengkapi Tanggal Lahir dengan format yang valid', }, ) .transform((dateStr) => new Date(dateStr).toISOString()), // Jenis Kelamin & Status gender: z.string({ required_error: 'Pilih Jenis Kelamin', }), maritalStatus: z.enum(['TIDAK_DIKETAHUI', 'BELUM_KAWIN', 'KAWIN', 'CERAI_HIDUP', 'CERAI_MATI'], { required_error: 'Pilih Status Perkawinan', }), // Informasi Lokasi & Sosial job: z .string({ required_error: 'Mohon lengkapi Pekerjaan', }) .min(1), nationality: z.string({ required_error: 'Pilih Kebangsaan', }), isNewBorn: IsNewBornSchema, language: z.string({ required_error: 'Mohon pilih Preferensi Bahasa', }), education: z .string({ required_error: 'Mohon lengkapi Pendidikan', }) .min(1), religion: z .string({ required_error: 'Pilih Kepercayaan', }) .min(1), ethnicity: z.string().optional(), // Disabilitas disability: z.enum(['YA', 'TIDAK'], { required_error: 'Mohon lengkapi Status Disabilitas', }), disabilityType: z.string().optional(), // Informasi Kontak passportNumber: z.string().optional(), communicationBarrier: CommunicationBarrierSchema, note: z.string().optional(), drivingLicenseNumber: z.string().optional(), }) .refine( (data) => { // Jika disability = 'TIDAK', maka disabilityType harus kosong atau undefined if (data.disability === 'TIDAK') { return !data.disabilityType || data.disabilityType.trim() === '' } return true }, { message: "Jenis Disabilitas harus kosong jika Status Disabilitas = 'TIDAK'", path: ['disabilityType'], }, ) .refine( (data) => { // Jika disability = 'YA', maka disabilityType wajib diisi if (data.disability === 'YA') { return !!data.disabilityType?.trim() } return true }, { message: 'Mohon pilih Jenis Disabilitas', path: ['disabilityType'], }, ) // .refine((data) => { // // Jika nationality = 'WNA', maka passportNumber wajib diisi // if (data.nationality === 'WNA') { // return !!data.passportNumber?.trim() // } // return true // }, { // message: 'Nomor Paspor wajib diisi untuk Warga Negara Asing', // path: ['passportNumber'], // }) .transform((data) => { // Transform untuk backend: hanya kirim disabilityType sesuai kondisi return { ...data, // Jika disability = 'YA', kirim disabilityType // Jika disability = 'TIDAK', kirim null untuk disabilityType disabilityType: data.disability === 'YA' ? data.disabilityType : null, // Hapus field disability karena yang dikirim ke backend adalah disabilityType disability: undefined, } }) type PatientFormData = z.infer export { PatientSchema } export type { PatientFormData }