feat/encounter-adjustment: adjust menu
This commit is contained in:
@@ -36,7 +36,7 @@ const dpjp = computed(() => {
|
||||
return '-'
|
||||
})
|
||||
|
||||
// Tanggal Lahir dengan Umur
|
||||
// Tgl. Lahir dengan Umur
|
||||
const birthDateFormatted = computed(() => {
|
||||
if (!props.data.patient.person.birthDate) {
|
||||
return '-'
|
||||
@@ -50,7 +50,7 @@ const birthDateFormatted = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// Tanggal Masuk RS dengan waktu
|
||||
// Tgl. Masuk RS dengan waktu
|
||||
const registeredDateFormatted = computed(() => {
|
||||
const dateStr = props.data.registeredAt || props.data.visitDate
|
||||
if (!dateStr) {
|
||||
@@ -64,7 +64,7 @@ const registeredDateFormatted = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// Jenis Kelamin
|
||||
// Jns. Kelamin
|
||||
const genderLabel = computed(() => {
|
||||
const code = props.data.patient.person.gender_code
|
||||
if (!code) return '-'
|
||||
@@ -77,7 +77,7 @@ const genderLabel = computed(() => {
|
||||
return code
|
||||
})
|
||||
|
||||
// Jenis Pembayaran
|
||||
// Jns. Pembayaran
|
||||
const paymentTypeLabel = computed(() => {
|
||||
const code = props.data.paymentMethod_code
|
||||
if (!code) return '-'
|
||||
@@ -142,30 +142,31 @@ const bedNumber = computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h2 class="mb-4 font-semibold md:text-base 2xl:text-lg">Data Pasien:</h2>
|
||||
<!-- 4 Column Grid Layout -->
|
||||
<div :class="cn('grid grid-cols-1 gap-4', isGrid && 'sm:grid-cols-4')">
|
||||
<div :class="cn('grid grid-cols-4 gap-4', isGrid && 'sm:grid-cols-4')">
|
||||
<!-- No. RM -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No. RM</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No. RM</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ data.patient.number || '-' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Tanggal Lahir -->
|
||||
<!-- Tgl. Lahir -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Tanggal Lahir</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Tgl. Lahir</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ birthDateFormatted }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Jenis Pembayaran -->
|
||||
<!-- Jns. Pembayaran -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Jenis Pembayaran</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Cara Bayar</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ paymentTypeLabel }}
|
||||
</p>
|
||||
@@ -173,8 +174,8 @@ const bedNumber = computed(() => {
|
||||
|
||||
<!-- No Bed -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No Bed</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No Bed</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ bedNumber }}
|
||||
</p>
|
||||
@@ -182,17 +183,17 @@ const bedNumber = computed(() => {
|
||||
|
||||
<!-- Nama Pasien -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No. Bed</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No. Bed</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ data.patient.person.name || '-' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Tanggal Masuk RS -->
|
||||
<!-- Tgl. Masuk RS -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Tanggal Masuk RS</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Tgl. Masuk RS</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ registeredDateFormatted }}
|
||||
</p>
|
||||
@@ -200,8 +201,8 @@ const bedNumber = computed(() => {
|
||||
|
||||
<!-- No. Billing -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No. Billing</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">No. Billing</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ billingNumber }}
|
||||
</p>
|
||||
@@ -209,8 +210,8 @@ const bedNumber = computed(() => {
|
||||
|
||||
<!-- DPJP -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">DPJP</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">DPJP</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ dpjp }}
|
||||
</p>
|
||||
@@ -218,17 +219,17 @@ const bedNumber = computed(() => {
|
||||
|
||||
<!-- Alamat -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Alamat</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Alamat</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ address }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Jenis Kelamin -->
|
||||
<!-- Jns. Kelamin -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Jenis Kelamin</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Jns. Kelamin</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ genderLabel }}
|
||||
</p>
|
||||
@@ -236,8 +237,8 @@ const bedNumber = computed(() => {
|
||||
|
||||
<!-- Nama Ruang -->
|
||||
<div class="flex gap-1">
|
||||
<label class="w-[150px] flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Nama Ruang</label>
|
||||
<label class="w-[20px] flex-none">:</label>
|
||||
<label class="w-20 2xl:w-24 flex-none text-sm font-semibold text-gray-700 dark:text-gray-300">Nama Ruang</label>
|
||||
<label class="w-2 flex-none">:</label>
|
||||
<p class="flex-1 text-sm text-gray-900 dark:text-gray-100">
|
||||
{{ roomName }}
|
||||
</p>
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<script setup lang="ts">
|
||||
// Components
|
||||
import { Button } from '~/components/pub/ui/button'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
// Track active menu item from query param
|
||||
const activeMenu = computed(() => route.query.menu as string || '')
|
||||
|
||||
interface ButtonItems {
|
||||
label: string
|
||||
icon: string
|
||||
value: string
|
||||
type: 'icon' | 'image'
|
||||
}
|
||||
|
||||
const itemsOne: ButtonItems[] = [
|
||||
{
|
||||
label: 'Data Pendaftaran',
|
||||
icon: 'i-lucide-file',
|
||||
value: 'register',
|
||||
type: 'icon',
|
||||
},
|
||||
{
|
||||
label: 'Status Pembayaran',
|
||||
icon: 'i-lucide-banknote-arrow-down',
|
||||
value: 'status',
|
||||
type: 'icon',
|
||||
},
|
||||
{
|
||||
label: 'Riwayat Pasien',
|
||||
icon: 'i-lucide-history',
|
||||
value: 'history',
|
||||
type: 'icon',
|
||||
},
|
||||
{
|
||||
label: 'Penunjang',
|
||||
icon: 'i-lucide-library-big',
|
||||
value: 'support',
|
||||
type: 'icon',
|
||||
},
|
||||
{
|
||||
label: 'Resep',
|
||||
icon: 'i-lucide-pill',
|
||||
value: 'receipt',
|
||||
type: 'icon',
|
||||
},
|
||||
{
|
||||
label: 'DPJP',
|
||||
icon: 'i-lucide-stethoscope',
|
||||
value: 'doctor',
|
||||
type: 'icon',
|
||||
},
|
||||
{
|
||||
label: 'I-Care BPJS',
|
||||
icon: '/bpjs.png',
|
||||
value: 'bpjs',
|
||||
type: 'image',
|
||||
},
|
||||
{
|
||||
label: 'File SEP',
|
||||
icon: 'i-lucide-file',
|
||||
value: 'sep',
|
||||
type: 'icon',
|
||||
},
|
||||
]
|
||||
|
||||
const itemsTwo: ButtonItems[] = [
|
||||
{
|
||||
label: 'Tarif Tindakan',
|
||||
icon: 'i-lucide-banknote-arrow-down',
|
||||
value: 'price-list',
|
||||
type: 'icon',
|
||||
},
|
||||
{
|
||||
label: 'Tarif Tindakan Paket',
|
||||
icon: 'i-lucide-banknote-arrow-down',
|
||||
value: 'price-list-package',
|
||||
type: 'icon',
|
||||
},
|
||||
]
|
||||
|
||||
function handleClick(value: string) {
|
||||
router.replace({ path: route.path, query: { menu: value } })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h2 class="mb-4 font-semibold md:text-base 2xl:text-lg">Menu Cepat:</h2>
|
||||
<div class="flex flex-wrap gap-2 mb-2">
|
||||
<Button
|
||||
v-for="item in itemsOne"
|
||||
:key="item.value"
|
||||
:class="[
|
||||
'flex items-center gap-2 rounded-lg border px-3 py-1 text-sm font-medium transition-colors',
|
||||
activeMenu === item.value
|
||||
? 'border-orange-300 bg-orange-400 text-white'
|
||||
: 'border-orange-300 bg-white text-orange-500 hover:bg-orange-400 hover:text-white'
|
||||
]"
|
||||
@click="handleClick(item.value)"
|
||||
>
|
||||
<Icon v-if="item.type === 'icon'"
|
||||
:name="item.icon"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
<img v-else-if="item.type === 'image'" :src="item.icon" class="h-[24px] w-[24px] object-contain" />
|
||||
{{ item.label }}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2 mb-2">
|
||||
<Button
|
||||
v-for="item in itemsTwo"
|
||||
:key="item.value"
|
||||
:class="[
|
||||
'flex items-center gap-2 rounded-lg border px-3 py-1 text-sm font-medium transition-colors',
|
||||
activeMenu === item.value
|
||||
? 'border-orange-300 bg-orange-400 text-white'
|
||||
: 'border-orange-300 bg-white text-orange-500 hover:bg-orange-400 hover:text-white'
|
||||
]"
|
||||
@click="handleClick(item.value)"
|
||||
>
|
||||
<Icon
|
||||
:name="item.icon"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
{{ item.label }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,10 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
// 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/patient-info-collapsible.vue'
|
||||
import EncounterHistoryButtonMenu from '~/components/app/encounter/history-button-menu.vue'
|
||||
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
|
||||
@@ -43,6 +46,9 @@ 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('/')
|
||||
}
|
||||
@@ -113,8 +119,14 @@ onMounted(async () => {
|
||||
<div class="mb-4">
|
||||
<PubMyUiNavContentBa label="Kembali ke Daftar Kunjungan" @click="handleClick" />
|
||||
</div>
|
||||
<EncounterPatientInfo v-if="isShowPatient" :data="data" />
|
||||
<EncounterHistoryButtonMenu v-if="isShowPatient" />
|
||||
<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>
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
height: 200
|
||||
activeTab?: 1 | 2
|
||||
}>()
|
||||
|
||||
const activeTab = ref(props.activeTab || 1)
|
||||
|
||||
function handleClick(value: 1 | 2) {
|
||||
activeTab.value = value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="content-switcher" :style="`height: ${height}px`">
|
||||
<div :class="`${activeTab === 1 ? 'active' : 'inactive'}`">
|
||||
<div class="content-wrapper">
|
||||
<div>
|
||||
<slot name="content1" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-nav">
|
||||
<button @click="handleClick(1)">
|
||||
<Icon name="i-lucide-chevron-right" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="`${activeTab === 2 ? 'active' : 'inactive'}`">
|
||||
<div class="content-nav">
|
||||
<button @click="handleClick(2)">
|
||||
<Icon name="i-lucide-chevron-left" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="content-wrapper">
|
||||
<div>
|
||||
<slot name="content2" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.content-switcher {
|
||||
@apply flex overflow-hidden gap-3
|
||||
}
|
||||
.content-switcher > * {
|
||||
@apply border border-slate-300 rounded-md flex overflow-hidden
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
@apply p-4 2xl:p-5 overflow-hidden
|
||||
}
|
||||
.inactive .content-wrapper {
|
||||
@apply p-0 w-0
|
||||
}
|
||||
|
||||
.content-nav {
|
||||
@apply h-full flex flex-row items-center justify-center content-center !text-2xl overflow-hidden
|
||||
}
|
||||
|
||||
.content-nav button {
|
||||
@apply pt-2 px-2 h-full w-full
|
||||
}
|
||||
|
||||
/* .content-switcher .inactive > .content-wrapper {
|
||||
@apply w-0 p-0 opacity-0 transition-all duration-500 ease-in-out
|
||||
} */
|
||||
.content-switcher .inactive {
|
||||
@apply w-16 transition-all duration-500 ease-in-out
|
||||
}
|
||||
.content-switcher .inactive > .content-nav {
|
||||
@apply w-full transition-all duration-100 ease-in-out
|
||||
}
|
||||
|
||||
.content-switcher .active {
|
||||
@apply grow transition-all duration-500 ease-in-out
|
||||
}
|
||||
.content-switcher .active > .content-nav {
|
||||
@apply w-0 transition-all duration-100 ease-in-out
|
||||
}
|
||||
/* .content-switcher .active > .content-wrapper {
|
||||
@apply w-full delay-1000 transition-all duration-1000 ease-in-out
|
||||
} */
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user