Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

308 строки
9.9 KiB

  1. import Divider from "@mui/material/Divider";
  2. import Box from "@mui/material/Box";
  3. import React from "react";
  4. import List from "@mui/material/List";
  5. import ListItemButton from "@mui/material/ListItemButton";
  6. import ListItemText from "@mui/material/ListItemText";
  7. import ListItemIcon from "@mui/material/ListItemIcon";
  8. import WorkHistory from "@mui/icons-material/WorkHistory";
  9. import Dashboard from "@mui/icons-material/Dashboard";
  10. import SummarizeIcon from "@mui/icons-material/Summarize";
  11. import PaymentsIcon from "@mui/icons-material/Payments";
  12. import AccountTreeIcon from "@mui/icons-material/AccountTree";
  13. import RequestQuote from "@mui/icons-material/RequestQuote";
  14. import PeopleIcon from "@mui/icons-material/People";
  15. import Task from "@mui/icons-material/Task";
  16. import Assignment from "@mui/icons-material/Assignment";
  17. import Settings from "@mui/icons-material/Settings";
  18. import Analytics from "@mui/icons-material/Analytics";
  19. import Payments from "@mui/icons-material/Payments";
  20. import Staff from "@mui/icons-material/PeopleAlt";
  21. import Company from "@mui/icons-material/Store";
  22. import Department from "@mui/icons-material/Diversity3";
  23. import Position from "@mui/icons-material/Paragliding";
  24. import Salary from "@mui/icons-material/AttachMoney";
  25. import Team from "@mui/icons-material/Paragliding";
  26. import Holiday from "@mui/icons-material/CalendarMonth";
  27. import { useTranslation } from "react-i18next";
  28. import { usePathname } from "next/navigation";
  29. import Link from "next/link";
  30. import { NAVIGATION_CONTENT_WIDTH } from "@/config/uiConfig";
  31. import Logo from "../Logo";
  32. import GroupIcon from "@mui/icons-material/Group";
  33. import BusinessIcon from "@mui/icons-material/Business";
  34. import ViewWeekIcon from "@mui/icons-material/ViewWeek";
  35. import ManageAccountsIcon from "@mui/icons-material/ManageAccounts";
  36. import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
  37. import {
  38. GENERATE_REPORTS,
  39. MAINTAIN_MASTERDATA,
  40. MAINTAIN_USER,
  41. VIEW_MASTERDATA,
  42. VIEW_USER,
  43. } from "@/middleware";
  44. import { SessionWithAbilities } from "../AppBar/NavigationToggle";
  45. import { authOptions } from "@/config/authConfig";
  46. import { getServerSession } from "next-auth";
  47. import useIsMobile from "@/app/utils/useIsMobile";
  48. interface NavigationItem {
  49. icon: React.ReactNode;
  50. label: string;
  51. path: string;
  52. isHidden?: boolean;
  53. showOnMobile?: boolean;
  54. children?: NavigationItem[];
  55. }
  56. interface Props {
  57. abilities?: string[];
  58. }
  59. const NavigationContent: React.FC<Props> = ({ abilities }) => {
  60. const navigationItems: NavigationItem[] = [
  61. {
  62. icon: <WorkHistory />,
  63. label: "User Workspace",
  64. path: "/home",
  65. showOnMobile: true,
  66. },
  67. {
  68. icon: <Dashboard />,
  69. label: "Dashboard",
  70. path: "",
  71. children: [
  72. {
  73. icon: <SummarizeIcon />,
  74. label: "Financial Summary",
  75. path: "/dashboard/ProjectFinancialSummary",
  76. },
  77. {
  78. icon: <PaymentsIcon />,
  79. label: "Company / Team Cash Flow",
  80. path: "/dashboard/CompanyTeamCashFlow",
  81. },
  82. {
  83. icon: <PaymentsIcon />,
  84. label: "Project Cash Flow",
  85. path: "/dashboard/ProjectCashFlow",
  86. },
  87. {
  88. icon: <AccountTreeIcon />,
  89. label: "Project Status by Client",
  90. path: "/dashboard/ProjectStatusByClient",
  91. },
  92. {
  93. icon: <AccountTreeIcon />,
  94. label: "Project Status by Team",
  95. path: "/dashboard/ProjectStatusByTeam",
  96. },
  97. {
  98. icon: <PeopleIcon />,
  99. label: "Staff Utilization",
  100. path: "/dashboard/StaffUtilization",
  101. },
  102. {
  103. icon: <ViewWeekIcon />,
  104. label: "Project Resource Summary",
  105. path: "/dashboard/ProjectResourceSummary",
  106. },
  107. ],
  108. },
  109. // No Claim function in Breaur, will be implement later
  110. // {
  111. // icon: <RequestQuote />,
  112. // label: "Staff Reimbursement",
  113. // path: "/staffReimbursement",
  114. // children: [
  115. // {
  116. // icon: <RequestQuote />,
  117. // label: "Claim Approval",
  118. // path: "/staffReimbursement/ClaimApproval",
  119. // },
  120. // {
  121. // icon: <RequestQuote />,
  122. // label: "Claim Summary",
  123. // path: "/staffReimbursement/ClaimSummary",
  124. // },
  125. // ],
  126. // },
  127. { icon: <Assignment />, label: "Project Management", path: "/projects" },
  128. { icon: <Task />, label: "Task Template", path: "/tasks" },
  129. { icon: <Payments />, label: "Invoice", path: "/invoice" },
  130. {
  131. icon: <Analytics />,
  132. label: "Analysis Report",
  133. path: "",
  134. isHidden: ![GENERATE_REPORTS].some((ability) =>
  135. abilities!.includes(ability),
  136. ),
  137. children: [
  138. {
  139. icon: <Analytics />,
  140. label: "Late Start Report",
  141. path: "/analytics/LateStartReport",
  142. },
  143. {
  144. icon: <Analytics />,
  145. label: "Delay Report",
  146. path: "/analytics/DelayReport",
  147. },
  148. {
  149. icon: <Analytics />,
  150. label: "Resource Overconsumption Report",
  151. path: "/analytics/ResourceOverconsumptionReport",
  152. },
  153. {
  154. icon: <Analytics />,
  155. label: "Cost and Expense Report",
  156. path: "/analytics/CostandExpenseReport",
  157. },
  158. {
  159. icon: <Analytics />,
  160. label: "Completion Report",
  161. path: "/analytics/ProjectCompletionReport",
  162. },
  163. {
  164. icon: <Analytics />,
  165. label: "Completion Report with Outstanding Un-billed Hours Report",
  166. path: "/analytics/ProjectCompletionReportWO",
  167. },
  168. {
  169. icon: <Analytics />,
  170. label: "Project Claims Report",
  171. path: "/analytics/ProjectClaimsReport",
  172. },
  173. {
  174. icon: <Analytics />,
  175. label: "Project P&L Report",
  176. path: "/analytics/ProjectPandLReport",
  177. },
  178. {
  179. icon: <Analytics />,
  180. label: "Financial Status Report",
  181. path: "/analytics/FinancialStatusReport",
  182. },
  183. {
  184. icon: <Analytics />,
  185. label: "Project Cash Flow Report",
  186. path: "/analytics/ProjectCashFlowReport",
  187. },
  188. {
  189. icon: <Analytics />,
  190. label: "Staff Monthly Work Hours Analysis Report",
  191. path: "/analytics/StaffMonthlyWorkHoursAnalysisReport",
  192. },
  193. ],
  194. },
  195. {
  196. icon: <Settings />,
  197. label: "Setting",
  198. path: "",
  199. isHidden: ![VIEW_MASTERDATA, MAINTAIN_MASTERDATA].some((ability) =>
  200. abilities!.includes(ability),
  201. ),
  202. children: [
  203. { icon: <GroupIcon />, label: "Client", path: "/settings/customer" },
  204. {
  205. icon: <BusinessIcon />,
  206. label: "Subsidiary",
  207. path: "/settings/subsidiary",
  208. },
  209. { icon: <Staff />, label: "Staff", path: "/settings/staff" },
  210. { icon: <Company />, label: "Company", path: "/settings/company" },
  211. { icon: <EmojiEventsIcon />, label: "Skill", path: "/settings/skill" },
  212. {
  213. icon: <Department />,
  214. label: "Department",
  215. path: "/settings/department",
  216. },
  217. { icon: <Position />, label: "Position", path: "/settings/position" },
  218. { icon: <Salary />, label: "Salary", path: "/settings/salary" },
  219. { icon: <Team />, label: "Team", path: "/settings/team" },
  220. // { icon: <ManageAccountsIcon />, label: "User", path: "/settings/user" },
  221. {
  222. icon: <ManageAccountsIcon />,
  223. label: "User Group",
  224. path: "/settings/group",
  225. },
  226. { icon: <Holiday />, label: "Holiday", path: "/settings/holiday" },
  227. ],
  228. },
  229. ];
  230. const isMobile = useIsMobile();
  231. const { t } = useTranslation("common");
  232. const pathname = usePathname();
  233. const [openItems, setOpenItems] = React.useState<string[]>([]);
  234. const toggleItem = (label: string) => {
  235. setOpenItems((prevOpenItems) =>
  236. prevOpenItems.includes(label)
  237. ? prevOpenItems.filter((item) => item !== label)
  238. : [...prevOpenItems, label],
  239. );
  240. };
  241. const renderNavigationItem = (item: NavigationItem) => {
  242. const isOpen = openItems.includes(item.label);
  243. return (
  244. <Box
  245. key={`${item.label}-${item.path}`}
  246. component={Link}
  247. href={item.path}
  248. sx={{ textDecoration: "none", color: "inherit" }}
  249. >
  250. <ListItemButton
  251. selected={pathname.includes(item.label)}
  252. onClick={() => item.children && toggleItem(item.label)}
  253. >
  254. <ListItemIcon>{item.icon}</ListItemIcon>
  255. <ListItemText primary={t(item.label)} />
  256. </ListItemButton>
  257. {item.children && isOpen && (
  258. <List sx={{ pl: 2 }}>
  259. {item.children.map((child) => renderNavigationItem(child))}
  260. </List>
  261. )}
  262. </Box>
  263. );
  264. };
  265. return (
  266. <Box sx={{ width: NAVIGATION_CONTENT_WIDTH }}>
  267. <Box sx={{ p: 3, display: "flex" }}>
  268. <Logo height={60} />
  269. {/* <button className="float-right bg-transparent border-transparent" >
  270. <ArrowCircleLeftRoundedIcon className="text-slate-400 hover:text-blue-400 hover:cursor-pointer " style={{ fontSize: '35px' }} />
  271. </button> */}
  272. </Box>
  273. <Divider />
  274. <List component="nav">
  275. {navigationItems
  276. .filter(
  277. (item) => !item.isHidden && (isMobile ? item.showOnMobile : true),
  278. )
  279. .map((item) => renderNavigationItem(item))}
  280. {/* {navigationItems.map(({ icon, label, path }, index) => {
  281. return (
  282. <Box
  283. key={`${label}-${index}`}
  284. component={Link}
  285. href={path}
  286. sx={{ textDecoration: "none", color: "inherit" }}
  287. >
  288. <ListItemButton selected={pathname.includes(path)}>
  289. <ListItemIcon>{icon}</ListItemIcon>
  290. <ListItemText primary={t(label)} />
  291. </ListItemButton>
  292. </Box>
  293. );
  294. })} */}
  295. </List>
  296. </Box>
  297. );
  298. };
  299. export default NavigationContent;