import { Link, router } from '@inertiajs/react'; import type { LucideIcon } from 'lucide-react'; import { Activity, ArrowUpFromLine, BarChart3, Boxes, CalendarCheck, CalendarDays, ClipboardCheck, DollarSign, HandCoins, LayoutGrid, Package, RefreshCw, Scissors, Settings, Shield, ShoppingCart, Tags, Truck, UserCircle, Users, Wallet, } from 'lucide-react'; import React from 'react'; import { AppLogo } from '@/components/brand'; import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, useSidebar, } from '@/components/ui/sidebar'; import { useCan } from '@/hooks/use-can'; import { useCurrentUrl } from '@/hooks/use-current-url'; import { dashboard } from '@/routes'; import analysis from '@/routes/admin/analysis'; import { index as cashAccountsIndex } from '@/routes/admin/finance/cash-accounts'; import { index as employeeAdvancesIndex } from '@/routes/admin/finance/employee-advances'; import { index as expensesIndex } from '@/routes/admin/finance/expenses'; import { current as payrollCurrent } from '@/routes/admin/finance/payroll-periods'; import { index as attendancesIndex } from '@/routes/admin/hr/attendances'; import { index as employeesIndex } from '@/routes/admin/hr/employees'; import { index as leaveRequestsIndex } from '@/routes/admin/hr/leave-requests'; import { index as cuttingsIndex } from '@/routes/admin/manage/cuttings'; import { index as purchasesIndex } from '@/routes/admin/manage/purchases'; import { index as restocksIndex } from '@/routes/admin/manage/restocks'; import { index as transactionsIndex } from '@/routes/admin/manage/transactions'; import { index as categoriesIndex } from '@/routes/admin/master/categories'; import { index as customersIndex } from '@/routes/admin/master/customers'; import { index as productsIndex } from '@/routes/admin/master/products'; import { index as rawMaterialsIndex } from '@/routes/admin/master/raw-materials'; import { index as suppliersIndex } from '@/routes/admin/master/suppliers'; import { index as rolesIndex } from '@/routes/admin/settings/roles'; type NavMenuItem = { title: string; href: string; icon: LucideIcon; permission?: string | string[] }; const dasborItem: NavMenuItem = { title: 'Dasbor', href: dashboard.url(), icon: LayoutGrid, }; const analisaItem: NavMenuItem = { title: 'Analisa', href: analysis.index.url(), icon: BarChart3, permission: 'analysis.view', }; const masterItems: NavMenuItem[] = [ { title: 'Kategori', href: categoriesIndex.url(), icon: Tags, permission: 'categories.view' }, { title: 'Produk', href: productsIndex.url(), icon: Package, permission: 'products.view' }, { title: 'Bahan Baku', href: rawMaterialsIndex.url(), icon: Boxes, permission: 'raw_materials.view' }, { title: 'Supplier', href: suppliersIndex.url(), icon: Truck, permission: 'suppliers.view' }, { title: 'Customer', href: customersIndex.url(), icon: Users, permission: 'customers.view' }, ]; const kelolaItems: NavMenuItem[] = [ { title: 'Belanja', href: purchasesIndex.url(), icon: ShoppingCart, permission: 'purchases.view' }, { title: 'Cutting', href: cuttingsIndex.url(), icon: Scissors, permission: 'cuttings.view' }, { title: 'Transaksi', href: transactionsIndex.url(), icon: ShoppingCart, permission: 'orders.view' }, { title: 'Restock', href: restocksIndex.url(), icon: RefreshCw, permission: 'restocks.view' }, { title: 'Stok Opname', href: '#', icon: ClipboardCheck, permission: 'stok_opnames.view' }, ]; const keuanganItems: NavMenuItem[] = [ { title: 'Kas Toko', href: cashAccountsIndex.url(), icon: Wallet, permission: 'cash.view' }, { title: 'Pengeluaran', href: expensesIndex.url(), icon: ArrowUpFromLine, permission: 'expenses.view' }, { title: 'Kasbon', href: employeeAdvancesIndex.url(), icon: HandCoins, permission: 'employee_advances.view' }, { title: 'Gaji', href: payrollCurrent.url(), icon: DollarSign, permission: 'payroll.view' }, ]; const hrItems: NavMenuItem[] = [ { title: 'Pegawai', href: employeesIndex.url(), icon: UserCircle, permission: 'employees.view' }, { title: 'Presensi', href: attendancesIndex.url(), icon: CalendarCheck, permission: 'attendances.view' }, { title: 'Cuti', href: leaveRequestsIndex.url(), icon: CalendarDays, permission: 'leave_requests.view' }, ]; const sistemItems: NavMenuItem[] = [ { title: 'Pengaturan', href: '/admin/settings', icon: Settings, permission: ['settings.view_system', 'settings.view_homepage', 'settings.view_social_media', 'settings.view_marketplace', 'settings.view_hr'] }, { title: 'Role & Permission', href: rolesIndex.url(), icon: Shield, permission: 'roles.view' }, { title: 'Log Aktivitas', href: '#', icon: Activity, permission: 'activity_logs.view' }, ]; function MenuGroup({ label, items }: { label: string; items: NavMenuItem[] }) { const { isCurrentUrl } = useCurrentUrl(); const { can, canAny } = useCan(); const filtered = items.filter((item) => { if (!item.permission) { return true; } if (Array.isArray(item.permission)) { return canAny(...item.permission); } return can(item.permission); }); if (filtered.length === 0) { return null; } return ( {label} {filtered.map((item) => ( {item.title} ))} ); } export function AppSidebar() { const { isCurrentUrl } = useCurrentUrl(); const { isMobile, setOpenMobile } = useSidebar(); const { can } = useCan(); React.useEffect(() => { if (!isMobile) { return; } const cleanup = router.on('finish', () => { setOpenMobile(false); }); return cleanup; }, [isMobile, setOpenMobile]); return ( {dasborItem.title} {can(analisaItem.permission as string) && ( {analisaItem.title} )} ); }