From cbb38c02756725ea6846415ba0ce12a44e4c7620 Mon Sep 17 00:00:00 2001 From: Khafid Prayoga Date: Fri, 15 Aug 2025 13:54:54 +0700 Subject: [PATCH] impl data table list of doctor --- app/components/app/doctor/list-cfg.ts | 102 ++++++++++++++++++++++++++ app/components/app/doctor/list.vue | 19 +++++ app/components/app/doctor/picker.vue | 0 app/components/app/doctor/search.vue | 0 app/components/flow/doctor/list.vue | 16 ++-- app/pages/(features)/doctor/add.vue | 4 +- app/pages/(features)/doctor/index.vue | 5 +- 7 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 app/components/app/doctor/list-cfg.ts create mode 100644 app/components/app/doctor/list.vue create mode 100644 app/components/app/doctor/picker.vue create mode 100644 app/components/app/doctor/search.vue diff --git a/app/components/app/doctor/list-cfg.ts b/app/components/app/doctor/list-cfg.ts new file mode 100644 index 00000000..9d47c6d0 --- /dev/null +++ b/app/components/app/doctor/list-cfg.ts @@ -0,0 +1,102 @@ +import type { Col, KeyLabel, RecComponent, RecStrFuncComponent, RecStrFuncUnknown, Th } from '../../pub/nav/types' +import { defineAsyncComponent } from 'vue' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/nav/dropdown-action-dud.vue')) + +const doctorStatus = { + 0: 'Tidak Aktif', + 1: 'Aktif', +} + +export const cols: Col[] = [ + { width: 100 }, + { width: 250 }, + {}, + { width: 100 }, + { width: 100 }, + {}, + {}, + {}, + { width: 100 }, + { width: 100 }, + { width: 100 }, + { width: 50 }, +] + +export const header: Th[][] = [ + [ + { label: 'Kode JKN' }, + { label: 'Nama' }, + { label: 'No KTP' }, + { label: 'No SIP' }, + { label: 'No IHS' }, + { label: 'Telpon' }, + { label: 'Fee Ranap' }, + { label: 'Fee Rajal' }, + { label: 'Status' }, + ], +] + +export const keys = [ + 'bpjs_code', + 'name', + 'identity_number', + 'sip_no', + 'ihs_number', + 'phone', + 'inPatient_itemPrice', + 'outPatient_itemPrice', + 'status', + 'action', +] + +export const delKeyNames: KeyLabel[] = [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, +] + +export const funcParsed: RecStrFuncUnknown = { + name: (rec: unknown): unknown => { + console.log(rec) + const recX = rec as SmallDetailDto + return `${recX.frontTitle} ${recX.name} ${recX.endTitle}`.trim() + }, + 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 + }, + inPatient_itemPrice: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID') + }, + outPatient_itemPrice: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID') + }, + status: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return doctorStatus[recX.status_code as keyof typeof doctorStatus] + }, +} + +export const funcComponent: RecStrFuncComponent = { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + } + return res + }, +} + +export const funcHtml: RecStrFuncUnknown = { + patient_address(_rec) { + return '-' + }, +} diff --git a/app/components/app/doctor/list.vue b/app/components/app/doctor/list.vue new file mode 100644 index 00000000..5b8778d9 --- /dev/null +++ b/app/components/app/doctor/list.vue @@ -0,0 +1,19 @@ + + + diff --git a/app/components/app/doctor/picker.vue b/app/components/app/doctor/picker.vue new file mode 100644 index 00000000..e69de29b diff --git a/app/components/app/doctor/search.vue b/app/components/app/doctor/search.vue new file mode 100644 index 00000000..e69de29b diff --git a/app/components/flow/doctor/list.vue b/app/components/flow/doctor/list.vue index ed4aff6f..c6007660 100644 --- a/app/components/flow/doctor/list.vue +++ b/app/components/flow/doctor/list.vue @@ -4,7 +4,6 @@ import type { HeaderPrep, RefSearchNav } from '~/components/pub/nav/types' const data = ref([]) const refSearchNav: RefSearchNav = { - onClick: () => { // open filter modal }, @@ -20,25 +19,26 @@ const recId = ref(0) const recAction = ref('') const recItem = ref(null) -const hreaderPrep: HeaderPrep = { +const headerPrep: HeaderPrep = { title: 'Dokter', - icon: 'i-lucide-add', + icon: 'i-lucide-network', addNav: { label: 'Tambah', onClick: () => navigateTo('/doctor/add'), }, } -async function getPatientList() { - const resp = await xfetch('/api/v1/patient') - console.log('data patient', resp) +useAsyncData('getDoctor', () => xfetch('/api/v1/doctor'), { server: false, immediate: true }) + +async function getDoctorList() { + const resp = await xfetch('/api/v1/doctor') if (resp.success) { data.value = (resp.body as Record).data } } onMounted(() => { - getPatientList() + getDoctorList() }) provide('rec_id', recId) @@ -47,6 +47,6 @@ provide('rec_item', recItem) diff --git a/app/pages/(features)/doctor/add.vue b/app/pages/(features)/doctor/add.vue index c869c0be..3f23c8a5 100644 --- a/app/pages/(features)/doctor/add.vue +++ b/app/pages/(features)/doctor/add.vue @@ -9,8 +9,10 @@ definePageMeta({ contentFrame: 'cf-full-width', }) +const route = useRoute() + useHead({ - title: () => useRoute().meta.title as string, + title: () => route.meta.title as string, }) const roleAccess: PagePermission = PAGE_PERMISSIONS['/doctor'] diff --git a/app/pages/(features)/doctor/index.vue b/app/pages/(features)/doctor/index.vue index f947e500..19c48dde 100644 --- a/app/pages/(features)/doctor/index.vue +++ b/app/pages/(features)/doctor/index.vue @@ -9,9 +9,12 @@ definePageMeta({ contentFrame: 'cf-full-width', }) +const route = useRoute() + useHead({ - title: () => useRoute().meta.title as string, + title: () => route.meta.title as string, }) + const roleAccess: PagePermission = PAGE_PERMISSIONS['/doctor'] const { checkRole, hasReadAccess } = useRBAC()