import { useSession } from "next-auth/react";
import Box from "@mui/material/Box";
import React from "react";
import List from "@mui/material/List";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemText from "@mui/material/ListItemText";
import ListItemIcon from "@mui/material/ListItemIcon";
import Dashboard from "@mui/icons-material/Dashboard";
import Storefront from "@mui/icons-material/Storefront";
import LocalShipping from "@mui/icons-material/LocalShipping";
import Assignment from "@mui/icons-material/Assignment";
import Inventory from "@mui/icons-material/Inventory";
import AssignmentTurnedIn from "@mui/icons-material/AssignmentTurnedIn";
import ReportProblem from "@mui/icons-material/ReportProblem";
import QrCodeIcon from "@mui/icons-material/QrCode";
import ViewModule from "@mui/icons-material/ViewModule";
import Description from "@mui/icons-material/Description";
import CalendarMonth from "@mui/icons-material/CalendarMonth";
import Factory from "@mui/icons-material/Factory";
import PostAdd from "@mui/icons-material/PostAdd";
import Kitchen from "@mui/icons-material/Kitchen";
import Inventory2 from "@mui/icons-material/Inventory2";
import Print from "@mui/icons-material/Print";
import Assessment from "@mui/icons-material/Assessment";
import ShowChart from "@mui/icons-material/ShowChart";
import Settings from "@mui/icons-material/Settings";
import Person from "@mui/icons-material/Person";
import Group from "@mui/icons-material/Group";
import Category from "@mui/icons-material/Category";
import TrendingUp from "@mui/icons-material/TrendingUp";
import Build from "@mui/icons-material/Build";
import Warehouse from "@mui/icons-material/Warehouse";
import VerifiedUser from "@mui/icons-material/VerifiedUser";
import Label from "@mui/icons-material/Label";
import Checklist from "@mui/icons-material/Checklist";
import Science from "@mui/icons-material/Science";
import UploadFile from "@mui/icons-material/UploadFile";
import { useTranslation } from "react-i18next";
import { usePathname } from "next/navigation";
import Link from "next/link";
import { NAVIGATION_CONTENT_WIDTH } from "@/config/uiConfig";
import Logo from "../Logo";
import { AUTH } from "../../authorities";
interface NavigationItem {
icon: React.ReactNode;
label: string;
path: string;
children?: NavigationItem[];
isHidden?: boolean | undefined;
requiredAbility?: string | string[];
}
const NavigationContent: React.FC = () => {
const { data: session, status } = useSession();
const abilities = session?.user?.abilities ?? [];
// Helper: check if user has required permission
const hasAbility = (required?: string | string[]): boolean => {
if (!required) return true; // no requirement → always show
if (Array.isArray(required)) {
return required.some(ability => abilities.includes(ability));
}
return abilities.includes(required);
};
const navigationItems: NavigationItem[] = [
{
icon: ,
label: "Dashboard",
path: "/dashboard",
},
{
icon: ,
label: "Store Management",
path: "",
requiredAbility: [AUTH.PURCHASE, AUTH.STOCK, AUTH.STOCK_TAKE, AUTH.STOCK_FG, AUTH.STOCK_IN_BIND, AUTH.ADMIN],
children: [
{
icon: ,
label: "Purchase Order",
requiredAbility: [AUTH.PURCHASE, AUTH.ADMIN],
path: "/po",
},
{
icon: ,
label: "Pick Order",
requiredAbility: [AUTH.STOCK, AUTH.ADMIN],
path: "/pickOrder",
},
{
icon: ,
label: "View item In-out And inventory Ledger",
requiredAbility: [AUTH.STOCK, AUTH.ADMIN],
path: "/inventory",
},
{
icon: ,
label: "Stock Take Management",
requiredAbility: [AUTH.STOCK, AUTH.STOCK_TAKE, AUTH.ADMIN],
path: "/stocktakemanagement",
},
{
icon: ,
label: "Stock Issue",
requiredAbility: [AUTH.STOCK, AUTH.STOCK_TAKE, AUTH.ADMIN],
path: "/stockIssue",
},
{
icon: ,
label: "Put Away Scan",
requiredAbility: [AUTH.STOCK, AUTH.STOCK_TAKE, AUTH.STOCK_IN_BIND, AUTH.ADMIN],
path: "/putAway",
},
{
icon: ,
label: "Finished Good Order",
requiredAbility: [AUTH.STOCK_FG, AUTH.ADMIN],
path: "/finishedGood",
},
{
icon: ,
label: "Stock Record",
requiredAbility: [AUTH.STOCK, AUTH.STOCK_TAKE, AUTH.STOCK_IN_BIND, AUTH.STOCK_FG, AUTH.ADMIN],
path: "/stockRecord",
},
],
},
{
icon: ,
label: "Delivery Order",
path: "/do",
requiredAbility: [AUTH.STOCK_FG, AUTH.ADMIN],
},
{
icon: ,
label: "Scheduling",
path: "/ps",
requiredAbility: [AUTH.FORECAST, AUTH.ADMIN],
isHidden: false,
},
{
icon: ,
label: "Management Job Order",
path: "",
requiredAbility: [AUTH.JOB_CREATE, AUTH.JOB_PICK, AUTH.JOB_PROD, AUTH.ADMIN],
children: [
{
icon: ,
label: "Search Job Order/ Create Job Order",
requiredAbility: [AUTH.JOB_CREATE, AUTH.ADMIN],
path: "/jo",
},
{
icon: ,
label: "Job Order Pickexcution",
requiredAbility: [AUTH.JOB_PICK, AUTH.JOB_MAT, AUTH.ADMIN],
path: "/jodetail",
},
{
icon: ,
label: "Job Order Production Process",
requiredAbility: [AUTH.JOB_PROD, AUTH.ADMIN],
path: "/productionProcess",
},
{
icon: ,
label: "Bag Usage",
requiredAbility: [AUTH.JOB_PROD, AUTH.ADMIN],
path: "/bag",
},
],
},
{
icon: ,
label: "打袋機",
path: "/bagPrint",
requiredAbility: [AUTH.JOB_PROD, AUTH.ADMIN],
isHidden: false,
},
{
icon: ,
label: "報告管理",
path: "/report",
requiredAbility: [AUTH.TESTING, AUTH.ADMIN],
isHidden: false,
},
{
icon: ,
label: "圖表報告",
path: "",
requiredAbility: [AUTH.TESTING, AUTH.ADMIN],
isHidden: false,
children: [
{
icon: ,
label: "庫存與倉儲",
path: "/chart/warehouse",
requiredAbility: [AUTH.TESTING, AUTH.ADMIN],
},
{
icon: ,
label: "採購",
path: "/chart/purchase",
requiredAbility: [AUTH.TESTING, AUTH.ADMIN],
},
{
icon: ,
label: "發貨與配送",
path: "/chart/delivery",
requiredAbility: [AUTH.TESTING, AUTH.ADMIN],
},
{
icon: ,
label: "工單",
path: "/chart/joborder",
requiredAbility: [AUTH.TESTING, AUTH.ADMIN],
},
{
icon: ,
label: "預測與計劃",
path: "/chart/forecast",
requiredAbility: [AUTH.TESTING, AUTH.ADMIN],
},
],
},
{
icon: ,
label: "Settings",
path: "",
requiredAbility: [AUTH.VIEW_USER, AUTH.ADMIN],
children: [
{
icon: ,
label: "User",
path: "/settings/user",
requiredAbility: [AUTH.VIEW_USER, AUTH.ADMIN],
},
//{
// icon: ,
// label: "User Group",
// path: "/settings/user",
// requiredAbility: [AUTH.VIEW_GROUP, AUTH.ADMIN],
//},
{
icon: ,
label: "Items",
path: "/settings/items",
},
{
icon: ,
label: "Equipment",
path: "/settings/equipment",
},
{
icon: ,
label: "Price Inquiry",
path: "/settings/itemPrice",
},
{
icon: ,
label: "Warehouse",
path: "/settings/warehouse",
},
{
icon: ,
label: "Printer",
path: "/settings/printer",
},
{
icon: ,
label: "QC Check Item",
path: "/settings/qcItem",
},
{
icon: ,
label: "QC Category",
path: "/settings/qcCategory",
},
{
icon: ,
label: "QC Item All",
path: "/settings/qcItemAll",
},
{
icon: ,
label: "ShopAndTruck",
path: "/settings/shop",
},
{
icon: ,
label: "Demand Forecast Setting",
path: "/settings/rss",
},
//{
// icon: ,
// label: "Customer",
// path: "/settings/user",
//},
{
icon: ,
label: "BOM Weighting Score List",
path: "/settings/bomWeighting",
},
{
icon: ,
label: "QR Code Handle",
path: "/settings/qrCodeHandle",
},
{
icon: ,
label: "Import Testing",
path: "/settings/m18ImportTesting",
},
{
icon: ,
label: "Import Excel",
path: "/settings/importExcel",
},
{
icon: ,
label: "Import BOM",
path: "/settings/importBom",
},
],
},
];
const { t } = useTranslation("common");
const pathname = usePathname();
const [openItems, setOpenItems] = React.useState([]);
// Keep "圖表報告" expanded when on any chart sub-route
React.useEffect(() => {
if (pathname.startsWith("/chart/") && !openItems.includes("圖表報告")) {
setOpenItems((prev) => [...prev, "圖表報告"]);
}
}, [pathname, openItems]);
const toggleItem = (label: string) => {
setOpenItems((prevOpenItems) =>
prevOpenItems.includes(label)
? prevOpenItems.filter((item) => item !== label)
: [...prevOpenItems, label],
);
};
const renderNavigationItem = (item: NavigationItem) => {
if (!hasAbility(item.requiredAbility)) {
return null;
}
const isOpen = openItems.includes(item.label);
const hasVisibleChildren = item.children?.some(child => hasAbility(child.requiredAbility));
const isLeaf = Boolean(item.path);
const isSelected = isLeaf && item.path
? pathname === item.path || pathname.startsWith(item.path + "/")
: hasVisibleChildren && item.children?.some(
(c) => c.path && (pathname === c.path || pathname.startsWith(c.path + "/"))
);
const content = (
toggleItem(item.label)}
sx={{
mx: 1,
"&.Mui-selected .MuiListItemIcon-root": { color: "primary.main" },
}}
>
{item.icon}
);
return (
{isLeaf ? (
{content}
) : (
content
)}
{item.children && isOpen && hasVisibleChildren && (
{item.children.map(
(child) => !child.isHidden && hasAbility(child.requiredAbility) && (
{child.icon}
),
)}
)}
);
};
if (status === "loading") {
return Loading...;
}
return (
{navigationItems
.filter(item => !item.isHidden)
.map(renderNavigationItem)
.filter(Boolean)}
);
};
export default NavigationContent;