7f6e0cc1fd
Update interface name from PatientEntity to Patient for better clarity and consistency. Modify all related components and models to use the new interface name. Also includes minor improvements to address handling in patient forms.
259 lines
9.1 KiB
Vue
259 lines
9.1 KiB
Vue
<script setup lang="ts">
|
|
import type { Patient, genPatientProps } from '~/models/patient'
|
|
import type { ExposedForm } from '~/types/form'
|
|
import type { PatientBase } from '~/models/patient'
|
|
import Action from '~/components/pub/my-ui/nav-footer/ba-dr-su.vue'
|
|
import { genPatient } from '~/models/patient'
|
|
import { PatientSchema } from '~/schemas/patient.schema'
|
|
import { PersonAddressRelativeSchema } from '~/schemas/person-address-relative.schema'
|
|
import { PersonAddressSchema } from '~/schemas/person-address.schema'
|
|
import { PersonContactListSchema } from '~/schemas/person-contact.schema'
|
|
import { PersonFamiliesSchema } from '~/schemas/person-family.schema'
|
|
import { ResponsiblePersonSchema } from '~/schemas/person-relative.schema'
|
|
import { postPatient } from '~/services/patient.service'
|
|
|
|
// #region Props & Emits
|
|
const props = defineProps<{
|
|
callbackUrl?: string
|
|
}>()
|
|
const payload = ref<Patient>()
|
|
|
|
// form related state
|
|
const personAddressForm = ref<ExposedForm<any> | null>(null)
|
|
const personAddressRelativeForm = ref<ExposedForm<any> | null>(null)
|
|
const personContactForm = ref<ExposedForm<any> | null>(null)
|
|
const personEmergencyContactRelative = ref<ExposedForm<any> | null>(null)
|
|
const personFamilyForm = ref<ExposedForm<any> | null>(null)
|
|
const personPatientForm = ref<ExposedForm<any> | null>(null)
|
|
|
|
// #endregion
|
|
|
|
// #region State & Computed
|
|
// #endregion
|
|
|
|
// #region Lifecycle Hooks
|
|
onMounted(() => {
|
|
// Initial synchronization when forms are mounted and isSameAddress is true by default
|
|
nextTick(() => {
|
|
const isSameAddress = personAddressRelativeForm.value?.values?.isSameAddress
|
|
if (
|
|
(isSameAddress === true || isSameAddress === '1') &&
|
|
personAddressForm.value?.values &&
|
|
personAddressRelativeForm.value
|
|
) {
|
|
const currentAddressValues = personAddressForm.value.values
|
|
if (Object.keys(currentAddressValues).length > 0) {
|
|
personAddressRelativeForm.value.setValues(
|
|
{
|
|
...personAddressRelativeForm.value.values,
|
|
province_code: currentAddressValues.province_code || undefined,
|
|
regency_code: currentAddressValues.regency_code || undefined,
|
|
district_code: currentAddressValues.district_code || undefined,
|
|
village_code: currentAddressValues.village_code || undefined,
|
|
postalCode_code: currentAddressValues.postalCode_code || undefined,
|
|
address: currentAddressValues.address || undefined,
|
|
rt: currentAddressValues.rt || undefined,
|
|
rw: currentAddressValues.rw || undefined,
|
|
},
|
|
false,
|
|
)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
// #endregion
|
|
|
|
// #region Functions
|
|
// #endregion region
|
|
|
|
// #region Utilities & event handlers
|
|
async function submitAll() {
|
|
const [patient, address, addressRelative, families, contacts, emergencyContact] = await Promise.all([
|
|
personPatientForm.value?.validate(),
|
|
personAddressForm.value?.validate(),
|
|
personAddressRelativeForm.value?.validate(),
|
|
personFamilyForm.value?.validate(),
|
|
personContactForm.value?.validate(),
|
|
personEmergencyContactRelative.value?.validate(),
|
|
])
|
|
|
|
const results = [patient, address, addressRelative, families, contacts, emergencyContact]
|
|
console.log(results)
|
|
const allValid = results.every((r) => r?.valid)
|
|
|
|
// exit, if form errors happend during validation
|
|
// for example: dropdown not selected
|
|
if (!allValid) return
|
|
|
|
const formDataRequest: genPatientProps = {
|
|
patient: patient?.values,
|
|
residentAddress: address?.values,
|
|
cardAddress: addressRelative?.values,
|
|
familyData: families?.values,
|
|
contacts: contacts?.values,
|
|
responsible: emergencyContact?.values,
|
|
}
|
|
|
|
const formData = genPatient(formDataRequest)
|
|
payload.value = formData
|
|
|
|
try {
|
|
const result = await postPatient(formData)
|
|
const patientData: PatientBase = result.body
|
|
if (result.success) {
|
|
console.log('Patient created successfully:', patientData)
|
|
|
|
// If has callback provided redirect to callback with patientData
|
|
if (props.callbackUrl) {
|
|
await navigateTo(props.callbackUrl + '?patient-id=' + patientData.person_id)
|
|
return
|
|
}
|
|
|
|
// Navigate to patient list or show success message
|
|
await navigateTo('/client/patient')
|
|
} else {
|
|
console.error('Failed to create patient:', result)
|
|
// Handle error - show error message to user
|
|
}
|
|
} catch (error) {
|
|
console.error('Error creating patient:', error)
|
|
// Handle error - show error message to user
|
|
}
|
|
}
|
|
// #endregion
|
|
|
|
// #region Watchers
|
|
// Watcher untuk sinkronisasi initial ketika kedua form sudah ready
|
|
watch(
|
|
[() => personAddressForm.value, () => personAddressRelativeForm.value],
|
|
([addressForm, relativeForm]) => {
|
|
if (addressForm && relativeForm) {
|
|
// Trigger initial sync jika isSameAddress adalah true
|
|
nextTick(() => {
|
|
const isSameAddress = relativeForm.values?.isSameAddress
|
|
if ((isSameAddress === true || isSameAddress === '1') && addressForm.values) {
|
|
const currentAddressValues = addressForm.values
|
|
if (Object.keys(currentAddressValues).length > 0) {
|
|
relativeForm.setValues(
|
|
{
|
|
...relativeForm.values,
|
|
province_code: currentAddressValues.province_code || undefined,
|
|
regency_code: currentAddressValues.regency_code || undefined,
|
|
district_code: currentAddressValues.district_code || undefined,
|
|
village_code: currentAddressValues.village_code || undefined,
|
|
postalCode_code: currentAddressValues.postalCode_code || undefined,
|
|
address: currentAddressValues.address || undefined,
|
|
rt: currentAddressValues.rt || undefined,
|
|
rw: currentAddressValues.rw || undefined,
|
|
},
|
|
false,
|
|
)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
|
|
// Watcher untuk sinkronisasi alamat ketika isSameAddress = true
|
|
watch(
|
|
() => personAddressForm.value?.values,
|
|
(newAddressValues) => {
|
|
// Cek apakah alamat KTP harus sama dengan alamat sekarang
|
|
const isSameAddress = personAddressRelativeForm.value?.values?.isSameAddress
|
|
|
|
if ((isSameAddress === true || isSameAddress === '1') && newAddressValues && personAddressRelativeForm.value) {
|
|
// Sinkronkan semua field alamat dari alamat sekarang ke alamat KTP
|
|
personAddressRelativeForm.value.setValues(
|
|
{
|
|
...personAddressRelativeForm.value.values,
|
|
province_code: newAddressValues.province_code || undefined,
|
|
regency_code: newAddressValues.regency_code || undefined,
|
|
district_code: newAddressValues.district_code || undefined,
|
|
village_code: newAddressValues.village_code || undefined,
|
|
postalCode_code: newAddressValues.postalCode_code || undefined,
|
|
address: newAddressValues.address || undefined,
|
|
rt: newAddressValues.rt || undefined,
|
|
rw: newAddressValues.rw || undefined,
|
|
},
|
|
false,
|
|
)
|
|
}
|
|
},
|
|
{ deep: true },
|
|
)
|
|
|
|
// Watcher untuk memantau perubahan isSameAddress
|
|
watch(
|
|
() => personAddressRelativeForm.value?.values?.isSameAddress,
|
|
(isSameAddress) => {
|
|
if (
|
|
(isSameAddress === true || isSameAddress === '1') &&
|
|
personAddressForm.value?.values &&
|
|
personAddressRelativeForm.value
|
|
) {
|
|
// Ketika isSameAddress diubah menjadi true, copy alamat sekarang ke alamat KTP
|
|
const currentAddressValues = personAddressForm.value.values
|
|
personAddressRelativeForm.value.setValues(
|
|
{
|
|
...personAddressRelativeForm.value.values,
|
|
province_code: currentAddressValues.province_code || undefined,
|
|
regency_code: currentAddressValues.regency_code || undefined,
|
|
district_code: currentAddressValues.district_code || undefined,
|
|
village_code: currentAddressValues.village_code || undefined,
|
|
postalCode_code: currentAddressValues.postalCode_code || undefined,
|
|
address: currentAddressValues.address || undefined,
|
|
rt: currentAddressValues.rt || undefined,
|
|
rw: currentAddressValues.rw || undefined,
|
|
},
|
|
false,
|
|
)
|
|
}
|
|
},
|
|
)
|
|
// #endregion
|
|
</script>
|
|
|
|
<template>
|
|
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg font-semibold xl:text-xl">Tambah Pasien</div>
|
|
<AppPatientEntryForm
|
|
ref="personPatientForm"
|
|
:schema="PatientSchema"
|
|
/>
|
|
<AppPersonAddressEntryForm
|
|
ref="personAddressForm"
|
|
title="Alamat Sekarang"
|
|
:schema="PersonAddressSchema"
|
|
/>
|
|
<AppPersonAddressEntryFormRelative
|
|
ref="personAddressRelativeForm"
|
|
title="Alamat KTP"
|
|
:schema="PersonAddressRelativeSchema"
|
|
/>
|
|
<AppPersonFamilyParentsForm
|
|
ref="personFamilyForm"
|
|
title="Identitas Orang Tua"
|
|
:schema="PersonFamiliesSchema"
|
|
/>
|
|
<AppPersonContactEntryForm
|
|
ref="personContactForm"
|
|
title="Kontak Pasien"
|
|
:contact-limit="10"
|
|
:schema="PersonContactListSchema"
|
|
/>
|
|
<AppPersonRelativeEntryForm
|
|
ref="personEmergencyContactRelative"
|
|
title="Penanggung Jawab"
|
|
:schema="ResponsiblePersonSchema"
|
|
/>
|
|
|
|
<div class="my-2 flex justify-end py-2">
|
|
<Action @click="submitAll" />
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
/* component style */
|
|
</style>
|