From 53a1b7d4ae83e953c02a6dcb401e2a7a0674e7e0 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Fri, 17 Oct 2025 02:19:12 +0700 Subject: [PATCH] feat/encounter: wip --- app/components/app/encounter/list-cfg.ts | 127 ------------------ app/components/app/encounter/list.cfg.ts | 104 ++++++++++++++ app/components/app/encounter/list.vue | 4 +- app/components/app/encounter/status-badge.vue | 18 ++- app/components/content/encounter/list.vue | 2 +- app/components/content/encounter/process.vue | 6 +- app/models/encounter.ts | 10 ++ app/models/patient.ts | 27 +++- app/models/person.ts | 6 + 9 files changed, 164 insertions(+), 140 deletions(-) delete mode 100644 app/components/app/encounter/list-cfg.ts create mode 100644 app/components/app/encounter/list.cfg.ts diff --git a/app/components/app/encounter/list-cfg.ts b/app/components/app/encounter/list-cfg.ts deleted file mode 100644 index fb15bc06..00000000 --- a/app/components/app/encounter/list-cfg.ts +++ /dev/null @@ -1,127 +0,0 @@ -import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' -import { defineAsyncComponent } from 'vue' - -type SmallDetailDto = any - -const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-pdud.vue')) -const statusBadge = defineAsyncComponent(() => import('./status-badge.vue')) - -export const config: Config = { - cols: [ - {}, - {}, - {}, - { width: 100 }, - { width: 120 }, - {}, - {}, - {}, - { width: 100 }, - { width: 100 }, - {}, - { width: 50 }, - ], - - headers: [ - [ - { label: 'Nama' }, - { label: 'Rekam Medis' }, - { label: 'KTP' }, - { label: 'Tgl Lahir' }, - { label: 'Umur' }, - { label: 'JK' }, - { label: 'Pendidikan' }, - { label: 'Status' }, - { label: '' }, - ], - ], - - keys: [ - 'name', - 'medicalRecord_number', - 'identity_number', - 'birth_date', - 'patient_age', - 'gender', - 'education', - 'status', - 'action', - ], - - delKeyNames: [ - { key: 'code', label: 'Kode' }, - { key: 'name', label: 'Nama' }, - ], - - parses: { - name: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - return `${recX.firstName} ${recX.middleName || ''} ${recX.lastName || ''}` - }, - identity_number: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - if (recX.identity_number?.substring(0, 5) === 'BLANK') { - return '(TANPA NIK)' - } - return recX.identity_number - }, - birth_date: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - if (typeof recX.birth_date == 'object' && recX.birth_date) { - return (recX.birth_date as Date).toLocaleDateString() - } else if (typeof recX.birth_date == 'string') { - return (recX.birth_date as string).substring(0, 10) - } - return recX.birth_date - }, - patient_age: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - return recX.birth_date?.split('T')[0] - }, - gender: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - if (typeof recX?.gender_code !== 'number' && recX?.gender_code !== '') { - return 'Tidak Diketahui' - } - return recX.gender_code - }, - education: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - if (typeof recX.education_code == 'number' && recX.education_code >= 0) { - return recX.education_code - } else if (typeof recX.education_code) { - return recX.education_code - } - return '-' - }, - }, - - components: { - action(rec, idx) { - const res: RecComponent = { - idx, - rec: rec as object, - component: action, - } - return res - }, - status(rec, idx) { - const recX = rec as SmallDetailDto - if (recX.status_code === null) { - recX.status_code = 0 - } - const res: RecComponent = { - idx, - rec: rec as object, - component: statusBadge, - } - return res - }, - }, - - htmls: { - patient_address(_rec) { - return '-' - }, - }, -} diff --git a/app/components/app/encounter/list.cfg.ts b/app/components/app/encounter/list.cfg.ts new file mode 100644 index 00000000..9ebbc34f --- /dev/null +++ b/app/components/app/encounter/list.cfg.ts @@ -0,0 +1,104 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' +import type { Encounter } from '~/models/encounter' +import { educationCodes, genderCodes } from '~/lib/constants' +import { getAge } from '~/lib/date' + +type SmallDetailDto = Encounter + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-pdud.vue')) +const statusBadge = defineAsyncComponent(() => import('./status-badge.vue')) + +export const config: Config = { + cols: [ + {}, + {}, + {}, + { width: 160 }, + {}, + { width: 70 }, + { }, + { width: 50 }, + ], + + headers: [ + [ + { label: 'Nama' }, + { label: 'Rekam Medis' }, + { label: 'KTP' }, + { label: 'Tgl Lahir / Umur' }, + { label: 'JK' }, + { label: 'Pendidikan' }, + { label: 'Status', classVal: '!text-center' }, + { label: '' }, + ], + ], + + keys: [ + 'patient.person.name', + 'patient.number', + 'patient.person.residentIdentityNumber', + 'birth_date', + 'gender', + 'education', + 'status', + 'action', + ], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: { + gender: (rec: unknown): unknown => { + const recX = rec as Encounter + if (recX.patient?.person?.gender_code) { + return genderCodes[recX.patient.person.gender_code] + } + return '-' + }, + education: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + if (recX.patient?.person?.education_code) { + return educationCodes[recX.patient.person.education_code] + } + return '-' + }, + }, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + } + return res + }, + status(rec, idx) { + const recX = rec as Encounter + if (!recX.status_code) { + recX.status_code = 'new' + } + const res: RecComponent = { + idx, + rec: recX, + component: statusBadge, + } + return res + }, + }, + + htmls: { + birth_date: (rec: unknown): unknown => { + const recX = rec as Encounter + if (recX.patient?.person?.birthDate) { + return '' + + '
' + (recX.patient.person.birthDate as string).substring(0, 10) + ' /
' + + getAge(recX.patient.person.birthDate as string).extFormat + } + return '-' + }, + }, +} diff --git a/app/components/app/encounter/list.vue b/app/components/app/encounter/list.vue index 96697bde..1d58d6a7 100644 --- a/app/components/app/encounter/list.vue +++ b/app/components/app/encounter/list.vue @@ -1,7 +1,7 @@ diff --git a/app/components/app/encounter/status-badge.vue b/app/components/app/encounter/status-badge.vue index 32cdfbca..c8d4cd06 100644 --- a/app/components/app/encounter/status-badge.vue +++ b/app/components/app/encounter/status-badge.vue @@ -1,22 +1,28 @@ diff --git a/app/components/content/encounter/list.vue b/app/components/content/encounter/list.vue index f218444a..5ddf3ad7 100644 --- a/app/components/content/encounter/list.vue +++ b/app/components/content/encounter/list.vue @@ -49,7 +49,7 @@ const refSearchNav: RefSearchNav = { async function getPatientList() { isLoading.isTableLoading = true - const resp = await xfetch('/api/v1/encounter') + const resp = await xfetch('/api/v1/encounter?includes=patient,patient-person') if (resp.success) { data.value = (resp.body as Record).data } diff --git a/app/components/content/encounter/process.vue b/app/components/content/encounter/process.vue index 67e71ddd..ea65f6a9 100644 --- a/app/components/content/encounter/process.vue +++ b/app/components/content/encounter/process.vue @@ -29,7 +29,9 @@ const activeTab = computed({ }) const id = typeof route.params.id == 'string' ? parseInt(route.params.id) : 0 -const encounter = ref((await getDetail(id)) as Encounter) +const encounterRes = await getDetail(id) +const encounterResBody = encounterRes.body ?? null +const encounter = encounterResBody?.data ?? null const data = { noRm: 'RM21123', @@ -45,7 +47,7 @@ const data = { } const tabs: TabItem[] = [ - { value: 'status', label: 'Status Masuk/Keluar', component: Status }, + { value: 'status', label: 'Status Masuk/Keluar', component: Status, props: { encounter } }, { value: 'early-medical-assessment', label: 'Pengkajian Awal Medis', component: EarlyMedicalAssesmentList }, { value: 'rehab-medical-assessment', diff --git a/app/models/encounter.ts b/app/models/encounter.ts index 43821be6..d6928070 100644 --- a/app/models/encounter.ts +++ b/app/models/encounter.ts @@ -1,14 +1,22 @@ import { type Doctor, genDoctor } from "./doctor" import { genEmployee, type Employee } from "./employee" +import { type Patient, genPatient } from "./patient" +import type { Specialist } from "./specialist" +import type { Subspecialist } from "./subspecialist" +import { genUnit, type Unit } from "./unit" export interface Encounter { id: number patient_id: number + patient: Patient registeredAt: string class_code: string unit_id: number + unit: Unit specialist_id?: number + specilist?: Specialist subspecialist_id?: number + subspecialist?: Subspecialist visitdate: string adm_employee_id: number adm_employee: Employee @@ -30,9 +38,11 @@ export function genEncounter(): Encounter { return { id: 0, patient_id: 0, + patient: genPatient(), registeredAt: '', class_code: '', unit_id: 0, + unit: genUnit(), visitdate: '', adm_employee_id: 0, adm_employee: genEmployee(), diff --git a/app/models/patient.ts b/app/models/patient.ts index 268bccd4..11b8d778 100644 --- a/app/models/patient.ts +++ b/app/models/patient.ts @@ -6,7 +6,7 @@ import type { PersonFamiliesFormData } from '~/schemas/person-family.schema' import type { PersonContactFormData } from '~/schemas/person-contact.schema' import type { PersonRelativeFormData } from '~/schemas/person-relative.schema' -import type { Person } from './person' +import { genPerson, type Person } from './person' import type { PersonAddress } from './person-address' import type { PersonContact } from './person-contact' import type { PersonRelative } from './person-relative' @@ -37,7 +37,7 @@ export interface genPatientProps { responsible: PersonRelativeFormData } -export function genPatient(props: genPatientProps): PatientEntity { +export function genPatientEntity(props: genPatientProps): PatientEntity { const { patient, residentAddress, cardAddress, familyData, contacts, responsible } = props const addresses: PersonAddress[] = [{ ...genBase(), person_id: 0, locationType: '', ...residentAddress }] @@ -135,3 +135,26 @@ export function genPatient(props: genPatientProps): PatientEntity { deletedAt: null, } } + + +// New model +export interface Patient extends Base { + person_id?: number + person: Person + newBornStatus?: boolean + registeredAt?: Date | string | null + status_code?: string + number?: string +} + +export function genPatient(): Patient { + return { + ...genBase(), + person_id: 0, + registeredAt: '', + status_code: '', + number: '', + newBornStatus: false, + person: genPerson(), + } +} \ No newline at end of file diff --git a/app/models/person.ts b/app/models/person.ts index 435eae4b..86506465 100644 --- a/app/models/person.ts +++ b/app/models/person.ts @@ -1,4 +1,7 @@ import { type Base, genBase } from "./_base" +import type { PersonAddress } from "./person-address" +import type { PersonContact } from "./person-contact" +import type { PersonRelative } from "./person-relative" export interface Person extends Base { // todo: awaiting approve from stake holder: buat field sapaan @@ -26,6 +29,9 @@ export interface Person extends Base { passportFileUrl?: string drivingLicenseFileUrl?: string familyIdentityFileUrl?: string + addresses?: PersonAddress[] + contacts?: PersonContact[] + relatives?: PersonRelative[] } export function genPerson(): Person {