105 lines
3.0 KiB
Vue
105 lines
3.0 KiB
Vue
<script setup lang="ts">
|
|
import {
|
|
BriefcaseBusiness,
|
|
CreditCard,
|
|
Database,
|
|
FolderKanban,
|
|
LayoutDashboard
|
|
} from "@lucide/vue"
|
|
import { computed, ref, watch } from 'vue'
|
|
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipTrigger,
|
|
} from '@/components/ui/tooltip'
|
|
|
|
import {
|
|
Sidebar,
|
|
SidebarContent,
|
|
SidebarGroup,
|
|
SidebarGroupContent,
|
|
SidebarGroupLabel,
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
} from '@/components/ui/sidebar'
|
|
|
|
const route = useRoute()
|
|
|
|
const groups = [
|
|
{
|
|
title: 'Master',
|
|
icon: FolderKanban,
|
|
items: [
|
|
{ title: 'Dashboard', url: '/admin/dashboard', icon: LayoutDashboard },
|
|
{ title: 'Jenis Bisnis', url: '/admin/business-types', icon: BriefcaseBusiness },
|
|
{ title: 'Plans', url: '/admin/plans', icon: CreditCard },
|
|
],
|
|
},
|
|
]
|
|
|
|
const activeGroup = ref(
|
|
groups.find(g => g.items.some(it => route.path === it.url))?.title ?? groups[0].title
|
|
)
|
|
|
|
watch(() => route.path, (path) => {
|
|
const found = groups.find(g => g.items.some(it => it.url === path))
|
|
if (found) activeGroup.value = found.title
|
|
})
|
|
|
|
const currentGroup = computed(() => groups.find(g => g.title === activeGroup.value))
|
|
</script>
|
|
|
|
<template>
|
|
<Sidebar collapsible="icon">
|
|
<div class="flex flex-row h-full w-full">
|
|
<!-- Left: Icon Rail -->
|
|
<div class="flex w-(--sidebar-width-icon) shrink-0 flex-col items-center border-r py-2 gap-1">
|
|
<SidebarMenuButton as-child class="p-1.5! mb-2">
|
|
<a href="#">
|
|
<img src="/assets/icon.png" class="size-6!" />
|
|
</a>
|
|
</SidebarMenuButton>
|
|
|
|
<Tooltip v-for="g in groups" :key="g.title">
|
|
<TooltipTrigger as-child>
|
|
<SidebarMenuButton as-child size="lg" :data-active="activeGroup === g.title || undefined"
|
|
@click="activeGroup = g.title">
|
|
<button>
|
|
<component :is="g.icon" />
|
|
</button>
|
|
</SidebarMenuButton>
|
|
</TooltipTrigger>
|
|
<TooltipContent side="right">
|
|
{{ g.title }}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</div>
|
|
|
|
<!-- Right: Content Panel -->
|
|
<div class="flex flex-1 flex-col min-w-0">
|
|
<SidebarContent>
|
|
<SidebarGroup>
|
|
<SidebarGroupLabel class="text-lg font-bold mb-5">
|
|
{{ currentGroup?.title }}
|
|
</SidebarGroupLabel>
|
|
<SidebarGroupContent>
|
|
<SidebarMenu>
|
|
<SidebarMenuItem v-for="item in currentGroup?.items" :key="item.title">
|
|
<SidebarMenuButton as-child :is-active="route.path === item.url">
|
|
<NuxtLink :to="item.url">
|
|
<component :is="item.icon" v-if="item.icon" />
|
|
<span>{{ item.title }}</span>
|
|
</NuxtLink>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</SidebarGroupContent>
|
|
</SidebarGroup>
|
|
</SidebarContent>
|
|
</div>
|
|
</div>
|
|
</Sidebar>
|
|
</template>
|