25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 

513 satır
17 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 FileUploadIcon from '@mui/icons-material/FileUpload';
  38. import EmailIcon from "@mui/icons-material/Email";
  39. import RequestQuoteIcon from '@mui/icons-material/RequestQuote';
  40. import {
  41. IMPORT_INVOICE,
  42. IMPORT_RECEIPT,
  43. MAINTAIN_PROJECT,
  44. MAINTAIN_TASK_TEMPLATE,
  45. MAINTAIN_USER,
  46. VIEW_DASHBOARD_ALL,
  47. VIEW_DASHBOARD_SELF,
  48. VIEW_PROJECT,
  49. VIEW_CLIENT,
  50. VIEW_SUBSIDIARY,
  51. VIEW_STAFF,
  52. VIEW_COMPANY,
  53. VIEW_SKILL,
  54. VIEW_DEPARTMENT,
  55. VIEW_POSITION,
  56. VIEW_SALARY,
  57. VIEW_TEAM,
  58. VIEW_GROUP,
  59. VIEW_HOLIDAY,
  60. MAINTAIN_CLIENT,
  61. MAINTAIN_SUBSIDIARY,
  62. MAINTAIN_STAFF,
  63. MAINTAIN_COMPANY,
  64. MAINTAIN_SKILL,
  65. MAINTAIN_DEPARTMENT,
  66. MAINTAIN_POSITION,
  67. MAINTAIN_SALARY,
  68. MAINTAIN_TEAM,
  69. MAINTAIN_GROUP,
  70. MAINTAIN_HOLIDAY,
  71. VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING,
  72. GENERATE_LATE_START_REPORT,
  73. GENERATE_PROJECT_POTENTIAL_DELAY_REPORT,
  74. GENERATE_RESOURCE_OVERCONSUMPTION_REPORT,
  75. GENERATE_COST_AND_EXPENSE_REPORT,
  76. GENERATE_PROJECT_COMPLETION_REPORT,
  77. GENERATE_PROJECT_PANDL_REPORT,
  78. GENERATE_FINANCIAL_STATUS_REPORT,
  79. GENERATE_PROJECT_CASH_FLOW_REPORT,
  80. GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT,
  81. GENERATE_CROSS_TEAM_CHARGE_REPORT,
  82. VIEW_MAIL,
  83. MAINTAIN_MAIL
  84. } from "@/middleware";
  85. import { SessionWithAbilities } from "../AppBar/NavigationToggle";
  86. import { authOptions } from "@/config/authConfig";
  87. import { getServerSession } from "next-auth";
  88. import useIsMobile from "@/app/utils/useIsMobile";
  89. interface NavigationItem {
  90. icon: React.ReactNode;
  91. label: string;
  92. path: string;
  93. isHidden?: boolean;
  94. showOnMobile?: boolean;
  95. children?: NavigationItem[];
  96. }
  97. interface Props {
  98. abilities?: string[];
  99. username?: string;
  100. }
  101. const NavigationContent: React.FC<Props> = ({ abilities, username }) => {
  102. const { t } = useTranslation("common");
  103. const navigationItems: NavigationItem[] = [
  104. {
  105. icon: <WorkHistory />,
  106. label: "User Workspace",
  107. path: "/home",
  108. showOnMobile: true,
  109. },
  110. {
  111. icon: <Dashboard />,
  112. label: t("Dashboard"),
  113. path: "",
  114. isHidden: ![VIEW_DASHBOARD_ALL, VIEW_DASHBOARD_SELF].some((ability) =>
  115. abilities!.includes(ability),
  116. ),
  117. children: [
  118. // {
  119. // icon: <SummarizeIcon />,
  120. // label: "Financial Summary",
  121. // path: "/dashboard/ProjectFinancialSummary",
  122. // },
  123. {
  124. icon: <PaymentsIcon />,
  125. label: "Company / Team Cash Flow",
  126. path: "/dashboard/CompanyTeamCashFlow",
  127. },
  128. {
  129. icon: <PaymentsIcon />,
  130. label: "Project Cash Flow",
  131. path: "/dashboard/ProjectCashFlow",
  132. },
  133. {
  134. icon: <AccountTreeIcon />,
  135. label: "Project Status by Client",
  136. path: "/dashboard/ProjectStatusByClient",
  137. },
  138. {
  139. icon: <AccountTreeIcon />,
  140. label: "Project Status by Team",
  141. path: "/dashboard/ProjectStatusByTeam",
  142. },
  143. {
  144. icon: <AccountTreeIcon />,
  145. label: "Project Resource Consumption Ranking",
  146. path: "/dashboard/ProjectResourceConsumptionRanking",
  147. isHidden: ![VIEW_PROJECT_RESOURCE_CONSUMPTION_RANKING].some((ability) =>
  148. abilities!.includes(ability),
  149. )
  150. },
  151. {
  152. icon: <PeopleIcon />,
  153. label: "Staff Utilization",
  154. path: "/dashboard/StaffUtilization",
  155. },
  156. {
  157. icon: <ViewWeekIcon />,
  158. label: "Project Resource Summary",
  159. path: "/dashboard/ProjectResourceSummary",
  160. },
  161. ],
  162. },
  163. {
  164. icon: <SummarizeIcon />,
  165. label: "Financial Summary",
  166. path: "/dashboard/ProjectFinancialSummary",
  167. isHidden: ![VIEW_DASHBOARD_ALL, VIEW_DASHBOARD_SELF].some((ability) =>
  168. abilities!.includes(ability),
  169. ),
  170. },
  171. {
  172. icon: <SummarizeIcon />,
  173. label: "Financial Summary2",
  174. path: "/dashboard/ProjectFinancialSummaryV2",
  175. isHidden: true,
  176. showOnMobile: true,
  177. },
  178. // No Claim function in Breaur, will be implement later
  179. // {
  180. // icon: <RequestQuote />,
  181. // label: "Staff Reimbursement",
  182. // path: "/staffReimbursement",
  183. // children: [
  184. // {
  185. // icon: <RequestQuote />,
  186. // label: "Claim Approval",
  187. // path: "/staffReimbursement/ClaimApproval",
  188. // },
  189. // {
  190. // icon: <RequestQuote />,
  191. // label: "Claim Summary",
  192. // path: "/staffReimbursement/ClaimSummary",
  193. // },
  194. // ],
  195. // },
  196. { icon: <Assignment />, label: "Project Management", path: "/projects", isHidden: ![MAINTAIN_PROJECT].some((ability) => abilities?.includes(ability)) },
  197. { icon: <Task />, label: "Task Template", path: "/tasks", isHidden: ![MAINTAIN_TASK_TEMPLATE].some((ability) => abilities?.includes(ability)) },
  198. {
  199. icon: <Payments />,
  200. label: "Invoice",
  201. path: "/invoice",
  202. isHidden: ![IMPORT_INVOICE, IMPORT_RECEIPT].some((ability) =>
  203. abilities!.includes(ability),
  204. ),
  205. },
  206. {
  207. icon: <RequestQuoteIcon />,
  208. label: "Expense",
  209. path: "/expense",
  210. isHidden: ![IMPORT_INVOICE, IMPORT_RECEIPT].some((ability) =>
  211. abilities!.includes(ability),
  212. ),
  213. },
  214. {
  215. icon: <Analytics />,
  216. label: "Analysis Report",
  217. path: "",
  218. isHidden: ![
  219. GENERATE_LATE_START_REPORT,
  220. GENERATE_PROJECT_POTENTIAL_DELAY_REPORT,
  221. GENERATE_RESOURCE_OVERCONSUMPTION_REPORT,
  222. GENERATE_COST_AND_EXPENSE_REPORT,
  223. GENERATE_PROJECT_COMPLETION_REPORT,
  224. GENERATE_PROJECT_PANDL_REPORT,
  225. GENERATE_FINANCIAL_STATUS_REPORT,
  226. GENERATE_PROJECT_CASH_FLOW_REPORT,
  227. GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT,
  228. GENERATE_CROSS_TEAM_CHARGE_REPORT
  229. ].some((ability) =>
  230. abilities!.includes(ability),
  231. ),
  232. children: [
  233. {
  234. icon: <Analytics />,
  235. label: "Late Start Report",
  236. path: "/analytics/LateStartReport",
  237. isHidden: ![GENERATE_LATE_START_REPORT].some((ability) =>
  238. abilities!.includes(ability),
  239. ),
  240. },
  241. {
  242. icon: <Analytics />,
  243. label: "Project Potential Delay Report",
  244. path: "/analytics/ProjectPotentialDelayReport",
  245. isHidden: ![GENERATE_PROJECT_POTENTIAL_DELAY_REPORT].some((ability) =>
  246. abilities!.includes(ability),
  247. ),
  248. },
  249. {
  250. icon: <Analytics />,
  251. label: "Resource Overconsumption Report",
  252. path: "/analytics/ResourceOverconsumptionReport",
  253. isHidden: ![GENERATE_RESOURCE_OVERCONSUMPTION_REPORT].some((ability) =>
  254. abilities!.includes(ability),
  255. ),
  256. },
  257. {
  258. icon: <Analytics />,
  259. label: "Cost and Expense Report",
  260. path: "/analytics/CostandExpenseReport",
  261. isHidden: ![GENERATE_COST_AND_EXPENSE_REPORT].some((ability) =>
  262. abilities!.includes(ability),
  263. ),
  264. },
  265. {
  266. icon: <Analytics />,
  267. label: "Project Completion Report",
  268. path: "/analytics/ProjectCompletionReport",
  269. isHidden: ![GENERATE_PROJECT_COMPLETION_REPORT].some((ability) =>
  270. abilities!.includes(ability),
  271. ),
  272. },
  273. // {
  274. // icon: <Analytics />,
  275. // label: "Completion Report with Outstanding Un-billed Hours Report",
  276. // path: "/analytics/ProjectCompletionReportWO",
  277. // },
  278. // {
  279. // icon: <Analytics />,
  280. // label: "Project Claims Report",
  281. // path: "/analytics/ProjectClaimsReport",
  282. // },
  283. {
  284. icon: <Analytics />,
  285. label: "Project P&L Report",
  286. path: "/analytics/ProjectPandLReport",
  287. isHidden: ![GENERATE_PROJECT_COMPLETION_REPORT].some((ability) =>
  288. abilities!.includes(ability),
  289. ),
  290. },
  291. {
  292. icon: <Analytics />,
  293. label: "Financial Status Report",
  294. path: "/analytics/FinancialStatusReport",
  295. isHidden: ![GENERATE_FINANCIAL_STATUS_REPORT].some((ability) =>
  296. abilities!.includes(ability),
  297. ),
  298. },
  299. {
  300. icon: <Analytics />,
  301. label: "Project Cash Flow Report",
  302. path: "/analytics/ProjectCashFlowReport",
  303. isHidden: ![GENERATE_PROJECT_CASH_FLOW_REPORT].some((ability) =>
  304. abilities!.includes(ability),
  305. ),
  306. },
  307. {
  308. icon: <Analytics />,
  309. label: "Staff Monthly Work Hours Analysis Report",
  310. path: "/analytics/StaffMonthlyWorkHoursAnalysisReport",
  311. isHidden: ![GENERATE_STAFF_MONTHLY_WORK_HOURS_ANALYSIS_REPORT].some((ability) =>
  312. abilities!.includes(ability),
  313. ),
  314. },
  315. {
  316. icon: <Analytics />,
  317. label: "Cross Team Charge Report",
  318. path: "/analytics/CrossTeamChargeReport",
  319. isHidden: ![GENERATE_CROSS_TEAM_CHARGE_REPORT].some((ability) =>
  320. abilities!.includes(ability),
  321. ),
  322. },
  323. ],
  324. },
  325. {
  326. icon: <Settings />,
  327. label: "Settings",
  328. path: "",
  329. isHidden: ![
  330. VIEW_CLIENT,
  331. VIEW_SUBSIDIARY,
  332. VIEW_STAFF,
  333. VIEW_COMPANY,
  334. VIEW_SKILL,
  335. VIEW_DEPARTMENT,
  336. VIEW_POSITION,
  337. VIEW_SALARY,
  338. VIEW_TEAM,
  339. VIEW_GROUP,
  340. VIEW_HOLIDAY,
  341. MAINTAIN_CLIENT,
  342. MAINTAIN_SUBSIDIARY,
  343. MAINTAIN_STAFF,
  344. MAINTAIN_COMPANY,
  345. MAINTAIN_SKILL,
  346. MAINTAIN_DEPARTMENT,
  347. MAINTAIN_POSITION,
  348. MAINTAIN_SALARY,
  349. MAINTAIN_TEAM,
  350. MAINTAIN_GROUP,
  351. MAINTAIN_HOLIDAY
  352. ].some((ability) =>
  353. abilities!.includes(ability),
  354. ),
  355. children: [
  356. {
  357. icon: <GroupIcon />,
  358. label: "Client",
  359. path: "/settings/customer",
  360. isHidden: ![VIEW_CLIENT, MAINTAIN_CLIENT].some((ability) => abilities!.includes(ability),),
  361. },
  362. {
  363. icon: <BusinessIcon />,
  364. label: "Subsidiary",
  365. path: "/settings/subsidiary",
  366. isHidden: ![VIEW_SUBSIDIARY, MAINTAIN_SUBSIDIARY].some((ability) => abilities!.includes(ability),),
  367. },
  368. {
  369. icon: <Staff />,
  370. label: "Staff",
  371. path: "/settings/staff",
  372. isHidden: ![VIEW_STAFF, MAINTAIN_STAFF].some((ability) => abilities!.includes(ability),),
  373. },
  374. {
  375. icon: <Company />,
  376. label: "Company",
  377. path: "/settings/company",
  378. isHidden: ![VIEW_COMPANY, MAINTAIN_COMPANY].some((ability) => abilities!.includes(ability),),
  379. },
  380. {
  381. icon: <EmojiEventsIcon />,
  382. label: "Skill",
  383. path: "/settings/skill",
  384. isHidden: ![VIEW_SKILL, MAINTAIN_SKILL].some((ability) => abilities!.includes(ability),),
  385. },
  386. {
  387. icon: <Department />,
  388. label: "Department",
  389. path: "/settings/department",
  390. isHidden: ![VIEW_DEPARTMENT, MAINTAIN_DEPARTMENT].some((ability) => abilities!.includes(ability),),
  391. },
  392. {
  393. icon: <Position />,
  394. label: "Position",
  395. path: "/settings/position",
  396. isHidden: ![VIEW_POSITION, MAINTAIN_POSITION].some((ability) => abilities!.includes(ability),),
  397. },
  398. {
  399. icon: <Salary />,
  400. label: "Salary",
  401. path: "/settings/salary",
  402. isHidden: ![VIEW_SALARY, MAINTAIN_SALARY].some((ability) => abilities!.includes(ability),),
  403. },
  404. {
  405. icon: <Team />,
  406. label: "Team",
  407. path: "/settings/team",
  408. isHidden: ![VIEW_TEAM, MAINTAIN_TEAM].some((ability) => abilities!.includes(ability),),
  409. },
  410. // { icon: <ManageAccountsIcon />, label: "User", path: "/settings/user" },
  411. {
  412. icon: <ManageAccountsIcon />,
  413. label: "User Group",
  414. path: "/settings/group",
  415. isHidden: ![VIEW_GROUP, MAINTAIN_GROUP].some((ability) => abilities!.includes(ability),),
  416. },
  417. {
  418. icon: <Holiday />,
  419. label: "Holiday",
  420. path: "/settings/holiday",
  421. isHidden: ![VIEW_HOLIDAY, MAINTAIN_HOLIDAY].some((ability) => abilities!.includes(ability),),
  422. },
  423. {
  424. icon: <EmailIcon />,
  425. label: "Mail",
  426. path: "/settings/mail",
  427. isHidden: ![VIEW_MAIL, MAINTAIN_MAIL].some((ability) => abilities!.includes(ability),),
  428. },
  429. { icon: <FileUploadIcon />, label: "Import Excel File", path: "/settings/import", isHidden: username !== "2fi" },
  430. ],
  431. },
  432. ];
  433. const isMobile = useIsMobile();
  434. // const { t } = useTranslation("common");
  435. const pathname = usePathname();
  436. const [openItems, setOpenItems] = React.useState<string[]>([]);
  437. const toggleItem = (label: string) => {
  438. setOpenItems((prevOpenItems) =>
  439. prevOpenItems.includes(label)
  440. ? prevOpenItems.filter((item) => item !== label)
  441. : [...prevOpenItems, label],
  442. );
  443. };
  444. const renderNavigationItem = (item: NavigationItem) => {
  445. const isOpen = openItems.includes(item.label);
  446. return (
  447. <Box
  448. key={`${item.label}-${item.path}`}
  449. component={Link}
  450. href={item.path}
  451. sx={{ textDecoration: "none", color: "inherit" }}
  452. >
  453. <ListItemButton
  454. selected={pathname.includes(item.label)}
  455. onClick={() => item.children && toggleItem(item.label)}
  456. >
  457. <ListItemIcon>{item.icon}</ListItemIcon>
  458. <ListItemText primary={t(item.label)} />
  459. </ListItemButton>
  460. {item.children && isOpen && (
  461. <List sx={{ pl: 2 }}>
  462. {item.children.map((child) => (!child.isHidden && renderNavigationItem(child)))}
  463. </List>
  464. )}
  465. </Box>
  466. );
  467. };
  468. return (
  469. <Box sx={{ width: NAVIGATION_CONTENT_WIDTH }}>
  470. <Box sx={{ p: 3, display: "flex" }}>
  471. <Logo height={60} />
  472. {/* <button className="float-right bg-transparent border-transparent" >
  473. <ArrowCircleLeftRoundedIcon className="text-slate-400 hover:text-blue-400 hover:cursor-pointer " style={{ fontSize: '35px' }} />
  474. </button> */}
  475. </Box>
  476. <Divider />
  477. <List component="nav">
  478. {navigationItems
  479. .filter(
  480. (item) => !item.isHidden && (isMobile ? item.showOnMobile : true),
  481. )
  482. .map((item) => renderNavigationItem(item))}
  483. {/* {navigationItems.map(({ icon, label, path }, index) => {
  484. return (
  485. <Box
  486. key={`${label}-${index}`}
  487. component={Link}
  488. href={path}
  489. sx={{ textDecoration: "none", color: "inherit" }}
  490. >
  491. <ListItemButton selected={pathname.includes(path)}>
  492. <ListItemIcon>{icon}</ListItemIcon>
  493. <ListItemText primary={t(label)} />
  494. </ListItemButton>
  495. </Box>
  496. );
  497. })} */}
  498. </List>
  499. </Box>
  500. );
  501. };
  502. export default NavigationContent;