Files

128 lines
3.5 KiB
TypeScript

import { z } from 'zod'
const ACCEPTED_UPLOAD_TYPES = ['image/jpeg', 'image/png', 'application/pdf']
const PatientSchema = z
.object({
// Data Diri Pasien
identityNumber: z.string().optional(),
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' }),
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',
}),
// Jenis Kelamin & Status
gender: z.string({
required_error: 'Pilih Jenis Kelamin',
}),
maritalStatus: z.enum(['S', 'M', 'D', 'W'], {
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: z.union([z.boolean(), z.string()], {
required_error: 'Mohon lengkapi Status Disabilitas',
}),
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.string({
required_error: 'Mohon lengkapi Status Disabilitas',
}),
disabilityType: z.string().optional(),
// Informasi Kontak
passportNumber: z.string().optional(),
communicationBarrier: z.union([z.boolean(), z.string()], {
required_error: 'Mohon lengkapi Status Hambatan Berkomunikasi',
}),
note: z.string().optional(),
drivingLicenseNumber: z.string().optional(),
})
.refine(
(data) => {
if (data.disability === 'yes') {
return !!data.disabilityType?.trim()
}
return true
},
{
message: 'Mohon pilih jenis Disabilitas',
path: ['disabilityType'],
},
)
.refine(
(data) => {
if (data.nationality === 'WNI') {
const nik = data.identityNumber?.trim()
if (!nik) return true
return nik && nik.length === 16 && /^\d+$/.test(nik)
}
return true
},
{
message: 'NIK harus berupa angka 16 digit',
path: ['identityNumber'],
},
)
// .transform((data) => {
// return {
// ...data,
// // newBornStatus: data.isNewBorn === 'yes',
// // communicationBarrier: data.communicationBarrier === 'yes',
// // disability: data.disability ? data.disabilityType : null,
// }
// })
type PatientFormData = z.infer<typeof PatientSchema>
export { PatientSchema }
export type { PatientFormData }