diff --git a/app/components/content/patient/entry.vue b/app/components/content/patient/entry.vue index ce27b487..8e4d8cb4 100644 --- a/app/components/content/patient/entry.vue +++ b/app/components/content/patient/entry.vue @@ -10,14 +10,28 @@ 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, uploadAttachment } from '~/services/patient.service' -import { uploadCode } from '~/lib/constants' +import { uploadAttachment } from '~/services/patient.service' + +import { + // for form entry + isReadonly, + isProcessing, + isFormEntryDialogOpen, + isRecordConfirmationOpen, + onResetState, + handleActionSave, + handleCancelForm, +} from '~/handlers/patient.handler' + +import { toast } from '~/components/pub/ui/toast' // #region Props & Emits const props = defineProps<{ callbackUrl?: string }>() -const payload = ref() + +const residentIdentityFile = ref() +const familyCardFile = ref() // form related state const personAddressForm = ref | null>(null) @@ -65,7 +79,7 @@ onMounted(() => { // #endregion // #region Functions -async function sendRequest() { +async function composeFormData(): Promise { const [patient, address, addressRelative, families, contacts, emergencyContact] = await Promise.all([ personPatientForm.value?.validate(), personAddressForm.value?.validate(), @@ -81,7 +95,7 @@ async function sendRequest() { // exit, if form errors happend during validation // for example: dropdown not selected - if (!allValid) return + if (!allValid) return Promise.reject('Form validation failed') const formDataRequest: genPatientProps = { patient: patient?.values, @@ -93,57 +107,64 @@ async function sendRequest() { } const formData = genPatient(formDataRequest) - console.log(formData) - payload.value = formData - try { - const result = await postPatient(formData) - const patientData: PatientBase = result.body.data - if (result.success) { - console.log('Patient created successfully:', patientData) - const createdPatientId = patientData.id - - // void run uploadAttachment in background so this try-catch non blocking - // behavior: fire-and-forget - if (patient?.values.residentIdentityFile) { - void uploadAttachment(patient?.values.residentIdentityFile, createdPatientId, 'ktp') - } - - if (patient?.values.familyIdentityFile) { - void uploadAttachment(patient?.values.familyIdentityFile, createdPatientId, 'kk') - } - // 30s - await new Promise((r) => setTimeout(r, 30_000)) - - // If has callback provided redirect to callback with patientData - if (props.callbackUrl) { - await navigateTo(props.callbackUrl + '?patient-id=' + patientData.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) + if (patient?.values.residentIdentityFile) { + residentIdentityFile.value = patient?.values.residentIdentityFile } + + if (patient?.values.familyIdentityFile) { + familyCardFile.value = patient?.values.familyIdentityFile + } + + return new Promise((resolve) => resolve(formData)) } // #endregion region // #region Utilities & event handlers async function handleActionClick(eventType: string) { if (eventType === 'submit') { - await sendRequest() + const patient: Patient = await composeFormData() + let createdPatientId = 0 + + const response = await handleActionSave( + patient, + () => {}, + () => {}, + toast, + ) + + const data = (response?.body?.data ?? null) as PatientBase | null + if (!data) return + createdPatientId = data.id + + if (residentIdentityFile.value) { + void uploadAttachment(residentIdentityFile.value, createdPatientId, 'ktp') + } + if (familyCardFile.value) { + void uploadAttachment(familyCardFile.value, createdPatientId, 'kk') + } + + // If has callback provided redirect to callback with patientData + if (props.callbackUrl) { + await navigateTo(props.callbackUrl + '?patient-id=' + patient.id) + return + } + + // Navigate to patient list or show success message + await navigateTo('/client/patient') return } if (eventType === 'cancel') { - navigateTo({ + if (props.callbackUrl) { + await navigateTo(props.callbackUrl) + return + } + + await navigateTo({ name: 'client-patient', }) + // handleCancelForm() } } // #endregion diff --git a/app/handlers/_handler.ts b/app/handlers/_handler.ts index 66177937..01a191b8 100644 --- a/app/handlers/_handler.ts +++ b/app/handlers/_handler.ts @@ -129,23 +129,34 @@ export function genCrudHandler(crud: { recItem.value = null } - async function handleActionSave(values: any, refresh: () => void, reset: () => void, toast: ToastFn) { + async function handleActionSave( + values: any, + refresh: () => void, + reset: () => void, + toast: ToastFn, + ): Promise { isProcessing.value = true + + let successResponse: any = null + await handleAsyncAction<[any], any>({ action: crud.create, args: [values], toast, successMessage: 'Data berhasil disimpan', errorMessage: 'Gagal menyimpan data', - onSuccess: () => { + onSuccess: (result) => { isFormEntryDialogOpen.value = false if (refresh) refresh() + successResponse = result }, onFinally: (isSuccess: boolean) => { if (isSuccess) setTimeout(reset, 500) isProcessing.value = false }, }) + + return successResponse } async function handleActionEdit( diff --git a/app/handlers/patient.handler.ts b/app/handlers/patient.handler.ts new file mode 100644 index 00000000..f87eaf71 --- /dev/null +++ b/app/handlers/patient.handler.ts @@ -0,0 +1,24 @@ +// Handlers +import { genCrudHandler } from '~/handlers/_handler' + +// Services +import { postPatient as create, patchPatient as update, removePatient as remove } from '~/services/patient.service' + +export const { + recId, + recAction, + recItem, + isReadonly, + isProcessing, + isFormEntryDialogOpen, + isRecordConfirmationOpen, + onResetState, + handleActionSave, + handleActionEdit, + handleActionRemove, + handleCancelForm, +} = genCrudHandler({ + create, + update, + remove, +})