|
- import Divider from "@mui/material/Divider";
- 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 WorkHistory from "@mui/icons-material/WorkHistory";
- import Dashboard from "@mui/icons-material/Dashboard";
- import SummarizeIcon from "@mui/icons-material/Summarize";
- import PaymentsIcon from "@mui/icons-material/Payments";
- import AccountTreeIcon from "@mui/icons-material/AccountTree";
- import RequestQuote from "@mui/icons-material/RequestQuote";
- import PeopleIcon from "@mui/icons-material/People";
- import Task from "@mui/icons-material/Task";
- import Assignment from "@mui/icons-material/Assignment";
- import Settings from "@mui/icons-material/Settings";
- import Analytics from "@mui/icons-material/Analytics";
- import Payments from "@mui/icons-material/Payments";
- import Staff from "@mui/icons-material/PeopleAlt";
- import Company from "@mui/icons-material/Store";
- import Department from "@mui/icons-material/Diversity3";
- import Position from "@mui/icons-material/Paragliding";
- import Salary from "@mui/icons-material/AttachMoney";
- import Team from "@mui/icons-material/Paragliding";
- import Holiday from "@mui/icons-material/CalendarMonth";
- 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 GroupIcon from "@mui/icons-material/Group";
- import BusinessIcon from "@mui/icons-material/Business";
- import ViewWeekIcon from "@mui/icons-material/ViewWeek";
- import ManageAccountsIcon from "@mui/icons-material/ManageAccounts";
- import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
- import FileUploadIcon from '@mui/icons-material/FileUpload';
- import EmailIcon from "@mui/icons-material/Email";
-
- import {
- IMPORT_INVOICE,
- IMPORT_RECEIPT,
- MAINTAIN_PROJECT,
- MAINTAIN_TASK_TEMPLATE,
- MAINTAIN_USER,
- VIEW_DASHBOARD_ALL,
- VIEW_DASHBOARD_SELF,
- VIEW_PROJECT,
- VIEW_CLIENT,
- VIEW_SUBSIDIARY,
- VIEW_STAFF,
- VIEW_COMPANY,
- VIEW_SKILL,
- VIEW_DEPARTMENT,
- VIEW_POSITION,
- VIEW_SALARY,
- VIEW_TEAM,
- VIEW_GROUP,
- VIEW_HOLIDAY,
- MAINTAIN_CLIENT,
- MAINTAIN_SUBSIDIARY,
- MAINTAIN_STAFF,
- MAINTAIN_COMPANY,
- MAINTAIN_SKILL,
- MAINTAIN_DEPARTMENT,
- MAINTAIN_POSITION,
- MAINTAIN_SALARY,
- MAINTAIN_TEAM,
- MAINTAIN_GROUP,
- MAINTAIN_HOLIDAY,
- VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING,
- GENERATE_LATE_START_REPORT,
- GENERATE_PROJECT_POTENTIAL_DELAY_REPORT,
- GENERATE_RESOURCE_OVERCONSUMPTION_REPORT,
- GENERATE_COST_AND_EXPENSE_REPORT,
- GENERATE_PROJECT_COMPLETION_REPORT,
- GENERATE_PROJECT_PANDL_REPORT,
- GENERATE_FINANCIAL_STATUS_REPORT,
- GENERATE_PROJECT_CASH_FLOW_REPORT,
- GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT,
- GENERATE_CROSS_TEAM_CHARGE_REPORT,
- VIEW_MAIL,
- MAINTAIN_MAIL
- } from "@/middleware";
- import { SessionWithAbilities } from "../AppBar/NavigationToggle";
- import { authOptions } from "@/config/authConfig";
- import { getServerSession } from "next-auth";
- import useIsMobile from "@/app/utils/useIsMobile";
- interface NavigationItem {
- icon: React.ReactNode;
- label: string;
- path: string;
- isHidden?: boolean;
- showOnMobile?: boolean;
- children?: NavigationItem[];
- }
-
- interface Props {
- abilities?: string[];
- username?: string;
- }
-
- const NavigationContent: React.FC<Props> = ({ abilities, username }) => {
- const navigationItems: NavigationItem[] = [
- {
- icon: <WorkHistory />,
- label: "User Workspace",
- path: "/home",
- showOnMobile: true,
- },
- {
- icon: <Dashboard />,
- label: "Dashboard",
- path: "",
- isHidden: ![VIEW_DASHBOARD_ALL, VIEW_DASHBOARD_SELF].some((ability) =>
- abilities!.includes(ability),
- ),
- children: [
- {
- icon: <SummarizeIcon />,
- label: "Financial Summary",
- path: "/dashboard/ProjectFinancialSummary",
- },
- {
- icon: <PaymentsIcon />,
- label: "Company / Team Cash Flow",
- path: "/dashboard/CompanyTeamCashFlow",
- },
- {
- icon: <PaymentsIcon />,
- label: "Project Cash Flow",
- path: "/dashboard/ProjectCashFlow",
- },
- {
- icon: <AccountTreeIcon />,
- label: "Project Status by Client",
- path: "/dashboard/ProjectStatusByClient",
- },
- {
- icon: <AccountTreeIcon />,
- label: "Project Status by Team",
- path: "/dashboard/ProjectStatusByTeam",
- },
- {
- icon: <AccountTreeIcon />,
- label: "Project Resource Consumption Ranking",
- path: "/dashboard/ProjectResourceConsumptionRanking",
- isHidden: ![VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING].some((ability) =>
- abilities!.includes(ability),
- )
- },
- {
- icon: <PeopleIcon />,
- label: "Staff Utilization",
- path: "/dashboard/StaffUtilization",
- },
- {
- icon: <ViewWeekIcon />,
- label: "Project Resource Summary",
- path: "/dashboard/ProjectResourceSummary",
- },
- ],
- },
- // No Claim function in Breaur, will be implement later
- // {
- // icon: <RequestQuote />,
- // label: "Staff Reimbursement",
- // path: "/staffReimbursement",
- // children: [
- // {
- // icon: <RequestQuote />,
- // label: "Claim Approval",
- // path: "/staffReimbursement/ClaimApproval",
- // },
- // {
- // icon: <RequestQuote />,
- // label: "Claim Summary",
- // path: "/staffReimbursement/ClaimSummary",
- // },
- // ],
- // },
- { icon: <Assignment />, label: "Project Management", path: "/projects", isHidden: ![MAINTAIN_PROJECT].some((ability) => abilities?.includes(ability)) },
- { icon: <Task />, label: "Task Template", path: "/tasks", isHidden: ![MAINTAIN_TASK_TEMPLATE].some((ability) => abilities?.includes(ability)) },
- {
- icon: <Payments />,
- label: "Invoice",
- path: "/invoice",
- isHidden: ![IMPORT_INVOICE, IMPORT_RECEIPT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Analysis Report",
- path: "",
- isHidden: ![
- GENERATE_LATE_START_REPORT,
- GENERATE_PROJECT_POTENTIAL_DELAY_REPORT,
- GENERATE_RESOURCE_OVERCONSUMPTION_REPORT,
- GENERATE_COST_AND_EXPENSE_REPORT,
- GENERATE_PROJECT_COMPLETION_REPORT,
- GENERATE_PROJECT_PANDL_REPORT,
- GENERATE_FINANCIAL_STATUS_REPORT,
- GENERATE_PROJECT_CASH_FLOW_REPORT,
- GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT,
- GENERATE_CROSS_TEAM_CHARGE_REPORT
- ].some((ability) =>
- abilities!.includes(ability),
- ),
- children: [
- {
- icon: <Analytics />,
- label: "Late Start Report",
- path: "/analytics/LateStartReport",
- isHidden: ![GENERATE_LATE_START_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Project Potential Delay Report",
- path: "/analytics/ProjectPotentialDelayReport",
- isHidden: ![GENERATE_PROJECT_POTENTIAL_DELAY_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Resource Overconsumption Report",
- path: "/analytics/ResourceOverconsumptionReport",
- isHidden: ![GENERATE_RESOURCE_OVERCONSUMPTION_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Cost and Expense Report",
- path: "/analytics/CostandExpenseReport",
- isHidden: ![GENERATE_COST_AND_EXPENSE_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Project Completion Report",
- path: "/analytics/ProjectCompletionReport",
- isHidden: ![GENERATE_PROJECT_COMPLETION_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- // {
- // icon: <Analytics />,
- // label: "Completion Report with Outstanding Un-billed Hours Report",
- // path: "/analytics/ProjectCompletionReportWO",
- // },
- // {
- // icon: <Analytics />,
- // label: "Project Claims Report",
- // path: "/analytics/ProjectClaimsReport",
- // },
- {
- icon: <Analytics />,
- label: "Project P&L Report",
- path: "/analytics/ProjectPandLReport",
- isHidden: ![GENERATE_PROJECT_COMPLETION_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Financial Status Report",
- path: "/analytics/FinancialStatusReport",
- isHidden: ![GENERATE_FINANCIAL_STATUS_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Project Cash Flow Report",
- path: "/analytics/ProjectCashFlowReport",
- isHidden: ![GENERATE_PROJECT_CASH_FLOW_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Staff Monthly Work Hours Analysis Report",
- path: "/analytics/StaffMonthlyWorkHoursAnalysisReport",
- isHidden: ![GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- {
- icon: <Analytics />,
- label: "Cross Team Charge Report",
- path: "/analytics/CrossTeamChargeReport",
- isHidden: ![GENERATE_CROSS_TEAM_CHARGE_REPORT].some((ability) =>
- abilities!.includes(ability),
- ),
- },
- ],
- },
- {
- icon: <Settings />,
- label: "Setting",
- path: "",
- isHidden: ![
- VIEW_CLIENT,
- VIEW_SUBSIDIARY,
- VIEW_STAFF,
- VIEW_COMPANY,
- VIEW_SKILL,
- VIEW_DEPARTMENT,
- VIEW_POSITION,
- VIEW_SALARY,
- VIEW_TEAM,
- VIEW_GROUP,
- VIEW_HOLIDAY,
- MAINTAIN_CLIENT,
- MAINTAIN_SUBSIDIARY,
- MAINTAIN_STAFF,
- MAINTAIN_COMPANY,
- MAINTAIN_SKILL,
- MAINTAIN_DEPARTMENT,
- MAINTAIN_POSITION,
- MAINTAIN_SALARY,
- MAINTAIN_TEAM,
- MAINTAIN_GROUP,
- MAINTAIN_HOLIDAY
- ].some((ability) =>
- abilities!.includes(ability),
- ),
- children: [
- {
- icon: <GroupIcon />,
- label: "Client",
- path: "/settings/customer",
- isHidden: ![VIEW_CLIENT, MAINTAIN_CLIENT].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <BusinessIcon />,
- label: "Subsidiary",
- path: "/settings/subsidiary",
- isHidden: ![VIEW_SUBSIDIARY, MAINTAIN_SUBSIDIARY].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <Staff />,
- label: "Staff",
- path: "/settings/staff",
- isHidden: ![VIEW_STAFF, MAINTAIN_STAFF].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <Company />,
- label: "Company",
- path: "/settings/company",
- isHidden: ![VIEW_COMPANY, MAINTAIN_COMPANY].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <EmojiEventsIcon />,
- label: "Skill",
- path: "/settings/skill",
- isHidden: ![VIEW_SKILL, MAINTAIN_SKILL].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <Department />,
- label: "Department",
- path: "/settings/department",
- isHidden: ![VIEW_DEPARTMENT, MAINTAIN_DEPARTMENT].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <Position />,
- label: "Position",
- path: "/settings/position",
- isHidden: ![VIEW_POSITION, MAINTAIN_POSITION].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <Salary />,
- label: "Salary",
- path: "/settings/salary",
- isHidden: ![VIEW_SALARY, MAINTAIN_SALARY].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <Team />,
- label: "Team",
- path: "/settings/team",
- isHidden: ![VIEW_TEAM, MAINTAIN_TEAM].some((ability) => abilities!.includes(ability),),
- },
- // { icon: <ManageAccountsIcon />, label: "User", path: "/settings/user" },
- {
- icon: <ManageAccountsIcon />,
- label: "User Group",
- path: "/settings/group",
- isHidden: ![VIEW_GROUP, MAINTAIN_GROUP].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <Holiday />,
- label: "Holiday",
- path: "/settings/holiday",
- isHidden: ![VIEW_HOLIDAY, MAINTAIN_HOLIDAY].some((ability) => abilities!.includes(ability),),
- },
- {
- icon: <EmailIcon />,
- label: "Mail",
- path: "/settings/mail",
- isHidden: ![VIEW_MAIL, MAINTAIN_MAIL].some((ability) => abilities!.includes(ability),),
- },
- { icon: <FileUploadIcon />, label: "Import Excel File", path: "/settings/import", isHidden: username !== "2fi" },
- ],
- },
- ];
-
- const isMobile = useIsMobile();
-
- const { t } = useTranslation("common");
- const pathname = usePathname();
- const [openItems, setOpenItems] = React.useState<string[]>([]);
- const toggleItem = (label: string) => {
- setOpenItems((prevOpenItems) =>
- prevOpenItems.includes(label)
- ? prevOpenItems.filter((item) => item !== label)
- : [...prevOpenItems, label],
- );
- };
-
- const renderNavigationItem = (item: NavigationItem) => {
- const isOpen = openItems.includes(item.label);
-
- return (
- <Box
- key={`${item.label}-${item.path}`}
- component={Link}
- href={item.path}
- sx={{ textDecoration: "none", color: "inherit" }}
- >
- <ListItemButton
- selected={pathname.includes(item.label)}
- onClick={() => item.children && toggleItem(item.label)}
- >
- <ListItemIcon>{item.icon}</ListItemIcon>
- <ListItemText primary={t(item.label)} />
- </ListItemButton>
- {item.children && isOpen && (
- <List sx={{ pl: 2 }}>
- {item.children.map((child) => (!child.isHidden && renderNavigationItem(child)))}
- </List>
- )}
- </Box>
- );
- };
-
- return (
- <Box sx={{ width: NAVIGATION_CONTENT_WIDTH }}>
- <Box sx={{ p: 3, display: "flex" }}>
- <Logo height={60} />
- {/* <button className="float-right bg-transparent border-transparent" >
- <ArrowCircleLeftRoundedIcon className="text-slate-400 hover:text-blue-400 hover:cursor-pointer " style={{ fontSize: '35px' }} />
- </button> */}
- </Box>
- <Divider />
- <List component="nav">
- {navigationItems
- .filter(
- (item) => !item.isHidden && (isMobile ? item.showOnMobile : true),
- )
- .map((item) => renderNavigationItem(item))}
- {/* {navigationItems.map(({ icon, label, path }, index) => {
- return (
- <Box
- key={`${label}-${index}`}
- component={Link}
- href={path}
- sx={{ textDecoration: "none", color: "inherit" }}
- >
- <ListItemButton selected={pathname.includes(path)}>
- <ListItemIcon>{icon}</ListItemIcon>
- <ListItemText primary={t(label)} />
- </ListItemButton>
- </Box>
- );
- })} */}
- </List>
- </Box>
- );
- };
-
- export default NavigationContent;
|