135 lines
5.7 KiB
Vue
135 lines
5.7 KiB
Vue
<script setup lang="ts">
|
|
import { Link, usePage } from '@inertiajs/vue3';
|
|
import { Banknote, CalendarDays, Clock, FolderTree, History, Layers, LayoutDashboard, Package, Receipt, Scissors, Settings2, Shield, ShoppingBag, ShoppingCart, User, UserCheck, Users, Wallet, WalletCards } from '@lucide/vue';
|
|
import {
|
|
Sidebar,
|
|
SidebarContent,
|
|
SidebarGroup,
|
|
SidebarGroupContent,
|
|
SidebarGroupLabel,
|
|
SidebarHeader,
|
|
SidebarMenu,
|
|
SidebarMenuBadge,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
SidebarRail,
|
|
} from '@/components/ui/sidebar';
|
|
import { useCan } from '@/composables/useCan';
|
|
|
|
const page = usePage();
|
|
const { can } = useCan();
|
|
|
|
interface MenuItem {
|
|
title: string;
|
|
href: string;
|
|
icon: any;
|
|
permission?: string;
|
|
badgeKey?: 'pendingLeaveRequests' | 'pendingEmployeeAdvances';
|
|
}
|
|
|
|
interface MenuGroup {
|
|
label: string;
|
|
items: MenuItem[];
|
|
}
|
|
|
|
const menuGroups: MenuGroup[] = [
|
|
{
|
|
label: 'Menu',
|
|
items: [
|
|
{ title: 'Dashboard', href: '/admin/dashboard', icon: LayoutDashboard },
|
|
],
|
|
},
|
|
{
|
|
label: 'Master',
|
|
items: [
|
|
{ title: 'Kategori', href: '/admin/master/categories', icon: FolderTree, permission: 'categories.view' },
|
|
{ title: 'Produk', href: '/admin/master/products', icon: Package, permission: 'products.view' },
|
|
{ title: 'Bahan Baku', href: '/admin/master/raw-materials', icon: Layers, permission: 'raw-materials.view' },
|
|
{ title: 'Supplier', href: '/admin/master/suppliers', icon: User, permission: 'suppliers.view' },
|
|
{ title: 'Customer', href: '/admin/master/customers', icon: UserCheck, permission: 'customers.view' },
|
|
],
|
|
},
|
|
{
|
|
label: 'Kelola',
|
|
items: [
|
|
{ title: 'Belanja', href: '/admin/manage/purchases', icon: ShoppingBag, permission: 'purchases.view' },
|
|
{ title: 'Cutting', href: '/admin/manage/cuttings', icon: Scissors, permission: 'cuttings.view' },
|
|
{ title: 'Pesanan', href: '/admin/manage/orders', icon: ShoppingCart, permission: 'orders.view' },
|
|
],
|
|
},
|
|
{
|
|
label: 'Keuangan',
|
|
items: [
|
|
{ title: 'Kas Toko', href: '/admin/finance/cash', icon: Wallet, permission: 'cash.view' },
|
|
{ title: 'Pengeluaran', href: '/admin/finance/expenses', icon: Receipt, permission: 'expenses.view' },
|
|
{ title: 'Kasbon', href: '/admin/finance/employee-advances', icon: Banknote, permission: 'employee-advances.view', badgeKey: 'pendingEmployeeAdvances' },
|
|
{ title: 'Gaji', href: '/admin/finance/payroll', icon: WalletCards, permission: 'payroll.view' },
|
|
],
|
|
},
|
|
{
|
|
label: 'HR',
|
|
items: [
|
|
{ title: 'Pegawai', href: '/admin/hr/employees', icon: Users, permission: 'employees.view' },
|
|
{ title: 'Presensi', href: '/admin/hr/attendances', icon: Clock, permission: 'attendances.view' },
|
|
{ title: 'Cuti', href: '/admin/hr/leave-requests', icon: CalendarDays, permission: 'leave-requests.view', badgeKey: 'pendingLeaveRequests' },
|
|
],
|
|
},
|
|
{
|
|
label: 'Sistem',
|
|
items: [
|
|
{ title: 'Role & Permission', href: '/admin/system/roles', icon: Shield, permission: 'roles.view' },
|
|
{ title: 'Pengaturan', href: '/admin/system/setting', icon: Settings2, permission: 'settings.view' },
|
|
{ title: 'Log Aktivitas', href: '/admin/system/activity-logs', icon: History, permission: 'activity-logs.view' },
|
|
],
|
|
},
|
|
];
|
|
</script>
|
|
|
|
<template>
|
|
<Sidebar collapsible="icon">
|
|
<SidebarHeader>
|
|
<SidebarMenu>
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton size="lg" as-child>
|
|
<Link href="/admin/dashboard">
|
|
<div class="grid flex-1 text-left text-sm leading-tight">
|
|
<span class="truncate font-semibold">{{ page.props.name }}</span>
|
|
</div>
|
|
</Link>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
</SidebarHeader>
|
|
<SidebarContent>
|
|
<template v-for="group in menuGroups" :key="group.label">
|
|
<SidebarGroup v-if="group.items.some(item => !item.permission || can(item.permission))">
|
|
<SidebarGroupLabel>{{ group.label }}</SidebarGroupLabel>
|
|
<SidebarGroupContent>
|
|
<SidebarMenu>
|
|
<template v-for="item in group.items" :key="item.href">
|
|
<SidebarMenuItem v-if="!item.permission || can(item.permission)">
|
|
<SidebarMenuButton
|
|
as-child
|
|
:tooltip="item.title"
|
|
:is-active="page.url.startsWith(item.href)"
|
|
>
|
|
<Link :href="item.href">
|
|
<component :is="item.icon" />
|
|
<span>{{ item.title }}</span>
|
|
</Link>
|
|
</SidebarMenuButton>
|
|
<SidebarMenuBadge v-if="item.badgeKey && (page.props as any)[item.badgeKey] > 0">
|
|
{{ (page.props as any)[item.badgeKey] }}
|
|
</SidebarMenuBadge>
|
|
</SidebarMenuItem>
|
|
</template>
|
|
</SidebarMenu>
|
|
</SidebarGroupContent>
|
|
</SidebarGroup>
|
|
</template>
|
|
</SidebarContent>
|
|
<SidebarRail />
|
|
</Sidebar>
|
|
</template>
|
|
|