Files
dashboard-cpsp-executive/components/Sidebar.tsx
T
2026-09-08 15:21:23 +07:00

152 lines
4.2 KiB
TypeScript

import React from 'react';
import { View } from '../types/common.ts';
import { useAuth } from '../context/AuthContext.tsx';
import NavLink, { NavItem } from './sidebar/NavLink.tsx';
const navItems: NavItem[] = [
{
view: 'dashboard',
label: 'Dashboard',
icon: <i className="fa-solid fa-home"></i>,
},
{
view: 'dataManagement',
label: 'Hitung Ayam',
icon: <i className="fa-solid fa-calculator"></i>,
},
{
view: 'weightMonitoring',
label: 'Berat Ayam',
icon: <i className="fa-solid fa-weight-scale"></i>,
subItems: [
{
view: 'weightMonitoring',
label: 'Dashboard Berat',
icon: <i className="fa-solid fa-chart-line"></i>,
},
{
view: 'weightStandard',
label: 'Standar Mr. Mike',
icon: <i className="fa-solid fa-table-list"></i>,
},
],
},
{
view: 'feedSackCounting',
label: 'Manajemen Pakan',
icon: <i className="fa-solid fa-boxes-stacked"></i>,
subItems: [
{
view: 'feedSackCounting',
label: 'Hitung Karung',
icon: <i className="fa-solid fa-boxes-stacked"></i>,
},
{
view: 'cobbStandard',
label: 'Standar Performa',
icon: <i className="fa-solid fa-table-list"></i>,
},
],
},
{
view: 'iotPanel',
label: 'Panel IoT',
icon: <i className="fa-solid fa-table-columns"></i>,
},
{
view: 'fcrDashboard',
label: 'FCR',
icon: <i className="fa-solid fa-chart-line"></i>,
},
{
view: 'eefDashboard',
label: 'EEF',
icon: <i className="fa-solid fa-gauge-high"></i>,
},
{
view: 'kandangRanking',
label: 'Peringkat Kandang',
icon: <i className="fa-solid fa-ranking-star"></i>,
},
{
view: 'kandangSettings',
label: 'Pengaturan',
icon: <i className="fa-solid fa-gear"></i>,
},
{
view: 'userManagement',
label: 'Manajemen Akun',
icon: <i className="fa-solid fa-users"></i>,
},
];
interface SidebarProps {
isCollapsed: boolean;
view: View;
setView: (view: View) => void;
onToggleCollapse: () => void;
}
const Sidebar: React.FC<SidebarProps> = ({ isCollapsed, view, setView, onToggleCollapse }) => {
const { user } = useAuth();
const canOpenSettings =
user?.status === 'gm' ||
user?.status === 'gm_admin' ||
user?.status === 'buh' ||
user?.status === 'bu_admin';
const canOpenUserManagement =
user?.status === 'superuser' || Boolean(user?.is_superuser);
const visibleNav = navItems.filter((item) => {
if (item.view === 'kandangSettings') return canOpenSettings;
if (item.view === 'userManagement') return canOpenUserManagement;
return true;
});
return (
<aside
className={`flex flex-col bg-white border-r border-gray-200 transition-all duration-300 ease-in-out z-20 ${
isCollapsed ? 'w-20' : 'w-64'
}`}
>
<div className="flex items-center justify-start h-16 border-b border-gray-200 px-4">
<img
src="/favicon.png"
alt="Logo Charoen Pokphand"
className="object-contain flex-shrink-0 h-10"
/>
</div>
<nav className="flex-grow p-2 overflow-y-auto">
<ul className="space-y-1">
{visibleNav.map((item) => {
const isActive =
view === item.view || (item.subItems?.some((sub) => sub.view === view) ?? false);
return (
<NavLink
key={item.label}
item={item}
isActive={isActive}
isCollapsed={isCollapsed}
setView={setView}
view={view}
/>
);
})}
</ul>
</nav>
<div className="p-2 border-t border-gray-200">
<button
onClick={onToggleCollapse}
className="w-full flex items-center h-11 px-4 rounded-lg text-gray-600 hover:bg-gray-100 hover:text-gray-900"
>
<div className="w-8 text-lg flex items-center justify-center -ml-1">
<i className={`fa-solid ${isCollapsed ? 'fa-angles-right' : 'fa-angles-left'}`}></i>
</div>
{!isCollapsed && <span className="ml-2 text-sm font-semibold">Tutup Menu</span>}
</button>
</div>
</aside>
);
};
export default Sidebar;