fix: solve edit + add pages

This commit is contained in:
riefive
2025-12-03 09:55:35 +07:00
203 changed files with 10884 additions and 902 deletions
+44 -2
View File
@@ -9,9 +9,15 @@ import AppViewHistory from '~/components/app/sep/view-history.vue'
import { refDebounced } from '@vueuse/core'
// Handlers
import { getDetail as getDoctorDetail } from '~/services/doctor.service'
import { useEncounterEntry } from '~/handlers/encounter-entry.handler'
<<<<<<< HEAD
import { useIntegrationSepEntry } from '~/handlers/integration-sep-entry.handler'
=======
import { genDoctor, type Doctor } from '~/models/doctor'
>>>>>>> 9a8ee9d90f669a5395b14107d86d9f788118fa92
// Props
const props = defineProps<{
id: number
classCode?: 'ambulatory' | 'emergency' | 'inpatient' | 'outpatient'
@@ -58,7 +64,33 @@ const {
const { recSepId, openHistory, histories, getMonitoringHistoryMappers } = useIntegrationSepEntry()
const debouncedSepNumber = refDebounced(sepNumber, 500)
const selectedDoctor = ref<Doctor>(genDoctor())
provide('rec_select_id', recSelectId)
provide('table_data_loader', isLoading)
watch(debouncedSepNumber, async (newValue) => {
await getValidateSepNumber(newValue)
})
watch(
() => formObjects.value?.paymentType,
(newValue) => {
isSepValid.value = false
if (newValue !== 'jkn') {
sepNumber.value = ''
}
},
)
onMounted(async () => {
await handleInit()
if (props.id > 0) {
await loadEncounterDetail()
}
})
///// Functions
function handleSavePatient() {
selectedPatientObject.value = null
setTimeout(() => {
@@ -120,6 +152,7 @@ async function handleEvent(menu: string, value?: any) {
}
}
<<<<<<< HEAD
provide('rec_select_id', recSelectId)
provide('rec_sep_id', recSepId)
provide('table_data_loader', isLoading)
@@ -151,8 +184,15 @@ onMounted(async () => {
await handleInit()
if (props.formType === 'edit' && props.id > 0) {
await getFetchEncounterDetail()
=======
async function getDoctorInfo(value: string) {
const resp = await getDoctorDetail(value, { includes: 'unit,specialist,subspecialist'})
if (resp.success) {
selectedDoctor.value = resp.body.data
// console.log(selectedDoctor.value)
>>>>>>> 9a8ee9d90f669a5395b14107d86d9f788118fa92
}
})
}
</script>
<template>
@@ -176,9 +216,11 @@ onMounted(async () => {
:seps="sepsList"
:participant-groups="participantGroupsList"
:specialists="specialistsTree"
:doctor="doctorsList"
:doctorItems="doctorsList"
:selectedDoctor="selectedDoctor"
:patient="selectedPatientObject"
:objects="formObjects"
@on-select-doctor="getDoctorInfo"
@event="handleEvent"
@fetch="handleFetch"
/>
+113 -146
View File
@@ -1,41 +1,40 @@
<script setup lang="ts">
// Components
import { Calendar, Hospital, UserCheck, UsersRound } from 'lucide-vue-next'
import SummaryCard from '~/components/pub/my-ui/summary-card/summary-card.vue'
///// Imports
// Pub components
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
import { toast } from '~/components/pub/ui/toast'
import { ActionEvents } from '~/components/pub/my-ui/data/types'
import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
import Header from '~/components/pub/my-ui/nav-header/prep.vue'
import Filter from '~/components/pub/my-ui/nav-header/filter.vue'
import * as CH from '~/components/pub/my-ui/content-header'
import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue'
import { useSidebar } from '~/components/pub/ui/sidebar/utils'
// Libs
import { getPositionAs } from '~/lib/roles'
// Types
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
import type { Summary } from '~/components/pub/my-ui/summary-card/type'
import type { HeaderPrep, RefSearchNav } from '~/components/pub/my-ui/data/types'
import { ActionEvents } from '~/components/pub/my-ui/data/types'
// App libs
import { getServicePosition } from '~/lib/roles' // previously getPositionAs
// Services
import { getList as getEncounterList, remove as removeEncounter, cancel as cancelEncounter } from '~/services/encounter.service'
// UI
import { toast } from '~/components/pub/ui/toast'
// Apps
import Content from '~/components/app/encounter/list.vue'
import FilterNav from '~/components/app/encounter/filter-nav.vue'
import FilterForm from '~/components/app/encounter/filter-form.vue'
// Props
const props = defineProps<{
classCode?: 'ambulatory' | 'emergency' | 'inpatient'
subClassCode?: 'reg' | 'rehab' | 'chemo' | 'emg' | 'eon' | 'op' | 'icu' | 'hcu' | 'vk'
canCreate?: boolean
canUpdate?: boolean
canDelete?: boolean
}>()
///// Declarations and Flows
// Sidebar automation
const { setOpen } = useSidebar()
setOpen(true)
const { getActiveRole } = useUserStore()
const activeRole = getActiveRole()
const activePosition = ref(getPositionAs(activeRole))
const props = defineProps<{
classCode?: 'ambulatory' | 'emergency' | 'inpatient' | 'outpatient'
subClassCode?: 'reg' | 'rehab' | 'chemo' | 'emg' | 'eon' | 'op' | 'icu' | 'hcu' | 'vk'
type: string
}>()
// Main data
const data = ref([])
const isLoading = reactive<DataTableLoader>({
summary: false,
@@ -44,67 +43,88 @@ const isLoading = reactive<DataTableLoader>({
const recId = ref<number>(0)
const recAction = ref<string>('')
const recItem = ref<any>(null)
const isFormEntryDialogOpen = ref(false)
const isFilterFormDialogOpen = ref(false)
const isRecordConfirmationOpen = ref(false)
const isRecordCancelOpen = ref(false)
const hreaderPrep: HeaderPrep = {
// Headers
const hreaderPrep: CH.Config = {
title: 'Kunjungan',
icon: 'i-lucide-users',
addNav: {
label: 'Tambah',
onClick: () => {
if (props.classCode === 'ambulatory' && props.subClassCode === 'rehab') {
navigateTo('/rehab/encounter/add')
}
if (props.classCode === 'ambulatory' && props.subClassCode === 'reg') {
navigateTo('/outpatient/encounter/add')
}
if (props.classCode === 'emergency') {
navigateTo('/emergency/encounter/add')
}
if (props.classCode === 'inpatient') {
navigateTo('/inpatient/encounter/add')
}
navigateTo(`/${props.classCode}/encounter/add`)
},
},
}
const refSearchNav: RefSearchNav = {
onClick: () => {
// open filter modal
isFormEntryDialogOpen.value = true
console.log(' 1open filter modal')
},
onInput: (_val: string) => {
// filter patient list
},
onClear: () => {
// clear url param
},
if (!props.canCreate) {
delete hreaderPrep.addNav
}
// Loading state management
// Filters
const filter = ref<{
installation: {
msg: {
placeholder: string
}
items: {
value: string
label: string
code: string
}[]
}
schema: any
initialValues?: Partial<any>
errors?: any
}>({
installation: {
msg: {
placeholder: 'Pilih',
},
items: [],
},
schema: {},
})
/**
* Get base path for encounter routes based on classCode and subClassCode
*/
function getBasePath(): string {
if (props.classCode === 'ambulatory' && props.subClassCode === 'rehab') {
return '/rehab/encounter'
}
if (props.classCode === 'ambulatory' && props.subClassCode === 'reg') {
return '/outpatient/encounter'
}
if (props.classCode === 'emergency') {
return '/emergency/encounter'
}
if (props.classCode === 'inpatient') {
return '/inpatient/encounter'
}
return '/encounter' // fallback
}
// Role reactivities
const { getActiveRole } = useUserStore()
const activeServicePosition = ref(getServicePosition(getActiveRole()))
provide('activeServicePosition', activeServicePosition)
watch(getActiveRole, (role? : string) => {
activeServicePosition.value = getServicePosition(role)
})
// Recrod reactivities
provide('rec_id', recId)
provide('rec_action', recAction)
provide('rec_item', recItem)
provide('table_data_loader', isLoading)
watch(() => recAction.value, () => {
const basePath = `/${props.classCode}/encounter`
// console.log(`${basePath}/${recId.value}`, recAction.value)
// return
if (recAction.value === ActionEvents.showConfirmDelete) {
isRecordConfirmationOpen.value = true
} else if (recAction.value === ActionEvents.showCancel) {
isRecordCancelOpen.value = true
} else if (recAction.value === ActionEvents.showDetail) {
navigateTo(`${basePath}/${recId.value}`)
} else if (recAction.value === ActionEvents.showEdit) {
navigateTo(`${basePath}/${recId.value}/edit`)
} else if (recAction.value === ActionEvents.showProcess) {
navigateTo(`${basePath}/${recId.value}/process`)
} else if (recAction.value === ActionEvents.showConfirmDelete) {
isRecordConfirmationOpen.value = true
}
recAction.value = '' // reset
})
onMounted(() => {
getPatientList()
})
/////// Functions
async function getPatientList() {
isLoading.isTableLoading = true
try {
@@ -215,94 +235,32 @@ function handleRemoveConfirmation() {
recItem.value = null
isRecordConfirmationOpen.value = false
}
watch(
() => recAction.value,
() => {
if (recAction.value === ActionEvents.showConfirmDelete) {
isRecordConfirmationOpen.value = true
return
}
if (recAction.value === ActionEvents.showCancel) {
isRecordCancelOpen.value = true
return
}
const basePath = getBasePath()
if (props.type === 'encounter') {
if (recAction.value === 'showDetail') {
navigateTo(`${basePath}/${recId.value}/detail`)
} else if (recAction.value === 'showEdit') {
navigateTo(`${basePath}/${recId.value}/process`)
} else if (recAction.value === 'showPrint') {
console.log('print')
} else {
// handle other actions
}
} else if (props.type === 'registration') {
// Handle registration type if needed
if (recAction.value === 'showDetail') {
navigateTo(`${basePath.replace('/encounter', '/registration')}/${recId.value}/detail`)
} else if (recAction.value === 'showEdit') {
navigateTo(`${basePath.replace('/encounter', '/registration')}/${recId.value}/edit`)
} else if (recAction.value === 'showProcess') {
navigateTo(`${basePath.replace('/encounter', '/registration')}/${recId.value}/process`)
} else {
// handle other actions
}
}
},
)
watch(getActiveRole, () => {
const activeRole = getActiveRole()
activePosition.value = getPositionAs(activeRole)
})
provide('rec_id', recId)
provide('rec_action', recAction)
provide('rec_item', recItem)
provide('table_data_loader', isLoading)
provide('position', activePosition)
onMounted(() => {
getPatientList()
})
</script>
<template>
<Header
:prep="{ ...hreaderPrep }"
:ref-search-nav="refSearchNav"
/>
<Separator class="my-4 xl:my-5" />
<CH.ContentHeader v-bind="hreaderPrep">
<FilterNav
@onFilterClick="() => isFilterFormDialogOpen = true"
@onExportPdf="() => {}"
@onExportExcel="() => {}"
@nExportCsv="() => {}"
/>
</CH.ContentHeader>
<Filter
:prep="hreaderPrep"
:ref-search-nav="refSearchNav"
/>
<AppEncounterList :data="data" />
<Content :data="data" />
<!-- Filter -->
<Dialog
v-model:open="isFormEntryDialogOpen"
v-model:open="isFilterFormDialogOpen"
title="Filter"
size="lg"
prevent-outside
>
<AppEncounterFilter
:installation="{
msg: { placeholder: 'Pilih' },
items: [],
}"
:schema="{}"
/>
<FilterForm v-bind="filter" />
</Dialog>
<!-- Record Confirmation Modal -->
<RecordConfirmation
<!-- Batal -->
<RecordConfirmation
v-model:open="isRecordCancelOpen"
custom-title="Batalkan Kunjungan"
custom-message="Apakah anda yakin ingin membatalkan kunjungan pasien berikut?"
@@ -325,7 +283,9 @@ onMounted(() => {
</template>
</RecordConfirmation>
<!-- Hapus -->
<RecordConfirmation
v-if="canDelete"
v-model:open="isRecordConfirmationOpen"
action="delete"
:record="recItem"
@@ -349,4 +309,11 @@ onMounted(() => {
</div>
</template>
</RecordConfirmation>
<Dialog
title="Hapus data"
size="md"
v-model:open="isRecordConfirmationOpen"
>
Hak akses tidak memenuhi kriteria untuk proses ini.
</Dialog>
</template>
@@ -0,0 +1,114 @@
<script setup lang="ts">
//
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { getDetail } from '~/services/encounter.service'
//
import type { TabItem } from '~/components/pub/my-ui/comp-tab/type'
import CompTab from '~/components/pub/my-ui/comp-tab/comp-tab.vue'
import { genEncounter } from '~/models/encounter'
// PLASE ORDER BY TAB POSITION
import Status from '~/components/content/encounter/status.vue'
import AssesmentFunctionList from '~/components/content/soapi/entry.vue'
import EarlyMedicalAssesmentList from '~/components/content/soapi/entry.vue'
import EarlyMedicalRehabList from '~/components/content/soapi/entry.vue'
import DeviceOrder from '~/components/content/device-order/main.vue'
import Prescription from '~/components/content/prescription/main.vue'
import CpLabOrder from '~/components/content/cp-lab-order/main.vue'
import Radiology from '~/components/content/radiology-order/main.vue'
import Consultation from '~/components/content/consultation/list.vue'
import Cprj from '~/components/content/cprj/entry.vue'
import DocUploadList from '~/components/content/document-upload/list.vue'
import GeneralConsentList from '~/components/content/general-consent/entry.vue'
import ResumeList from '~/components/content/resume/list.vue'
import ControlLetterList from '~/components/content/control-letter/list.vue'
const route = useRoute()
const router = useRouter()
// activeTab selalu sinkron dengan query param
const activeTab = computed({
get: () => (route.query?.tab && typeof route.query.tab === 'string' ? route.query.tab : 'status'),
set: (val: string) => {
router.replace({ path: route.path, query: { tab: val } })
},
})
const id = typeof route.params.id == 'string' ? parseInt(route.params.id) : 0
const data = ref(genEncounter())
async function fetchDetail() {
const res = await getDetail(id, {
includes:
'patient,patient-person,patient-person-addresses,unit,Appointment_Doctor,Appointment_Doctor-employee,Appointment_Doctor-employee-person,EncounterDocuments',
})
if (res.body?.data) data.value = res.body?.data
}
onMounted(() => {
fetchDetail()
})
const tabs: TabItem[] = [
{ value: 'status', label: 'Status Masuk/Keluar', component: Status, props: { encounter: data } },
{
value: 'early-medical-assessment',
label: 'Pengkajian Awal Medis',
component: EarlyMedicalAssesmentList,
props: { encounter: data, type: 'early-medic', label: 'Pengkajian Awal Medis' },
},
{
value: 'rehab-medical-assessment',
label: 'Pengkajian Awal Medis Rehabilitasi Medis',
component: EarlyMedicalRehabList,
props: { encounter: data, type: 'early-rehab', label: 'Pengkajian Awal Medis Rehabilitasi Medis' },
},
{
value: 'function-assessment',
label: 'Asesmen Fungsi',
component: AssesmentFunctionList,
props: { encounter: data, type: 'function', label: 'Asesmen Fungsi' },
},
{ value: 'therapy-protocol', label: 'Protokol Terapi' },
{ value: 'education-assessment', label: 'Asesmen Kebutuhan Edukasi' },
{ value: 'patient-note', label: 'CPRJ', component: Cprj, props: { encounter: data } },
{ value: 'consent', label: 'General Consent', component: GeneralConsentList, props: { encounter: data } },
{ value: 'prescription', label: 'Order Obat', component: Prescription, props: { encounter_id: data.value.id } },
{ value: 'device-order', label: 'Order Alkes', component: DeviceOrder, props: { encounter_id: data.value.id } },
{ value: 'device', label: 'Order Alkes' },
{ value: 'mcu-radiology', label: 'Order Radiologi', component: Radiology, props: { encounter_id: data.id } },
{ value: 'mcu-lab-cp', label: 'Order Lab PK', component: CpLabOrder, props: { encounter_id: data.id } },
{ value: 'mcu-lab-micro', label: 'Order Lab Mikro' },
{ value: 'mcu-lab-pa', label: 'Order Lab PA' },
{ value: 'medical-action', label: 'Order Ruang Tindakan' },
{ value: 'mcu-result', label: 'Hasil Penunjang' },
{ value: 'consultation', label: 'Konsultasi', component: Consultation, props: { encounter: data } },
{ value: 'resume', label: 'Resume', component: ResumeList, props: { encounter: data } },
{ value: 'control', label: 'Surat Kontrol', component: ControlLetterList, props: { encounter: data } },
{ value: 'screening', label: 'Skrinning MPP' },
{
value: 'supporting-document',
label: 'Upload Dokumen Pendukung',
component: DocUploadList,
props: { encounter: data },
},
]
</script>
<template>
<div class="w-full">
<div class="mb-4">
<PubMyUiNavContentBa label="Kembali ke Daftar Kunjungan" />
</div>
<AppEncounterQuickInfo :data="data" />
<CompTab
:data="tabs"
:initial-active-tab="activeTab"
@change-tab="activeTab = $event"
/>
</div>
</template>
@@ -1,132 +0,0 @@
<script setup lang="ts">
import { computed } from 'vue'
// Pubs components
import ContentSwitcher from '~/components/pub/my-ui/content-switcher/content-switcher.vue'
import { useSidebar } from '~/components/pub/ui/sidebar/utils'
// Components
import EncounterPatientInfo from '~/components/app/encounter/quick-info-full.vue'
import EncounterHistoryButtonMenu from '~/components/app/encounter/quick-shortcut.vue'
import SubMenu from '~/components/pub/my-ui/menus/submenu.vue'
// Libraries
import { getPositionAs } from '~/lib/roles'
// Models
import { genEncounter } from '~/models/encounter'
// Types
import type { EncounterProps } from '~/handlers/encounter-init.handler'
// Handlers
import { getEncounterData } from '~/handlers/encounter-process.handler'
import { getMenuItems } from "~/handlers/encounter-init.handler"
const { user, getActiveRole } = useUserStore()
const route = useRoute()
const router = useRouter()
const props = defineProps<{
classCode?: EncounterProps['classCode']
subClassCode?: EncounterProps['subClassCode']
}>()
const activeRole = getActiveRole()
const activePosition = ref(getPositionAs(activeRole))
const menus = ref([] as any)
const activeMenu = computed({
get: () => (route.query?.menu && typeof route.query.menu === 'string' ? route.query.menu : 'status'),
set: (value: string) => {
router.replace({ path: route.path, query: { menu: value } })
},
})
const id = typeof route.params.id == 'string' ? parseInt(route.params.id) : 0
const data = ref<any>(genEncounter())
const isShowPatient = computed(() => data.value && data.value?.patient?.person)
const { setOpen } = useSidebar()
setOpen(false)
if (activePosition.value === 'none') { // if user position is none, redirect to home page
router.push('/')
}
// Dummy rows for ProtocolList (matches keys expected by list-cfg.protocol)
const protocolRows = [
{
number: '1',
tanggal: new Date().toISOString().substring(0, 10),
siklus: 'I',
periode: 'Siklus I',
kehadiran: 'Hadir',
action: '',
},
{
number: '2',
tanggal: new Date().toISOString().substring(0, 10),
siklus: 'II',
periode: 'Siklus II',
kehadiran: 'Tidak Hadir',
action: '',
},
]
const paginationMeta = {
recordCount: protocolRows.length,
page: 1,
pageSize: 10,
totalPage: 1,
hasNext: false,
hasPrev: false,
}
function handleClick(type: string) {
if (type === 'draft') {
router.back()
}
}
function initMenus() {
menus.value = getMenuItems(id, props, user, {
encounter: data.value
} as any, {
protocolTheraphy: paginationMeta,
protocolChemotherapy: paginationMeta,
medicineProtocolChemotherapy: paginationMeta,
})
}
async function getData() {
data.value = await getEncounterData(id)
}
watch(getActiveRole, () => {
const activeRole = getActiveRole()
activePosition.value = getPositionAs(activeRole)
initMenus()
})
onMounted(async () => {
await getData()
initMenus()
})
</script>
<template>
<div class="w-full">
<div class="mb-4">
<PubMyUiNavContentBa label="Kembali ke Daftar Kunjungan" @click="handleClick" />
</div>
<ContentSwitcher :active="1" :height="200">
<template v-slot:content1>
<EncounterPatientInfo v-if="isShowPatient" :data="data" />
</template>
<template v-slot:content2>
<EncounterHistoryButtonMenu v-if="isShowPatient" />
</template>
</ContentSwitcher>
<SubMenu :data="menus" :initial-active-menu="activeMenu" @change-menu="activeMenu = $event" />
</div>
</template>
+113 -85
View File
@@ -1,114 +1,142 @@
<script setup lang="ts">
//
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
///// Imports
// Pubs components
import ContentSwitcher from '~/components/pub/my-ui/content-switcher/content-switcher.vue'
import { useSidebar } from '~/components/pub/ui/sidebar/utils'
import SubMenu from '~/components/pub/my-ui/menus/submenu.vue'
import ContentNavBa from '~/components/pub/my-ui/nav-content/ba.vue'
import { getDetail } from '~/services/encounter.service'
// App libs
import { getServicePosition } from '~/lib/roles' // previously getPositionAs
//
import type { TabItem } from '~/components/pub/my-ui/comp-tab/type'
import CompTab from '~/components/pub/my-ui/comp-tab/comp-tab.vue'
// App Models
import { genEncounter, type Encounter } from '~/models/encounter'
import { genEncounter } from '~/models/encounter'
// Handlers
import type { EncounterProps } from '~/handlers/encounter-init.handler'
import { getEncounterData } from '~/handlers/encounter-process.handler'
import { getMenuItems } from "~/handlers/encounter-init.handler"
// PLASE ORDER BY TAB POSITION
import Status from '~/components/content/encounter/status.vue'
import AssesmentFunctionList from '~/components/content/soapi/entry.vue'
import EarlyMedicalAssesmentList from '~/components/content/soapi/entry.vue'
import EarlyMedicalRehabList from '~/components/content/soapi/entry.vue'
import DeviceOrder from '~/components/content/device-order/main.vue'
import Prescription from '~/components/content/prescription/main.vue'
import CpLabOrder from '~/components/content/cp-lab-order/main.vue'
import Radiology from '~/components/content/radiology-order/main.vue'
import Consultation from '~/components/content/consultation/list.vue'
import Cprj from '~/components/content/cprj/entry.vue'
import DocUploadList from '~/components/content/document-upload/list.vue'
import GeneralConsentList from '~/components/content/general-consent/entry.vue'
import ResumeList from '~/components/content/resume/list.vue'
import ControlLetterList from '~/components/content/control-letter/list.vue'
// App Components
import EncounterPatientInfo from '~/components/app/encounter/quick-info.vue'
import EncounterHistoryButtonMenu from '~/components/app/encounter/quick-shortcut.vue'
///// Declarations and Flows
// Props
const props = defineProps<{
classCode: EncounterProps['classCode']
subClassCode?: EncounterProps['subClassCode']
}>()
// Common preparations
const route = useRoute()
const router = useRouter()
// activeTab selalu sinkron dengan query param
const activeTab = computed({
get: () => (route.query?.tab && typeof route.query.tab === 'string' ? route.query.tab : 'status'),
set: (val: string) => {
router.replace({ path: route.path, query: { tab: val } })
const { user, userActiveRole, getActiveRole } = useUserStore()
const activeRole = getActiveRole()
const activePosition = ref(getServicePosition(activeRole))
const menus = ref([] as any)
const activeMenu = computed({
get: () => (route.query?.menu && typeof route.query.menu === 'string' ? route.query.menu : 'status'),
set: (value: string) => {
router.replace({ path: route.path, query: { menu: value } })
},
})
const id = typeof route.params.id == 'string' ? parseInt(route.params.id) : 0
const data = ref(genEncounter())
const data = ref<Encounter>(genEncounter())
const isShowPatient = computed(() => data.value && data.value?.patient?.person)
async function fetchDetail() {
const res = await getDetail(id, {
includes:
'patient,patient-person,patient-person-addresses,unit,Appointment_Doctor,Appointment_Doctor-employee,Appointment_Doctor-employee-person,EncounterDocuments',
})
if (res.body?.data) data.value = res.body?.data
const { setOpen } = useSidebar()
setOpen(false)
if (activePosition.value === 'none') { // if user position is none, redirect to home page
router.push('/')
}
onMounted(() => {
fetchDetail()
})
const tabs: TabItem[] = [
{ value: 'status', label: 'Status Masuk/Keluar', component: Status, props: { encounter: data } },
// Dummy rows for ProtocolList (matches keys expected by list-cfg.protocol)
const protocolRows = [
{
value: 'early-medical-assessment',
label: 'Pengkajian Awal Medis',
component: EarlyMedicalAssesmentList,
props: { encounter: data, type: 'early-medic', label: 'Pengkajian Awal Medis' },
number: '1',
tanggal: new Date().toISOString().substring(0, 10),
siklus: 'I',
periode: 'Siklus I',
kehadiran: 'Hadir',
action: '',
},
{
value: 'rehab-medical-assessment',
label: 'Pengkajian Awal Medis Rehabilitasi Medis',
component: EarlyMedicalRehabList,
props: { encounter: data, type: 'early-rehab', label: 'Pengkajian Awal Medis Rehabilitasi Medis' },
},
{
value: 'function-assessment',
label: 'Asesmen Fungsi',
component: AssesmentFunctionList,
props: { encounter: data, type: 'function', label: 'Asesmen Fungsi' },
},
{ value: 'therapy-protocol', label: 'Protokol Terapi' },
{ value: 'education-assessment', label: 'Asesmen Kebutuhan Edukasi' },
{ value: 'patient-note', label: 'CPRJ', component: Cprj, props: { encounter: data } },
{ value: 'consent', label: 'General Consent', component: GeneralConsentList, props: { encounter: data } },
{ value: 'prescription', label: 'Order Obat', component: Prescription, props: { encounter_id: data.value.id } },
{ value: 'device-order', label: 'Order Alkes', component: DeviceOrder, props: { encounter_id: data.value.id } },
{ value: 'device', label: 'Order Alkes' },
{ value: 'mcu-radiology', label: 'Order Radiologi', component: Radiology, props: { encounter_id: data.id } },
{ value: 'mcu-lab-cp', label: 'Order Lab PK', component: CpLabOrder, props: { encounter_id: data.id } },
{ value: 'mcu-lab-micro', label: 'Order Lab Mikro' },
{ value: 'mcu-lab-pa', label: 'Order Lab PA' },
{ value: 'medical-action', label: 'Order Ruang Tindakan' },
{ value: 'mcu-result', label: 'Hasil Penunjang' },
{ value: 'consultation', label: 'Konsultasi', component: Consultation, props: { encounter: data } },
{ value: 'resume', label: 'Resume', component: ResumeList, props: { encounter: data } },
{ value: 'control', label: 'Surat Kontrol', component: ControlLetterList, props: { encounter: data } },
{ value: 'screening', label: 'Skrinning MPP' },
{
value: 'supporting-document',
label: 'Upload Dokumen Pendukung',
component: DocUploadList,
props: { encounter: data },
number: '2',
tanggal: new Date().toISOString().substring(0, 10),
siklus: 'II',
periode: 'Siklus II',
kehadiran: 'Tidak Hadir',
action: '',
},
]
const paginationMeta = {
recordCount: protocolRows.length,
page: 1,
pageSize: 10,
totalPage: 1,
hasNext: false,
hasPrev: false,
}
// Reacrtivities
watch(getActiveRole, () => {
activePosition.value = getServicePosition(userActiveRole)
initMenus()
})
onMounted(async () => {
await getData()
initMenus()
})
///// Functions
function handleClick(type: string) {
if (type === 'draft') {
router.back()
}
}
function initMenus() {
menus.value = getMenuItems(id, props, user, {
encounter: data.value
} as any, {
protocolTheraphy: paginationMeta,
protocolChemotherapy: paginationMeta,
medicineProtocolChemotherapy: paginationMeta,
})
}
async function getData() {
data.value = await getEncounterData(id)
}
</script>
<template>
<div class="w-full">
<div class="mb-4">
<PubMyUiNavContentBa label="Kembali ke Daftar Kunjungan" />
<div class="bg-white dark:bg-slate-800 p-4 2xl:p-5">
<div class="mb-4 flex">
<div>
<ContentNavBa label="Kembali" @click="handleClick" />
</div>
<!-- <div class="ms-auto pe-3 pt-1 text-end text-xl 2xl:text-2xl font-semibold">
Pasien: {{ data.patient.person.name }} --- No. RM: {{ data.patient.number }}
</div> -->
</div>
<ContentSwitcher :active="1" :height="150">
<template v-slot:content1>
<EncounterPatientInfo v-if="isShowPatient" :data="data" />
</template>
<template v-slot:content2>
<EncounterHistoryButtonMenu v-if="isShowPatient" />
</template>
</ContentSwitcher>
</div>
<AppEncounterQuickInfo :data="data" />
<CompTab
:data="tabs"
:initial-active-tab="activeTab"
@change-tab="activeTab = $event"
/>
<SubMenu :data="menus" :initial-active-menu="activeMenu" @change-menu="activeMenu = $event" />
</div>
</template>