store/resources/js/components/AppSidebar.vue

143 lines
6.4 KiB
Vue

<script setup lang="ts">
import { Link, usePage } from '@inertiajs/vue3';
import { Banknote, CalendarDays, CheckCircle, Clock, FolderTree, History, Layers, LayoutDashboard, Package, Receipt, Scissors, Settings2, Shield, ShoppingBag, ShoppingCart, User, UserCheck, Users, Wallet, WalletCards, Warehouse } 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' | 'pendingCuttings' | 'pendingOwnerVerifications';
}
interface MenuGroup {
label: string;
items: MenuItem[];
}
const menuGroups: MenuGroup[] = [
{
label: 'Menu',
items: [
{ title: 'Dasbor', 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: 'Stok', href: '/admin/manage/stocks', icon: Warehouse, permission: 'stocks.view', badgeKey: 'pendingCuttings' },
{ title: 'Verifikasi Owner', href: '/admin/manage/owner-verifications', icon: CheckCircle, permission: 'owner_verifications.view', badgeKey: 'pendingOwnerVerifications' },
{ 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/settings', 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">
<img
v-if="page.props.logo_url"
:src="page.props.logo_url"
:alt="page.props.name"
class="h-8 w-auto object-contain"
/>
<div v-else 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>