fix edit form state
fix: id list for contacts and address list fix warning fix duplicate contacts responsible: true fix edit family fix nik required
This commit is contained in:
@@ -30,7 +30,7 @@ import {
|
|||||||
} from './fields'
|
} from './fields'
|
||||||
|
|
||||||
interface FormData extends PatientFormData {
|
interface FormData extends PatientFormData {
|
||||||
_calculatedAge: string
|
_calculatedAge: string | Date
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type untuk initial values (sebelum transform schema)
|
// Type untuk initial values (sebelum transform schema)
|
||||||
@@ -66,7 +66,7 @@ interface Props {
|
|||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
const formSchema = toTypedSchema(PatientSchema)
|
const formSchema = toTypedSchema(PatientSchema)
|
||||||
|
|
||||||
const { values, resetForm, setValues, setFieldValue, validate } = useForm<FormData>({
|
const { values, resetForm, setValues, setFieldValue, validate, setFieldError } = useForm<FormData>({
|
||||||
name: 'patientForm',
|
name: 'patientForm',
|
||||||
validationSchema: formSchema,
|
validationSchema: formSchema,
|
||||||
initialValues: (props.initialValues ?? {}) as any,
|
initialValues: (props.initialValues ?? {}) as any,
|
||||||
@@ -106,6 +106,7 @@ watch(
|
|||||||
placeholder="Masukkan NIK"
|
placeholder="Masukkan NIK"
|
||||||
numeric-only
|
numeric-only
|
||||||
:is-disabled="isReadonly"
|
:is-disabled="isReadonly"
|
||||||
|
:max-length="16"
|
||||||
/>
|
/>
|
||||||
<InputBase
|
<InputBase
|
||||||
field-name="drivingLicenseNumber"
|
field-name="drivingLicenseNumber"
|
||||||
|
|||||||
@@ -114,7 +114,9 @@ const patientFormInitialValues = computed(() => {
|
|||||||
|
|
||||||
// Computed: unwrap alamat domisili (alamat sekarang)
|
// Computed: unwrap alamat domisili (alamat sekarang)
|
||||||
const addressFormInitialValues = computed(() => {
|
const addressFormInitialValues = computed(() => {
|
||||||
const addresses = patientDetail.value.person?.addresses || patientDetail.value.personAddresses || []
|
if (!patientDetail.value.person?.addresses) return {}
|
||||||
|
|
||||||
|
const addresses = patientDetail.value.person?.addresses
|
||||||
const domicileAddress = addresses.find((a: PersonAddress) => a.locationType_code === 'domicile')
|
const domicileAddress = addresses.find((a: PersonAddress) => a.locationType_code === 'domicile')
|
||||||
if (!domicileAddress) return undefined
|
if (!domicileAddress) return undefined
|
||||||
|
|
||||||
@@ -125,6 +127,7 @@ const addressFormInitialValues = computed(() => {
|
|||||||
const province = regency?.province
|
const province = regency?.province
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
id: domicileAddress.id || 0,
|
||||||
locationType_code: 'domicile',
|
locationType_code: 'domicile',
|
||||||
province_code: province?.code || '',
|
province_code: province?.code || '',
|
||||||
regency_code: regency?.code || '',
|
regency_code: regency?.code || '',
|
||||||
@@ -139,30 +142,11 @@ const addressFormInitialValues = computed(() => {
|
|||||||
|
|
||||||
// Computed: unwrap alamat KTP (identity)
|
// Computed: unwrap alamat KTP (identity)
|
||||||
const addressRelativeFormInitialValues = computed(() => {
|
const addressRelativeFormInitialValues = computed(() => {
|
||||||
const addresses = patientDetail.value.person?.addresses || patientDetail.value.personAddresses || []
|
if (!patientDetail.value.person?.addresses) return {}
|
||||||
const domicileAddress = addresses.find((a: PersonAddress) => a.locationType_code === 'domicile')
|
|
||||||
const identityAddress = addresses.find((a: PersonAddress) => a.locationType_code === 'identity')
|
|
||||||
|
|
||||||
// Jika tidak ada alamat KTP terpisah, berarti sama dengan domisili
|
const addresses = patientDetail.value.person?.addresses
|
||||||
if (!identityAddress) {
|
const domicileAddress = addresses.find((a: PersonAddress) => a.locationType_code === 'domicile')!
|
||||||
return {
|
const identityAddress = addresses.find((a: PersonAddress) => a.locationType_code === 'identity')!
|
||||||
isSameAddress: '1',
|
|
||||||
locationType_code: 'identity',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cek apakah alamat sama dengan domisili
|
|
||||||
const isSame =
|
|
||||||
domicileAddress &&
|
|
||||||
identityAddress.village_code === domicileAddress.village_code &&
|
|
||||||
identityAddress.address === domicileAddress.address
|
|
||||||
|
|
||||||
if (isSame) {
|
|
||||||
return {
|
|
||||||
isSameAddress: '1',
|
|
||||||
locationType_code: 'identity',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract kode wilayah dari preload data
|
// extract kode wilayah dari preload data
|
||||||
const village = identityAddress.postalRegion?.village
|
const village = identityAddress.postalRegion?.village
|
||||||
@@ -170,8 +154,11 @@ const addressRelativeFormInitialValues = computed(() => {
|
|||||||
const regency = district?.regency
|
const regency = district?.regency
|
||||||
const province = regency?.province
|
const province = regency?.province
|
||||||
|
|
||||||
|
const isSame = domicileAddress.village_code === identityAddress.village_code ? '1' : '0'
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isSameAddress: '0',
|
isSameAddress: isSame,
|
||||||
|
id: identityAddress.id || 0,
|
||||||
locationType_code: 'identity',
|
locationType_code: 'identity',
|
||||||
province_code: province?.code || '',
|
province_code: province?.code || '',
|
||||||
regency_code: regency?.code || '',
|
regency_code: regency?.code || '',
|
||||||
@@ -201,6 +188,7 @@ const familyFormInitialValues = computed(() => {
|
|||||||
return {
|
return {
|
||||||
shareFamilyData: '1',
|
shareFamilyData: '1',
|
||||||
families: parents.map((parent: PersonRelative) => ({
|
families: parents.map((parent: PersonRelative) => ({
|
||||||
|
id: parent.id || 0,
|
||||||
relation: parent.relationship_code || '',
|
relation: parent.relationship_code || '',
|
||||||
name: parent.name || '',
|
name: parent.name || '',
|
||||||
education: parent.education_code || '',
|
education: parent.education_code || '',
|
||||||
@@ -216,6 +204,7 @@ const contactFormInitialValues = computed(() => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
contacts: contacts.map((contact: PersonContact) => ({
|
contacts: contacts.map((contact: PersonContact) => ({
|
||||||
|
id: contact.id || 0,
|
||||||
contactType: reverseContactTypeMapping[contact.type_code] || contact.type_code || '',
|
contactType: reverseContactTypeMapping[contact.type_code] || contact.type_code || '',
|
||||||
contactNumber: contact.value || '',
|
contactNumber: contact.value || '',
|
||||||
})),
|
})),
|
||||||
@@ -231,6 +220,7 @@ const responsibleFormInitialValues = computed(() => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
contacts: responsibles.map((r: PersonRelative) => ({
|
contacts: responsibles.map((r: PersonRelative) => ({
|
||||||
|
id: r.id || 0,
|
||||||
relation: r.relationship_code || '',
|
relation: r.relationship_code || '',
|
||||||
name: r.name || '',
|
name: r.name || '',
|
||||||
address: r.address || '',
|
address: r.address || '',
|
||||||
@@ -272,6 +262,7 @@ async function composeFormData(): Promise<PatientEntity> {
|
|||||||
...patient?.values,
|
...patient?.values,
|
||||||
|
|
||||||
// casting comp. val to backend well known reflect value
|
// casting comp. val to backend well known reflect value
|
||||||
|
ethnic: patient?.values.nationality === 'WNI' ? patient?.values.ethnic : null,
|
||||||
birthDate: parseISO(patient?.values.birthDate || ''),
|
birthDate: parseISO(patient?.values.birthDate || ''),
|
||||||
isNewBorn: patient?.values.isNewBorn === 'yes',
|
isNewBorn: patient?.values.isNewBorn === 'yes',
|
||||||
communicationBarrier: patient?.values.communicationBarrier === 'yes',
|
communicationBarrier: patient?.values.communicationBarrier === 'yes',
|
||||||
@@ -327,8 +318,7 @@ async function handleActionClick(eventType: string) {
|
|||||||
|
|
||||||
let createdPatientId = 0
|
let createdPatientId = 0
|
||||||
let response: any
|
let response: any
|
||||||
|
// return
|
||||||
// If edit mode, update patient
|
|
||||||
if (props.mode === 'edit' && props.patientId) {
|
if (props.mode === 'edit' && props.patientId) {
|
||||||
response = await handleActionEdit(
|
response = await handleActionEdit(
|
||||||
patientDetail.value.id,
|
patientDetail.value.id,
|
||||||
@@ -337,9 +327,7 @@ async function handleActionClick(eventType: string) {
|
|||||||
() => {},
|
() => {},
|
||||||
toast,
|
toast,
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
// If create mode, create patient
|
|
||||||
else {
|
|
||||||
response = await handleActionSave(
|
response = await handleActionSave(
|
||||||
patient,
|
patient,
|
||||||
() => {},
|
() => {},
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { contactTypeMapping } from '~/lib/constants'
|
|||||||
|
|
||||||
export interface PatientBase extends Base {
|
export interface PatientBase extends Base {
|
||||||
person_id?: number | null
|
person_id?: number | null
|
||||||
newBornStatus?: boolean
|
newBornStatus?: boolean | string
|
||||||
registeredAt?: Date | string | null
|
registeredAt?: Date | string | null
|
||||||
status_code?: string | null
|
status_code?: string | null
|
||||||
number?: string | null
|
number?: string | null
|
||||||
@@ -40,6 +40,7 @@ export interface genPatientProps {
|
|||||||
export function genPatientEntity(props: genPatientProps, patientData: PatientEntity | null): PatientEntity {
|
export function genPatientEntity(props: genPatientProps, patientData: PatientEntity | null): PatientEntity {
|
||||||
const { patient, residentAddress, cardAddress, familyData, contacts, responsible } = props
|
const { patient, residentAddress, cardAddress, familyData, contacts, responsible } = props
|
||||||
|
|
||||||
|
// const val = toRaw(patientData)
|
||||||
const addresses: PersonAddress[] = [{ ...genBase(), person_id: patientData?.person?.id || 0, ...residentAddress }]
|
const addresses: PersonAddress[] = [{ ...genBase(), person_id: patientData?.person?.id || 0, ...residentAddress }]
|
||||||
const familiesContact: PersonRelative[] = []
|
const familiesContact: PersonRelative[] = []
|
||||||
const personContacts: PersonContact[] = []
|
const personContacts: PersonContact[] = []
|
||||||
@@ -49,6 +50,7 @@ export function genPatientEntity(props: genPatientProps, patientData: PatientEnt
|
|||||||
addresses.push({
|
addresses.push({
|
||||||
...genBase(),
|
...genBase(),
|
||||||
...residentAddress,
|
...residentAddress,
|
||||||
|
id: cardAddress.id || 0,
|
||||||
person_id: 0,
|
person_id: 0,
|
||||||
locationType_code: cardAddress.locationType_code || 'identity',
|
locationType_code: cardAddress.locationType_code || 'identity',
|
||||||
})
|
})
|
||||||
@@ -57,6 +59,7 @@ export function genPatientEntity(props: genPatientProps, patientData: PatientEnt
|
|||||||
// Pastikan semua field yang diperlukan ada
|
// Pastikan semua field yang diperlukan ada
|
||||||
const relativeAddress = {
|
const relativeAddress = {
|
||||||
...genBase(),
|
...genBase(),
|
||||||
|
id: cardAddress.id || 0,
|
||||||
person_id: patientData?.person?.id || 0,
|
person_id: patientData?.person?.id || 0,
|
||||||
locationType_code: cardAddress.locationType_code || 'identity',
|
locationType_code: cardAddress.locationType_code || 'identity',
|
||||||
address: cardAddress.address || '',
|
address: cardAddress.address || '',
|
||||||
@@ -75,7 +78,7 @@ export function genPatientEntity(props: genPatientProps, patientData: PatientEnt
|
|||||||
if (familyData.shareFamilyData === '1') {
|
if (familyData.shareFamilyData === '1') {
|
||||||
for (const family of familyData.families) {
|
for (const family of familyData.families) {
|
||||||
familiesContact.push({
|
familiesContact.push({
|
||||||
id: 0,
|
id: family.id || 0,
|
||||||
relationship_code: family.relation,
|
relationship_code: family.relation,
|
||||||
name: family.name,
|
name: family.name,
|
||||||
education_code: family.education,
|
education_code: family.education,
|
||||||
@@ -94,6 +97,7 @@ export function genPatientEntity(props: genPatientProps, patientData: PatientEnt
|
|||||||
|
|
||||||
personContacts.push({
|
personContacts.push({
|
||||||
...genBase(),
|
...genBase(),
|
||||||
|
id: contact.id || 0,
|
||||||
person_id: patientData?.person?.id || 0,
|
person_id: patientData?.person?.id || 0,
|
||||||
type_code: mappedContactType || '',
|
type_code: mappedContactType || '',
|
||||||
value: contact.contactNumber,
|
value: contact.contactNumber,
|
||||||
@@ -105,7 +109,7 @@ export function genPatientEntity(props: genPatientProps, patientData: PatientEnt
|
|||||||
if (responsible) {
|
if (responsible) {
|
||||||
for (const contact of responsible.contacts) {
|
for (const contact of responsible.contacts) {
|
||||||
familiesContact.push({
|
familiesContact.push({
|
||||||
id: 0,
|
id: contact.id || 0,
|
||||||
relationship_code: contact.relation,
|
relationship_code: contact.relation,
|
||||||
name: contact.name,
|
name: contact.name,
|
||||||
address: contact.address,
|
address: contact.address,
|
||||||
@@ -164,7 +168,7 @@ export function genPatientEntity(props: genPatientProps, patientData: PatientEnt
|
|||||||
export interface Patient extends Base {
|
export interface Patient extends Base {
|
||||||
person_id?: number | null
|
person_id?: number | null
|
||||||
person: Person
|
person: Person
|
||||||
newBornStatus?: boolean
|
newBornStatus?: boolean | string
|
||||||
registeredAt?: Date | string | null
|
registeredAt?: Date | string | null
|
||||||
status_code?: string | null
|
status_code?: string | null
|
||||||
number?: string | null
|
number?: string | null
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export interface Person extends Base {
|
|||||||
ethnic_code?: string | null
|
ethnic_code?: string | null
|
||||||
language_code?: string | null
|
language_code?: string | null
|
||||||
nationality?: string | null
|
nationality?: string | null
|
||||||
communicationIssueStatus?: boolean
|
communicationIssueStatus?: boolean | string
|
||||||
disability?: string | null
|
disability?: string | null
|
||||||
residentIdentityFileUrl?: string | null
|
residentIdentityFileUrl?: string | null
|
||||||
passportFileUrl?: string | null
|
passportFileUrl?: string | null
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ const PatientSchema = z
|
|||||||
.object({
|
.object({
|
||||||
// Data Diri Pasien
|
// Data Diri Pasien
|
||||||
identityNumber: z.string().optional(),
|
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
|
residentIdentityFile: z
|
||||||
.any()
|
.any()
|
||||||
.optional()
|
.optional()
|
||||||
@@ -58,8 +53,8 @@ const PatientSchema = z
|
|||||||
nationality: z.string({
|
nationality: z.string({
|
||||||
required_error: 'Pilih Kebangsaan',
|
required_error: 'Pilih Kebangsaan',
|
||||||
}),
|
}),
|
||||||
isNewBorn: z.string({
|
isNewBorn: z.union([z.boolean(), z.string()], {
|
||||||
required_error: 'Mohon lengkapi status pasien',
|
required_error: 'Mohon lengkapi Status Disabilitas',
|
||||||
}),
|
}),
|
||||||
language: z.string({
|
language: z.string({
|
||||||
required_error: 'Mohon pilih Preferensi Bahasa',
|
required_error: 'Mohon pilih Preferensi Bahasa',
|
||||||
@@ -84,7 +79,7 @@ const PatientSchema = z
|
|||||||
|
|
||||||
// Informasi Kontak
|
// Informasi Kontak
|
||||||
passportNumber: z.string().optional(),
|
passportNumber: z.string().optional(),
|
||||||
communicationBarrier: z.string({
|
communicationBarrier: z.union([z.boolean(), z.string()], {
|
||||||
required_error: 'Mohon lengkapi Status Hambatan Berkomunikasi',
|
required_error: 'Mohon lengkapi Status Hambatan Berkomunikasi',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@@ -103,6 +98,19 @@ const PatientSchema = z
|
|||||||
path: ['disabilityType'],
|
path: ['disabilityType'],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.refine(
|
||||||
|
(data) => {
|
||||||
|
if (data.nationality === 'WNI') {
|
||||||
|
const nik = data.identityNumber?.trim()
|
||||||
|
return !!nik && nik.length === 16 && /^\d+$/.test(nik)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: 'NIK harus berupa angka 16 digit',
|
||||||
|
path: ['identityNumber'],
|
||||||
|
},
|
||||||
|
)
|
||||||
// .transform((data) => {
|
// .transform((data) => {
|
||||||
// return {
|
// return {
|
||||||
// ...data,
|
// ...data,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
const PersonAddressSchema = z.object({
|
const PersonAddressSchema = z.object({
|
||||||
|
id: z.number().optional(),
|
||||||
|
|
||||||
locationType_code: z.string({
|
locationType_code: z.string({
|
||||||
required_error: 'Mohon pilih jenis alamat',
|
required_error: 'Mohon pilih jenis alamat',
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
const PersonContactBaseSchema = z.object({
|
const PersonContactBaseSchema = z.object({
|
||||||
|
id: z.number().optional(),
|
||||||
|
|
||||||
contactType: z.string({ required_error: 'Mohon pilih tipe kontak' }).min(1, 'Mohon pilih tipe kontak'),
|
contactType: z.string({ required_error: 'Mohon pilih tipe kontak' }).min(1, 'Mohon pilih tipe kontak'),
|
||||||
contactNumber: z.string({ required_error: 'Nomor kontak harus diisi' }).min(8, 'Nomor minimal 8 digit'),
|
contactNumber: z.string({ required_error: 'Nomor kontak harus diisi' }).min(8, 'Nomor minimal 8 digit'),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
const PersonFamilySchema = z.object({
|
const PersonFamilySchema = z.object({
|
||||||
|
id: z.number().optional(),
|
||||||
relation: z.enum(['mother', 'father', 'guardian', 'emergency_contact']),
|
relation: z.enum(['mother', 'father', 'guardian', 'emergency_contact']),
|
||||||
name: z
|
name: z
|
||||||
.string({
|
.string({
|
||||||
@@ -29,6 +30,7 @@ const PersonFamiliesSchema = z.discriminatedUnion('shareFamilyData', [
|
|||||||
interface PersonFamiliesFormData {
|
interface PersonFamiliesFormData {
|
||||||
shareFamilyData: '0' | '1'
|
shareFamilyData: '0' | '1'
|
||||||
families: {
|
families: {
|
||||||
|
id?: number
|
||||||
relation: 'mother' | 'father' | 'guardian' | 'emergency_contact'
|
relation: 'mother' | 'father' | 'guardian' | 'emergency_contact'
|
||||||
name: string
|
name: string
|
||||||
education: string
|
education: string
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
|
|
||||||
const ResponsibleContactPersonSchema = z.object({
|
const ResponsibleContactPersonSchema = z.object({
|
||||||
|
id: z.number().optional(),
|
||||||
|
|
||||||
relation: z.string({ required_error: 'Pilih jenis Penanggung Jawab' }).min(1, 'Pilih jenis Penanggung Jawab'),
|
relation: z.string({ required_error: 'Pilih jenis Penanggung Jawab' }).min(1, 'Pilih jenis Penanggung Jawab'),
|
||||||
name: z.string({ required_error: 'Mohon lengkapi Nama' }).min(3, 'Mohon lengkapi Nama'),
|
name: z.string({ required_error: 'Mohon lengkapi Nama' }).min(3, 'Mohon lengkapi Nama'),
|
||||||
address: z.string({ required_error: 'Mohon lengkapi Alamat' }).min(3, 'Mohon lengkapi Alamat'),
|
address: z.string({ required_error: 'Mohon lengkapi Alamat' }).min(3, 'Mohon lengkapi Alamat'),
|
||||||
|
|||||||
Reference in New Issue
Block a user