feat (appsidebar): load menu from json file

This commit is contained in:
Abizrh
2025-08-13 15:19:03 +07:00
parent a6558e312b
commit f89cd09646
2 changed files with 115 additions and 111 deletions
+40 -111
View File
@@ -1,98 +1,11 @@
<script setup lang="ts">
const navMenu: any[] = [
{
heading: 'Menu Utama',
items: [
{
title: 'Dashboard',
icon: 'i-lucide-home',
link: '/',
},
{
title: 'Rawat Jalan',
icon: 'i-lucide-stethoscope',
children: [
{
title: 'Antrian Pendaftaran',
icon: 'i-lucide-stethoscope',
link: '/outpatient/registration-queue',
},
{
title: 'Pendaftaran',
icon: 'i-lucide-building-2',
link: '/outpatient/registration',
},
{
title: 'Antrian Pemeriksaan',
icon: 'i-lucide-stethoscope',
link: '/outpatient/examination-queue',
},
{
title: 'Pendaftaran',
icon: 'i-lucide-building-2',
link: '/outpatient/examination',
},
],
},
{
title: 'Pasien',
icon: 'i-lucide-users',
link: '/patient',
},
{
title: 'Rehabilitasi Medik',
icon: 'i-lucide-heart',
link: '/rehabilitasi',
},
{
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
@@ -105,44 +18,60 @@ 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"
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)"
+75
View File
@@ -0,0 +1,75 @@
[
{
"title": "Dashboard",
"icon": "i-lucide-home",
"link": "/"
},
{
"title": "Rawat Jalan",
"icon": "i-lucide-stethoscope",
"children": [
{
"title": "Antrian Pendaftaran",
"icon": "i-lucide-stethoscope",
"link": "/outpatient/registration-queue"
},
{
"title": "Pendaftaran",
"icon": "i-lucide-building-2",
"link": "/outpatient/registration"
},
{
"title": "Antrian Pemeriksaan",
"icon": "i-lucide-stethoscope",
"link": "/outpatient/examination-queue"
},
{
"title": "Pendaftaran",
"icon": "i-lucide-building-2",
"link": "/outpatient/examination"
}
]
},
{
"title": "Pasien",
"icon": "i-lucide-users",
"link": "/patient"
},
{
"title": "Rehabilitasi Medik",
"icon": "i-lucide-heart",
"link": "/rehabilitasi"
},
{
"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"
}
]