dstpabuaran.com/resources/js/components/app-sidebar.tsx
Yoga Pangestu 72848d51d8 feat: add transaction management page with filtering and CRUD functionality
- Implemented TransactionIndex component for displaying transactions with pagination and filtering options.
- Created TransactionCardRow component for rendering individual transaction details.
- Added TransactionItemSubRow component for displaying detailed order items within a transaction.
- Integrated delete confirmation dialog for transaction deletion.
- Updated routes to include transaction management with appropriate permissions.
2026-08-04 10:37:28 +07:00

208 lines
7.6 KiB
TypeScript

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/app-logo';
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupLabel,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from '@/components/ui/sidebar';
import { useCurrentUrl } from '@/hooks/use-current-url';
import { dashboard } from '@/routes';
import admin from '@/routes/admin';
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 };
const dasborItem: NavMenuItem = {
title: 'Dasbor',
href: dashboard.url(),
icon: LayoutGrid,
};
const analisaItem: NavMenuItem = {
title: 'Analisa',
href: '#',
icon: BarChart3,
};
const masterItems: NavMenuItem[] = [
{ title: 'Kategori', href: categoriesIndex.url(), icon: Tags },
{ title: 'Produk', href: productsIndex.url(), icon: Package },
{ title: 'Bahan Baku', href: rawMaterialsIndex.url(), icon: Boxes },
{ title: 'Supplier', href: suppliersIndex.url(), icon: Truck },
{ title: 'Customer', href: customersIndex.url(), icon: Users },
];
const kelolaItems: NavMenuItem[] = [
{ title: 'Belanja', href: purchasesIndex.url(), icon: ShoppingCart },
{ title: 'Cutting', href: cuttingsIndex.url(), icon: Scissors },
{ title: 'Transaksi', href: transactionsIndex.url(), icon: ShoppingCart },
{ title: 'Restock', href: restocksIndex.url(), icon: RefreshCw },
{ title: 'Stok Opname', href: '#', icon: ClipboardCheck },
];
const keuanganItems: NavMenuItem[] = [
{ title: 'Kas Toko', href: cashAccountsIndex.url(), icon: Wallet },
{ title: 'Pengeluaran', href: expensesIndex.url(), icon: ArrowUpFromLine },
{ title: 'Kasbon', href: employeeAdvancesIndex.url(), icon: HandCoins },
{ title: 'Gaji', href: payrollCurrent.url(), icon: DollarSign },
];
const hrItems: NavMenuItem[] = [
{ title: 'Pegawai', href: employeesIndex.url(), icon: UserCircle },
{ title: 'Presensi', href: attendancesIndex.url(), icon: CalendarCheck },
{ title: 'Cuti', href: leaveRequestsIndex.url(), icon: CalendarDays },
];
const sistemItems: NavMenuItem[] = [
{ title: 'Pengaturan', href: '/admin/settings', icon: Settings },
{ title: 'Role & Permission', href: rolesIndex.url(), icon: Shield },
{ title: 'Log Aktivitas', href: '#', icon: Activity },
];
function MenuGroup({ label, items }: { label: string; items: NavMenuItem[] }) {
const { isCurrentUrl } = useCurrentUrl();
return (
<SidebarGroup>
<SidebarGroupLabel>{label}</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton
asChild
isActive={isCurrentUrl(item.href)}
tooltip={{ children: item.title }}
>
<Link href={item.href} prefetch>
<item.icon />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroup>
);
}
export function AppSidebar() {
const { isCurrentUrl } = useCurrentUrl();
const { isMobile, setOpenMobile } = useSidebar();
React.useEffect(() => {
if (!isMobile) {
return;
}
const cleanup = router.on('finish', () => {
setOpenMobile(false);
});
return cleanup;
}, [isMobile, setOpenMobile]);
return (
<Sidebar collapsible="icon" variant="inset">
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton size="lg" asChild>
<Link href={dashboard.url()} prefetch>
<AppLogo />
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton
asChild
isActive={isCurrentUrl('/dashboard')}
tooltip={{ children: dasborItem.title }}
>
<Link href={dasborItem.href} prefetch>
<dasborItem.icon />
<span>{dasborItem.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
<SidebarGroup>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton
asChild
tooltip={{ children: analisaItem.title }}
>
<Link href={analisaItem.href} prefetch>
<analisaItem.icon />
<span>{analisaItem.title}</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
<MenuGroup label="Master" items={masterItems} />
<MenuGroup label="Kelola" items={kelolaItems} />
<MenuGroup label="Keuangan" items={keuanganItems} />
<MenuGroup label="HR" items={hrItems} />
<MenuGroup label="Sistem" items={sistemItems} />
</SidebarContent>
</Sidebar>
);
}