Merge remote-tracking branch 'origin/dev' into feat/doctor

This commit is contained in:
Khafid Prayoga
2025-08-14 10:32:16 +07:00
20 changed files with 197 additions and 129 deletions
+2 -3
View File
@@ -6,7 +6,6 @@ import { Calendar, Hospital, UserCheck, UsersRound } from 'lucide-vue-next'
const data = ref([])
const refSearchNav: RefSearchNav = {
onClick: () => {
// open filter modal
},
@@ -29,7 +28,7 @@ const recItem = ref<any>(null)
const hreaderPrep: HeaderPrep = {
title: 'Pasien',
icon: 'i-lucide-add',
icon: 'i-lucide-users',
addNav: {
label: 'Tambah',
onClick: () => navigateTo('/patient/add'),
@@ -102,7 +101,7 @@ provide('rec_item', recItem)
<template>
<PubNavHeaderPrep :prep="{ ...hreaderPrep }" :ref-search-nav="refSearchNav" />
<div class="flex flex-1 flex-col gap-4 md:gap-8">
<div class="my-4 flex flex-1 flex-col gap-4 md:gap-8">
<div class="grid gap-4 md:grid-cols-2 md:gap-8 lg:grid-cols-4">
<template v-if="isLoading.summary">
<PubBaseSummaryCard v-for="n in 4" :key="n" is-skeleton />
+41 -96
View File
@@ -1,82 +1,11 @@
<script setup lang="ts">
const navMenu: any[] = [
{
heading: 'Menu Utama',
items: [
{
title: 'Dashboard',
icon: 'i-lucide-home',
link: '/',
},
{
title: 'Pasien',
icon: 'i-lucide-users',
link: '/patient',
},
{
title: 'Doctor',
icon: 'i-lucide-cross',
link: '/doctor',
},
{
title: 'Rehabilitasi Medik',
icon: 'i-lucide-heart',
link: '/rehabilitasi',
},
{
title: 'Rawat Jalan',
icon: 'i-lucide-stethoscope',
link: '/rawat-jalan',
},
{
title: 'Rawat Inap',
icon: 'i-lucide-building-2',
link: '/rawat-inap',
},
{
title: 'VClaim BPJS',
icon: 'i-lucide-refresh-cw',
link: '/vclaim',
badge: 'Live',
},
{
title: 'SATUSEHAT',
icon: 'i-lucide-database',
link: '/satusehat',
badge: 'FHIR',
},
{
title: 'Medical Records',
icon: 'i-lucide-file-text',
link: '/medical-records',
},
{
title: 'Laporan',
icon: 'i-lucide-clipboard-list',
link: '/laporan',
},
{
title: 'Monitoring',
icon: 'i-lucide-bar-chart-3',
link: '/monitoring',
},
],
},
]
const navMenuBottom: any[] = [
{
title: 'Help & Support',
icon: 'i-lucide-circle-help',
link: 'https://github.com/simrs/simrs-fe',
},
]
function resolveNavItemComponent(item: any): any {
if ('children' in item) return resolveComponent('LayoutSidebarNavGroup')
return resolveComponent('LayoutSidebarNavLink')
}
const navMenu: {
heading: string
items: Array<any>
} = ref({
heading: 'Menu Utama',
items: [],
})
const teams: {
name: string
@@ -89,39 +18,55 @@ const teams: {
plan: 'Saiful Anwar Hospital',
},
]
// const user: {
// name: string
// email: string
// avatar: string
// } = {
// name: '',
// email: '',
// avatar: '/',
// }
// const { sidebar } = useAppSettings()
const sidebar = {
collapsible: 'offcanvas', // 'offcanvas' | 'icon' | 'none'
side: 'left', // 'left' | 'right'
variant: 'sidebar', // 'sidebar' | 'floating' | 'inset'
}
const navMenuBottom: any[] = [
{
title: 'Help & Support',
icon: 'i-lucide-circle-help',
link: 'https://github.com/simrs/simrs-fe',
},
]
onMounted(async () => {
await setMenu()
})
function resolveNavItemComponent(item: any): any {
if ('children' in item) return resolveComponent('LayoutSidebarNavGroup')
return resolveComponent('LayoutSidebarNavLink')
}
async function setMenu() {
const position_code = 'sys'
const res = await fetch(`/side-menu-items/${position_code}.json`)
const rawMenu = await res.text()
navMenu.value.items = JSON.parse(rawMenu)
}
</script>
<template>
<Sidebar :collapsible="sidebar.collapsible" :side="sidebar.side" :variant="sidebar.variant">
<SidebarHeader>
<LayoutSidebarNavHeader :teams="teams" />
<!-- <Search /> -->
</SidebarHeader>
<SidebarContent>
<SidebarGroup v-for="(nav, indexGroup) in navMenu" :key="indexGroup">
<SidebarGroupLabel v-if="nav.heading">
{{ nav.heading }}
<SidebarGroup v-if="navMenu.items.length > 0">
<SidebarGroupLabel>
{{ navMenu.heading }}
</SidebarGroupLabel>
<component :is="resolveNavItemComponent(item)" v-for="(item, index) in nav.items" :key="index" :item="item"
class="mb-2" />
<component :is="resolveNavItemComponent(item)" v-for="(item, index) in navMenu.items" :key="index" :item="item"
class="my-2 mb-2" />
</SidebarGroup>
<template v-else>
<div class="p-5">
<div v-for="n in 10" :key="n" class="my-4 h-8 animate-pulse rounded bg-gray-200 py-2"></div>
</div>
</template>
<SidebarGroup class="mt-auto">
<component :is="resolveNavItemComponent(item)" v-for="(item, index) in navMenuBottom" :key="index" :item="item"
size="sm" />
+3 -3
View File
@@ -50,7 +50,7 @@ const showModalTheme = ref(false)
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
class="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
class="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg bg-white"
:side="isMobile ? 'bottom' : 'right'"
align="end"
>
@@ -76,13 +76,13 @@ const showModalTheme = ref(false)
<DropdownMenuSeparator />
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem @click="showModalTheme = true">
<DropdownMenuItem class="hover:bg-gray-100" @click="showModalTheme = true">
<Icon name="i-lucide-user" />
Profile
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem @click="handleLogout">
<DropdownMenuItem class="hover:bg-gray-100" @click="handleLogout">
<Icon name="i-lucide-log-out" />
Log out
</DropdownMenuItem>
+7 -14
View File
@@ -24,13 +24,7 @@ const openCollapsible = ref(false)
<CollapsibleTrigger as-child>
<SidebarMenuButton :tooltip="item.title" :size="size">
<Icon :name="item.icon || ''" mode="svg" />
<span>{{ item.title }}</span>
<span
v-if="item.new"
class="bg-#adfa1d rounded-md px-1.5 py-0.5 text-xs leading-none text-black no-underline group-hover:no-underline"
>
New
</span>
<span class="mx-2">{{ item.title }}</span>
<Icon
name="i-lucide-chevron-right"
class="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90"
@@ -41,14 +35,13 @@ const openCollapsible = ref(false)
<SidebarMenuSub>
<SidebarMenuSubItem v-for="subItem in item.children" :key="subItem.title">
<SidebarMenuSubButton as-child>
<NuxtLink :to="subItem.link" @click="setOpenMobile(false)">
<NuxtLink
:to="subItem.link"
class="mx-4 rounded-lg py-5 text-sm font-medium transition-all duration-200"
active-class="bg-primary text-white"
@click="setOpenMobile(false)"
>
<span>{{ subItem.title }}</span>
<span
v-if="subItem.new"
class="bg-#adfa1d rounded-md px-1.5 py-0.5 text-xs leading-none text-black no-underline group-hover:no-underline"
>
New
</span>
</NuxtLink>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
+1 -1
View File
@@ -21,7 +21,7 @@ const { setOpenMobile } = useSidebar()
<SidebarMenuButton as-child :tooltip="item.title" :size="size">
<NuxtLink
:to="item.link"
class="group flex items-center gap-3 rounded-lg px-3 py-2 text-sm font-medium transition-all duration-200"
class="group flex items-center gap-3 rounded-lg px-3 py-3 text-sm font-medium transition-all duration-200"
active-class="bg-primary text-white"
@click="setOpenMobile(false)"
>
+2 -1
View File
@@ -43,7 +43,8 @@ const router = useRouter()
</template>
<div class="mt-6 flex gap-4">
<Button variant="outline" @click="router.back()"> Kembali </Button>
<Button @click="router.push('/')"> Kembali Ke Dashboard </Button>
<Button v-if="statusCode === 401" @click="router.push('/auth/login')">Login</Button>
<Button v-else @click="router.push('/')">Kembali ke Dashboard</Button>
</div>
</div>
</div>
+1
View File
@@ -24,6 +24,7 @@ function btnClick() {
<div class="flex items-center justify-between">
<div class="flex items-center">
<div class="ml-3 text-lg font-bold text-gray-900">
<Icon :name="prep.icon" class="mr-2 h-4 w-4 align-middle" />
{{ prep.title }}
</div>
</div>