Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 

1443 righe
53 KiB

  1. "use client";
  2. import * as React from "react";
  3. import Grid from "@mui/material/Grid";
  4. import { useState, useEffect, useMemo } from "react";
  5. import Paper from "@mui/material/Paper";
  6. import { TFunction } from "i18next";
  7. import { useTranslation } from "react-i18next";
  8. import { Card, CardHeader } from "@mui/material";
  9. import CustomSearchForm from "../CustomSearchForm/CustomSearchForm";
  10. import CustomDatagrid from "../CustomDatagrid/CustomDatagrid";
  11. import ReactApexChart from "react-apexcharts";
  12. import { ApexOptions } from "apexcharts";
  13. import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid";
  14. import ReportProblemIcon from "@mui/icons-material/ReportProblem";
  15. import dynamic from "next/dynamic";
  16. import "../../app/global.css";
  17. import { AnyARecord, AnyCnameRecord } from "dns";
  18. import SearchBox, { Criterion } from "../SearchBox";
  19. import ProgressByClientSearch from "@/components/ProgressByClientSearch";
  20. import { Suspense } from "react";
  21. import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch";
  22. import { Input, Label } from "reactstrap";
  23. import Select, { components } from "react-select";
  24. import { DateCalendar } from "@mui/x-date-pickers/DateCalendar";
  25. import { DatePicker } from "@mui/x-date-pickers/DatePicker";
  26. import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
  27. import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
  28. import dayjs, { Dayjs } from "dayjs";
  29. import isBetweenPlugin from "dayjs/plugin/isBetween";
  30. import { PickersDay, PickersDayProps } from "@mui/x-date-pickers/PickersDay";
  31. import { styled } from "@mui/material/styles";
  32. dayjs.extend(isBetweenPlugin);
  33. interface CustomPickerDayProps extends PickersDayProps<Dayjs> {
  34. isSelected: boolean;
  35. isHovered: boolean;
  36. }
  37. const CustomPickersDay = styled(PickersDay, {
  38. shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isHovered",
  39. })<CustomPickerDayProps>(({ theme, isSelected, isHovered, day }) => ({
  40. borderRadius: 0,
  41. ...(isSelected && {
  42. backgroundColor: theme.palette.primary.main,
  43. color: theme.palette.primary.contrastText,
  44. "&:hover, &:focus": {
  45. backgroundColor: theme.palette.primary.main,
  46. },
  47. }),
  48. ...(isHovered && {
  49. backgroundColor: theme.palette.primary[theme.palette.mode],
  50. "&:hover, &:focus": {
  51. backgroundColor: theme.palette.primary[theme.palette.mode],
  52. },
  53. }),
  54. ...(day.day() === 0 && {
  55. borderTopLeftRadius: "50%",
  56. borderBottomLeftRadius: "50%",
  57. }),
  58. ...(day.day() === 6 && {
  59. borderTopRightRadius: "50%",
  60. borderBottomRightRadius: "50%",
  61. }),
  62. })) as React.ComponentType<CustomPickerDayProps>;
  63. const isInSameWeek = (dayA: Dayjs, dayB: Dayjs | null | undefined) => {
  64. if (dayB == null) {
  65. return false;
  66. }
  67. return dayA.isSame(dayB, "week");
  68. };
  69. function Day(
  70. props: PickersDayProps<Dayjs> & {
  71. selectedDay?: Dayjs | null;
  72. hoveredDay?: Dayjs | null;
  73. },
  74. ) {
  75. const { day, selectedDay, hoveredDay, ...other } = props;
  76. return (
  77. <CustomPickersDay
  78. {...other}
  79. day={day}
  80. sx={{ px: 2.5 }}
  81. disableMargin
  82. selected={false}
  83. isSelected={isInSameWeek(day, selectedDay)}
  84. isHovered={isInSameWeek(day, hoveredDay)}
  85. />
  86. );
  87. }
  88. const StaffUtilization: React.FC = () => {
  89. const todayDate = new Date();
  90. const firstDayOfWeek = new Date();
  91. const lastDayOfWeek = new Date();
  92. firstDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 1);
  93. lastDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 7);
  94. const firstDayOfMonth = new Date(
  95. todayDate.getFullYear(),
  96. todayDate.getMonth(),
  97. 1,
  98. );
  99. const lastDayOfMonth = new Date(
  100. todayDate.getFullYear(),
  101. todayDate.getMonth() + 1,
  102. 0,
  103. );
  104. const [firstDayOfWeekString, setFirstDayOfWeekString] = React.useState(
  105. dayjs(firstDayOfWeek).format("DD MMM YYYY"),
  106. );
  107. const [lastDayOfWeekString, setLastDayOfWeekString] = React.useState(
  108. dayjs(lastDayOfWeek).format("DD MMM YYYY"),
  109. );
  110. const [firstDayOfMonthString, setFirstDayOfMonthString] = React.useState(
  111. dayjs(firstDayOfMonth).format("DD MMM YYYY"),
  112. );
  113. const [lastDayOfMonthString, setLastDayOfMonthString] = React.useState(
  114. dayjs(lastDayOfMonth).format("DD MMM YYYY"),
  115. );
  116. const [selectionModel, setSelectionModel]: any[] = React.useState([]);
  117. const [manHoursSpentPeriod, setManHoursSpentPeriod]: any[] = React.useState(
  118. firstDayOfWeekString + " to " + lastDayOfWeekString,
  119. );
  120. const [unsubmittedTimeSheetSelect, setUnsubmittedTimeSheetSelect]: any =
  121. React.useState("Weekly");
  122. const [teamTotalManhoursSpentSelect, setTeamTotalManhoursSpentSelect]: any =
  123. React.useState("Weekly");
  124. const [staffGradeManhoursSpentSelect, setStaffGradeManhoursSpentSelect]: any =
  125. React.useState("Weekly");
  126. const [
  127. individualStaffManhoursSpentSelect,
  128. setIndividualStaffManhoursSpentSelect,
  129. ]: any = React.useState("Daily");
  130. const weekDates: any[] = [];
  131. const monthDates: any[] = [];
  132. const currentDate = dayjs();
  133. const sixMonthsAgo = currentDate.subtract(6, "month");
  134. for (let i = 0; i < 7; i++) {
  135. const currentDate = new Date(firstDayOfWeek);
  136. currentDate.setDate(firstDayOfWeek.getDate() + i);
  137. const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
  138. weekDates.push(formattedDate);
  139. }
  140. for (
  141. let date = sixMonthsAgo.clone();
  142. date.isBefore(currentDate, "month");
  143. date = date.add(1, "month")
  144. ) {
  145. monthDates.push(date.format("MM-YYYY"));
  146. }
  147. monthDates.push(currentDate.format("MM-YYYY"));
  148. // for (let i = firstDayOfMonth.getDate(); i <= lastDayOfMonth.getDate(); i++) {
  149. // const currentDate = new Date(todayDate.getFullYear(), todayDate.getMonth(), i);
  150. // const formattedDate = dayjs(currentDate).format('DD MMM');
  151. // monthDates.push(formattedDate);
  152. // }
  153. const [teamTotalManhoursSpentPeriod, setTeamTotalManhoursSpentPeriod]: any[] =
  154. React.useState(weekDates);
  155. const [
  156. teamTotalManhoursByStaffGrade,
  157. setTeamTotalManhoursByStaffGrade,
  158. ]: any[] = React.useState(weekDates);
  159. const [
  160. individualStaffManhoursSpentPeriod,
  161. setIndividualStaffManhoursSpentPeriod,
  162. ]: any[] = React.useState(weekDates);
  163. const [
  164. unsubmittedTimeSheetPeriod,
  165. setUnsubmittedTimeSheetPeriod,
  166. ]: any[] = React.useState(weekDates);
  167. const [
  168. teamTotalManhoursSpentPlanData,
  169. setTeamTotalManhoursSpentPlanData,
  170. ]: any[] = React.useState([42, 42, 42, 42, 42, 0, 0]);
  171. const [
  172. teamTotalManhoursSpentActualData,
  173. setTeamTotalManhoursSpentActualData,
  174. ]: any[] = React.useState([45, 42, 60, 42, 58, 0, 0]);
  175. const [hoveredDay, setHoveredDay] = React.useState<Dayjs | null>(null);
  176. const [value, setValue] = React.useState<Dayjs | null>(dayjs());
  177. const [weeklyValueByStaffGrade, setWeeklyValueByStaffGrade] =
  178. React.useState<Dayjs | null>(dayjs());
  179. const [weeklyValueByIndividualStaff, setWeeklyValueByIndividualStaff] =
  180. React.useState<Dayjs | null>(dayjs());
  181. const [weeklyUnsubmittedTimeSheet, setWeeklyUnsubmittedTimeSheet ] =
  182. React.useState<Dayjs | null>(dayjs());
  183. const [staffGradeManhoursSpentValue, setStaffGradeManhoursSpentValue] =
  184. React.useState<Dayjs | null>(dayjs());
  185. const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] =
  186. React.useState<Dayjs>(dayjs(new Date()).subtract(6, "month"));
  187. const [totalManHoursMonthlyToValue, setTotalManHoursMonthlyToValue] =
  188. React.useState<Dayjs>(dayjs());
  189. const [
  190. totalManHoursByStaffGradeMonthlyFromValue,
  191. setTotalManHoursByStaffGradeMonthlyFromValue,
  192. ] = React.useState<Dayjs>(dayjs(new Date()).subtract(6, "month"));
  193. const [
  194. totalManHoursByStaffGradeMonthlyToValue,
  195. setTotalManHoursByStaffGradeMonthlyToValue,
  196. ] = React.useState<Dayjs>(dayjs());
  197. const [
  198. totalManHoursByIndividualStaffMonthlyFromValue,
  199. setTotalManHoursByIndividualStaffMonthlyFromValue,
  200. ] = React.useState<Dayjs>(dayjs(new Date()).subtract(6, "month"));
  201. const [
  202. totalManHoursByIndividualStaffMonthlyToValue,
  203. setTotalManHoursByIndividualStaffMonthlyToValue,
  204. ] = React.useState<Dayjs>(dayjs());
  205. const [
  206. totalManHoursByIndividualStaffDailyFromValue,
  207. setTotalManHoursByIndividualStaffDailyFromValue,
  208. ] = React.useState<Dayjs>(dayjs(new Date()).subtract(6, "day"));
  209. const [
  210. totalManHoursByIndividualStaffDailyToValue,
  211. setTotalManHoursByIndividualStaffDailyToValue,
  212. ] = React.useState<Dayjs>(dayjs());
  213. const [totalManHoursMaxValue, setTotalManHoursMaxValue] = React.useState(75);
  214. const teamOptions = [
  215. { value: 1, label: "XXX Team" },
  216. { value: 2, label: "YYY Team" },
  217. { value: 3, label: "ZZZ Team" },
  218. ];
  219. const columns = [
  220. {
  221. id: "projectCode",
  222. field: "projectCode",
  223. headerName: "Project Code",
  224. flex: 1,
  225. },
  226. {
  227. id: "projectName",
  228. field: "projectName",
  229. headerName: "Project Name",
  230. flex: 1,
  231. },
  232. {
  233. id: "team",
  234. field: "team",
  235. headerName: "Team",
  236. flex: 1,
  237. },
  238. {
  239. id: "teamLeader",
  240. field: "teamLeader",
  241. headerName: "Team Leader",
  242. flex: 1,
  243. },
  244. {
  245. id: "startDate",
  246. field: "startDate",
  247. headerName: "Start Date",
  248. flex: 1,
  249. },
  250. {
  251. id: "targetEndDate",
  252. field: "targetEndDate",
  253. headerName: "Target End Date",
  254. flex: 1,
  255. },
  256. {
  257. id: "client",
  258. field: "client",
  259. headerName: "Client",
  260. flex: 1,
  261. },
  262. {
  263. id: "subsidiary",
  264. field: "subsidiary",
  265. headerName: "Subsidiary",
  266. flex: 1,
  267. },
  268. ];
  269. const options: ApexOptions = {
  270. chart: {
  271. height: 350,
  272. type: "line",
  273. },
  274. stroke: {
  275. width: [2, 2],
  276. },
  277. plotOptions: {
  278. bar: {
  279. horizontal: false,
  280. distributed: false,
  281. },
  282. },
  283. dataLabels: {
  284. enabled: true,
  285. },
  286. xaxis: {
  287. categories: teamTotalManhoursSpentPeriod,
  288. },
  289. yaxis: [
  290. {
  291. title: {
  292. text: "Team Total Manhours Spent (Hour)",
  293. },
  294. min: 0,
  295. max: totalManHoursMaxValue,
  296. tickAmount: 5,
  297. },
  298. ],
  299. grid: {
  300. borderColor: "#f1f1f1",
  301. },
  302. annotations: {},
  303. series: [
  304. {
  305. name: "Planned",
  306. type: "line",
  307. color: "#efbe7d",
  308. data: teamTotalManhoursSpentPlanData,
  309. },
  310. {
  311. name: "Actual",
  312. type: "line",
  313. color: "#7cd3f2",
  314. data: teamTotalManhoursSpentActualData,
  315. },
  316. ],
  317. };
  318. const staffGradeOptions: ApexOptions = {
  319. chart: {
  320. height: 350,
  321. type: "line",
  322. },
  323. stroke: {
  324. width: [2, 2],
  325. },
  326. plotOptions: {
  327. bar: {
  328. horizontal: true,
  329. distributed: false,
  330. },
  331. },
  332. dataLabels: {
  333. enabled: true,
  334. },
  335. xaxis: {
  336. categories: [
  337. "Grade 1: A. QS / QS Trainee",
  338. "Grade 2: QS",
  339. "Grade 3: Senior QS",
  340. "Grade 4: Manager",
  341. "Grade 5: Director",
  342. ],
  343. },
  344. yaxis: [
  345. {
  346. title: {
  347. text: "Staff Grade",
  348. },
  349. min: 0,
  350. max: 60,
  351. tickAmount: 5,
  352. },
  353. ],
  354. grid: {
  355. borderColor: "#f1f1f1",
  356. },
  357. annotations: {},
  358. series: [
  359. {
  360. name: "Planned",
  361. type: "bar",
  362. color: "#efbe7d",
  363. data: [35, 45, 35, 20, 10],
  364. },
  365. {
  366. name: "Actual",
  367. type: "bar",
  368. color: "#00acb1",
  369. data: [25, 26, 33, 20, 11],
  370. },
  371. ],
  372. };
  373. const individualStaffOptions: ApexOptions = {
  374. chart: {
  375. height: 350,
  376. type: "line",
  377. },
  378. stroke: {
  379. width: [1],
  380. },
  381. plotOptions: {
  382. bar: {
  383. horizontal: true,
  384. distributed: false,
  385. },
  386. },
  387. dataLabels: {
  388. enabled: true,
  389. },
  390. xaxis: {
  391. categories: [
  392. "Consultancy Project 123 (CUST-001, Subsidiary A)",
  393. "Consultancy Project 456 (CUST-001, Subsidiary A)",
  394. "Construction Project A (CUST-001, Subsidiary A)",
  395. "Construction Project B (CUST-001, Subsidiary A)",
  396. "Construction Project C (CUST-001, Subsidiary A)",
  397. ],
  398. },
  399. yaxis: [
  400. {
  401. title: {
  402. text: "Project",
  403. },
  404. min: 0,
  405. max: 12,
  406. tickAmount: 5,
  407. },
  408. ],
  409. grid: {
  410. borderColor: "#f1f1f1",
  411. },
  412. annotations: {},
  413. series: [
  414. {
  415. name: "Manhours(Hour)",
  416. type: "bar",
  417. color: "#00acb1",
  418. data: [12, 12, 11, 12, 0],
  419. },
  420. ],
  421. };
  422. const unsubmittedTimeSheetOptions: ApexOptions = {
  423. chart: {
  424. height: 350,
  425. type: "line",
  426. },
  427. stroke: {
  428. width: [1],
  429. },
  430. plotOptions: {
  431. bar: {
  432. horizontal: true,
  433. distributed: false,
  434. },
  435. },
  436. dataLabels: {
  437. enabled: true,
  438. },
  439. xaxis: {
  440. categories: [
  441. "001-Staff A",
  442. "002-Staff B",
  443. "005-Staff E",
  444. "006-Staff F",
  445. "007-Staff G",
  446. ],
  447. },
  448. yaxis: [
  449. {
  450. title: {
  451. text: "Staff",
  452. },
  453. min: 0,
  454. max: 12,
  455. tickAmount: 5,
  456. },
  457. ],
  458. grid: {
  459. borderColor: "#f1f1f1",
  460. },
  461. annotations: {},
  462. series: [
  463. {
  464. name: "Unsubmitted Time Sheet",
  465. type: "bar",
  466. color: "#00acb1",
  467. data: [2, 2, 1, 5, 1],
  468. },
  469. ],
  470. };
  471. const teamTotalManhoursSpentOnClick = (r: any) => {
  472. setTeamTotalManhoursSpentSelect(r);
  473. if (r === "Weekly") {
  474. setValue(dayjs(new Date()));
  475. setTeamTotalManhoursSpentPeriod(weekDates);
  476. setTeamTotalManhoursSpentPlanData([42, 42, 42, 42, 42, 0, 0]);
  477. setTeamTotalManhoursSpentActualData([45, 42, 60, 42, 58, 0, 0]);
  478. setTotalManHoursMaxValue(75);
  479. } else if (r === "Monthly") {
  480. setTeamTotalManhoursSpentPeriod(monthDates);
  481. setTeamTotalManhoursSpentPlanData([840, 840, 840, 840, 840, 840]);
  482. setTeamTotalManhoursSpentActualData([900, 840, 1200, 840, 1160, 840]);
  483. setTotalManHoursMaxValue(1250);
  484. }
  485. };
  486. const individualStaffManhoursSpentOnClick = (r: any) => {
  487. setIndividualStaffManhoursSpentSelect(r);
  488. // if (r === "Weekly") {
  489. // setValue(dayjs(new Date))
  490. // setTeamTotalManhoursSpentPeriod(weekDates)
  491. // setTeamTotalManhoursSpentPlanData([42,42,42,42,42,0,0])
  492. // setTeamTotalManhoursSpentActualData([45,42,60,42,58,0,0])
  493. // setTotalManHoursMaxValue(75)
  494. // } else if (r === "Monthly") {
  495. // setTeamTotalManhoursSpentPeriod(monthDates)
  496. // setTeamTotalManhoursSpentPlanData([840,840,840,840,840,840])
  497. // setTeamTotalManhoursSpentActualData([900,840,1200,840,1160,840])
  498. // setTotalManHoursMaxValue(1250)
  499. // }
  500. };
  501. const unsubmittedTimeSheetOnClick = (r: any) => {
  502. setUnsubmittedTimeSheetSelect(r);
  503. };
  504. const selectWeeklyPeriod = (r: any) => {
  505. const selectDate = new Date(r);
  506. const firstDayOfWeek = new Date();
  507. firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
  508. const weekDates: any[] = [];
  509. for (let i = 0; i < 7; i++) {
  510. const currentDate = new Date(firstDayOfWeek);
  511. currentDate.setDate(firstDayOfWeek.getDate() + i);
  512. const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
  513. weekDates.push(formattedDate);
  514. }
  515. setTeamTotalManhoursSpentPeriod(weekDates);
  516. setValue(dayjs(firstDayOfWeek));
  517. };
  518. const selectWeeklyPeriodByStaffGrade = (r: any) => {
  519. const selectDate = new Date(r);
  520. const firstDayOfWeek = new Date();
  521. firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
  522. const weekDates: any[] = [];
  523. for (let i = 0; i < 7; i++) {
  524. const currentDate = new Date(firstDayOfWeek);
  525. currentDate.setDate(firstDayOfWeek.getDate() + i);
  526. const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
  527. weekDates.push(formattedDate);
  528. }
  529. setTeamTotalManhoursByStaffGrade(weekDates);
  530. setWeeklyValueByStaffGrade(dayjs(firstDayOfWeek));
  531. };
  532. const selectWeeklyPeriodUnsubmittedTimeSheet = (r: any) => {
  533. const selectDate = new Date(r);
  534. const firstDayOfWeek = new Date();
  535. firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
  536. const weekDates: any[] = [];
  537. for (let i = 0; i < 7; i++) {
  538. const currentDate = new Date(firstDayOfWeek);
  539. currentDate.setDate(firstDayOfWeek.getDate() + i);
  540. const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
  541. weekDates.push(formattedDate);
  542. }
  543. setUnsubmittedTimeSheetPeriod(weekDates);
  544. setWeeklyUnsubmittedTimeSheet(dayjs(firstDayOfWeek));
  545. };
  546. const selectWeeklyPeriodIndividualStaff = (r: any) => {
  547. const selectDate = new Date(r);
  548. const firstDayOfWeek = new Date();
  549. firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0);
  550. const weekDates: any[] = [];
  551. for (let i = 0; i < 7; i++) {
  552. const currentDate = new Date(firstDayOfWeek);
  553. currentDate.setDate(firstDayOfWeek.getDate() + i);
  554. const formattedDate = dayjs(currentDate).format("DD MMM (ddd)");
  555. weekDates.push(formattedDate);
  556. }
  557. setIndividualStaffManhoursSpentPeriod(weekDates);
  558. setWeeklyValueByIndividualStaff(dayjs(firstDayOfWeek));
  559. };
  560. const selectMonthlyPeriodFrom = (r: any) => {
  561. const monthDates: any[] = [];
  562. const monthPlanData: any[] = [];
  563. const monthActualData: any[] = [];
  564. const selectFromDate = dayjs(r);
  565. for (
  566. let date = selectFromDate.clone();
  567. date.isBefore(totalManHoursMonthlyToValue, "month");
  568. date = date.add(1, "month")
  569. ) {
  570. monthDates.push(date.format("MM-YYYY"));
  571. monthPlanData.push(840);
  572. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  573. }
  574. monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
  575. monthPlanData.push(840);
  576. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  577. setTeamTotalManhoursSpentPlanData(monthPlanData);
  578. setTeamTotalManhoursSpentActualData(monthActualData);
  579. setTeamTotalManhoursSpentPeriod(monthDates);
  580. };
  581. const selectMonthlyPeriodTo = (r: any) => {
  582. const monthDates: any[] = [];
  583. const monthPlanData: any[] = [];
  584. const monthActualData: any[] = [];
  585. const selectToDate = dayjs(r);
  586. for (
  587. let date = totalManHoursMonthlyFromValue.clone();
  588. date.isBefore(selectToDate, "month");
  589. date = date.add(1, "month")
  590. ) {
  591. monthDates.push(date.format("MM-YYYY"));
  592. monthPlanData.push(840);
  593. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  594. }
  595. monthDates.push(selectToDate.format("MM-YYYY"));
  596. monthPlanData.push(840);
  597. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  598. setTeamTotalManhoursSpentPlanData(monthPlanData);
  599. setTeamTotalManhoursSpentActualData(monthActualData);
  600. setTeamTotalManhoursSpentPeriod(monthDates);
  601. };
  602. const selectStaffGradeMonthlyPeriodFrom = (r: any) => {
  603. const monthDates: any[] = [];
  604. const monthPlanData: any[] = [];
  605. const monthActualData: any[] = [];
  606. const selectFromDate = dayjs(r);
  607. for (
  608. let date = selectFromDate.clone();
  609. date.isBefore(totalManHoursMonthlyToValue, "month");
  610. date = date.add(1, "month")
  611. ) {
  612. monthDates.push(date.format("MM-YYYY"));
  613. monthPlanData.push(840);
  614. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  615. }
  616. monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
  617. monthPlanData.push(840);
  618. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  619. // setTeamTotalManhoursSpentPlanData(monthPlanData)
  620. // setTeamTotalManhoursSpentActualData(monthActualData)
  621. setTeamTotalManhoursByStaffGrade(weekDates);
  622. };
  623. const selectStaffGradeMonthlyPeriodTo = (r: any) => {
  624. const monthDates: any[] = [];
  625. const monthPlanData: any[] = [];
  626. const monthActualData: any[] = [];
  627. const selectToDate = dayjs(r);
  628. for (
  629. let date = totalManHoursMonthlyFromValue.clone();
  630. date.isBefore(selectToDate, "month");
  631. date = date.add(1, "month")
  632. ) {
  633. monthDates.push(date.format("MM-YYYY"));
  634. monthPlanData.push(840);
  635. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  636. }
  637. monthDates.push(selectToDate.format("MM-YYYY"));
  638. monthPlanData.push(840);
  639. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  640. // setTeamTotalManhoursSpentPlanData(monthPlanData)
  641. // setTeamTotalManhoursSpentActualData(monthActualData)
  642. setTeamTotalManhoursByStaffGrade(weekDates);
  643. };
  644. const selectUnsubmittedTimeSheetMonthlyPeriodFrom = (r: any) => {
  645. const monthDates: any[] = [];
  646. const monthPlanData: any[] = [];
  647. const monthActualData: any[] = [];
  648. const selectFromDate = dayjs(r);
  649. for (
  650. let date = selectFromDate.clone();
  651. date.isBefore(totalManHoursMonthlyToValue, "month");
  652. date = date.add(1, "month")
  653. ) {
  654. monthDates.push(date.format("MM-YYYY"));
  655. monthPlanData.push(840);
  656. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  657. }
  658. monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
  659. monthPlanData.push(840);
  660. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  661. // setTeamTotalManhoursSpentPlanData(monthPlanData)
  662. // setTeamTotalManhoursSpentActualData(monthActualData)
  663. setUnsubmittedTimeSheetPeriod(weekDates);
  664. };
  665. const selectIndividualStaffMonthlyPeriodFrom = (r: any) => {
  666. const monthDates: any[] = [];
  667. const monthPlanData: any[] = [];
  668. const monthActualData: any[] = [];
  669. const selectFromDate = dayjs(r);
  670. for (
  671. let date = selectFromDate.clone();
  672. date.isBefore(totalManHoursMonthlyToValue, "month");
  673. date = date.add(1, "month")
  674. ) {
  675. monthDates.push(date.format("MM-YYYY"));
  676. monthPlanData.push(840);
  677. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  678. }
  679. monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY"));
  680. monthPlanData.push(840);
  681. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  682. // setTeamTotalManhoursSpentPlanData(monthPlanData)
  683. // setTeamTotalManhoursSpentActualData(monthActualData)
  684. setIndividualStaffManhoursSpentPeriod(weekDates);
  685. };
  686. const selectUnsubmittedTimeSheetMonthlyPeriodTo = (r: any) => {
  687. const monthDates: any[] = [];
  688. const monthPlanData: any[] = [];
  689. const monthActualData: any[] = [];
  690. const selectToDate = dayjs(r);
  691. for (
  692. let date = totalManHoursMonthlyFromValue.clone();
  693. date.isBefore(selectToDate, "month");
  694. date = date.add(1, "month")
  695. ) {
  696. monthDates.push(date.format("MM-YYYY"));
  697. monthPlanData.push(840);
  698. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  699. }
  700. monthDates.push(selectToDate.format("MM-YYYY"));
  701. monthPlanData.push(840);
  702. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  703. // setTeamTotalManhoursSpentPlanData(monthPlanData)
  704. // setTeamTotalManhoursSpentActualData(monthActualData)
  705. setUnsubmittedTimeSheetPeriod(weekDates);
  706. };
  707. const selectIndividualStaffMonthlyPeriodTo = (r: any) => {
  708. const monthDates: any[] = [];
  709. const monthPlanData: any[] = [];
  710. const monthActualData: any[] = [];
  711. const selectToDate = dayjs(r);
  712. for (
  713. let date = totalManHoursMonthlyFromValue.clone();
  714. date.isBefore(selectToDate, "month");
  715. date = date.add(1, "month")
  716. ) {
  717. monthDates.push(date.format("MM-YYYY"));
  718. monthPlanData.push(840);
  719. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  720. }
  721. monthDates.push(selectToDate.format("MM-YYYY"));
  722. monthPlanData.push(840);
  723. monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840));
  724. // setTeamTotalManhoursSpentPlanData(monthPlanData)
  725. // setTeamTotalManhoursSpentActualData(monthActualData)
  726. setIndividualStaffManhoursSpentPeriod(weekDates);
  727. };
  728. const options2: ApexOptions = {
  729. chart: {
  730. type: "donut",
  731. },
  732. colors: ['#f57f90','#94f7d6','#87c5f5','#ab95f5','#ab95f5'],
  733. plotOptions: {
  734. pie: {
  735. donut: {
  736. labels: {
  737. show: true,
  738. name: {
  739. show: true,
  740. },
  741. value: {
  742. show: false,
  743. fontWeight: 500,
  744. fontSize: "30px",
  745. color: "#3e98c7",
  746. },
  747. total: {
  748. show: false,
  749. showAlways: true,
  750. label: "Spent",
  751. fontFamily: "sans-serif",
  752. formatter: function (val) {
  753. return val + "%";
  754. },
  755. },
  756. },
  757. },
  758. },
  759. },
  760. series:[23.5,25.5,25.5,25.5],
  761. labels: ["Consultancy Project 123","Consultancy Project ABC","Consultancy Project A","Consultancy Project B"],
  762. legend: {
  763. show: false,
  764. },
  765. responsive: [
  766. {
  767. breakpoint: 480,
  768. options: {
  769. chart: {
  770. width: 200,
  771. },
  772. legend: {
  773. position: "bottom",
  774. show: false,
  775. },
  776. },
  777. },
  778. ],
  779. };
  780. return (
  781. <>
  782. <Grid item sm>
  783. <div style={{ display: "inline-block", width: "40%" }}>
  784. <div>
  785. <Grid item xs={12} md={12} lg={12}>
  786. <Card>
  787. <CardHeader
  788. className="text-slate-500"
  789. title="Team Total Manhours Spent"
  790. />
  791. <div style={{ display: "inline-block", width: "99%" }}>
  792. <div className="w-fit align-top mr-5 float-right">
  793. {teamTotalManhoursSpentSelect === "Weekly" && (
  794. <>
  795. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-l-md w-32">
  796. Weekly
  797. </button>
  798. <button
  799. onClick={() =>
  800. teamTotalManhoursSpentOnClick("Monthly")
  801. }
  802. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-32"
  803. >
  804. Monthly
  805. </button>
  806. </>
  807. )}
  808. {teamTotalManhoursSpentSelect === "Monthly" && (
  809. <>
  810. <button
  811. onClick={() =>
  812. teamTotalManhoursSpentOnClick("Weekly")
  813. }
  814. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-l-md w-32"
  815. >
  816. Weekly
  817. </button>
  818. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-r-md w-32">
  819. Monthly
  820. </button>
  821. </>
  822. )}
  823. </div>
  824. <div className="inline-block w-fit mt-2">
  825. <div className="inline-block ml-6">
  826. <Label className="text-slate-500 font-medium">
  827. Team:&nbsp;
  828. </Label>
  829. </div>
  830. <div className="inline-block ml-1 w-60">
  831. <Select
  832. placeholder="All Team"
  833. options={teamOptions}
  834. isClearable={true}
  835. />
  836. </div>
  837. <div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>
  838. {/* <Label className="text-slate-500 font-medium ml-6">
  839. Period:&nbsp;
  840. </Label> */}
  841. {teamTotalManhoursSpentSelect === "Weekly" && (
  842. <LocalizationProvider dateAdapter={AdapterDayjs}>
  843. <DatePicker
  844. className="w-72 h-10 align-top"
  845. label="Period:"
  846. value={value}
  847. format="DD-MM-YYYY"
  848. onChange={(newValue) =>
  849. selectWeeklyPeriod(newValue)
  850. }
  851. showDaysOutsideCurrentMonth
  852. displayWeekNumber
  853. slots={{ day: Day }}
  854. slotProps={{
  855. day: (ownerState) =>
  856. ({
  857. selectedDay: value,
  858. hoveredDay,
  859. onPointerEnter: () =>
  860. setHoveredDay(ownerState.day),
  861. onPointerLeave: () => setHoveredDay(null),
  862. }) as any,
  863. }}
  864. />
  865. </LocalizationProvider>
  866. )}
  867. {teamTotalManhoursSpentSelect === "Monthly" && (
  868. <LocalizationProvider dateAdapter={AdapterDayjs}>
  869. <DatePicker
  870. className="w-40 h-10 align-top"
  871. onChange={(newValue) =>
  872. selectMonthlyPeriodFrom(newValue)
  873. }
  874. defaultValue={totalManHoursMonthlyFromValue}
  875. label={"Form"}
  876. views={["month", "year"]}
  877. />
  878. <DatePicker
  879. className="w-40 h-10 align-top"
  880. onChange={(newValue) =>
  881. selectMonthlyPeriodTo(newValue)
  882. }
  883. defaultValue={totalManHoursMonthlyToValue}
  884. label={"To"}
  885. views={["month", "year"]}
  886. />
  887. </LocalizationProvider>
  888. )}
  889. </div>
  890. </div>
  891. <ReactApexChart
  892. options={options}
  893. series={options.series}
  894. type="line"
  895. height="400"
  896. />
  897. </div>
  898. </Card>
  899. </Grid>
  900. </div>
  901. <div className="mt-5">
  902. <Grid item xs={12} md={12} lg={12}>
  903. <Card>
  904. <CardHeader
  905. className="text-slate-500"
  906. title="Total Manhours Spent by Staff Grade"
  907. />
  908. <div style={{ display: "inline-block", width: "99%" }}>
  909. <div className="w-fit align-top mr-5 float-right">
  910. {staffGradeManhoursSpentSelect === "Weekly" && (
  911. <>
  912. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-l-md w-32">
  913. Weekly
  914. </button>
  915. <button
  916. onClick={() =>
  917. setStaffGradeManhoursSpentSelect("Monthly")
  918. }
  919. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-48"
  920. >
  921. Monthly
  922. </button>
  923. </>
  924. )}
  925. {staffGradeManhoursSpentSelect === "Monthly" && (
  926. <>
  927. <button
  928. onClick={() =>
  929. setStaffGradeManhoursSpentSelect("Weekly")
  930. }
  931. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-l-md w-32"
  932. >
  933. Weekly
  934. </button>
  935. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-r-md w-48">
  936. Monthly
  937. </button>
  938. </>
  939. )}
  940. </div>
  941. <div className="inline-block w-fit mt-2">
  942. <div className="inline-block mt-2 ml-6">
  943. {staffGradeManhoursSpentSelect === "Weekly" && (
  944. <LocalizationProvider dateAdapter={AdapterDayjs}>
  945. <DatePicker
  946. className="w-72 h-10 align-top"
  947. label="Period:"
  948. value={value}
  949. format="DD-MM-YYYY"
  950. onChange={(newValue) =>
  951. selectWeeklyPeriodByStaffGrade(newValue)
  952. }
  953. showDaysOutsideCurrentMonth
  954. displayWeekNumber
  955. slots={{ day: Day }}
  956. slotProps={{
  957. day: (ownerState) =>
  958. ({
  959. selectedDay: value,
  960. hoveredDay,
  961. onPointerEnter: () =>
  962. setHoveredDay(ownerState.day),
  963. onPointerLeave: () => setHoveredDay(null),
  964. }) as any,
  965. }}
  966. />
  967. </LocalizationProvider>
  968. )}
  969. {staffGradeManhoursSpentSelect === "Monthly" && (
  970. <LocalizationProvider dateAdapter={AdapterDayjs}>
  971. <DatePicker
  972. className="w-40 h-10 align-top"
  973. onChange={(newValue) =>
  974. selectStaffGradeMonthlyPeriodFrom(newValue)
  975. }
  976. defaultValue={
  977. totalManHoursByStaffGradeMonthlyFromValue
  978. }
  979. label={"Form"}
  980. views={["month", "year"]}
  981. />
  982. <DatePicker
  983. className="w-40 h-10 align-top"
  984. onChange={(newValue) =>
  985. selectStaffGradeMonthlyPeriodTo(newValue)
  986. }
  987. defaultValue={
  988. totalManHoursByStaffGradeMonthlyToValue
  989. }
  990. label={"To"}
  991. views={["month", "year"]}
  992. />
  993. </LocalizationProvider>
  994. )}
  995. {/* <Label className="text-slate-500 font-medium ml-6">
  996. Period:&nbsp;
  997. </Label>
  998. <Input
  999. id={'cashFlowYear'}
  1000. value={manHoursSpentPeriod}
  1001. readOnly={true}
  1002. bsSize="lg"
  1003. className="rounded-md text-base w-56 border-slate-200 border-solid text-slate-500 text-center"
  1004. /> */}
  1005. </div>
  1006. </div>
  1007. <ReactApexChart
  1008. options={staffGradeOptions}
  1009. series={staffGradeOptions.series}
  1010. type="bar"
  1011. height="400"
  1012. />
  1013. </div>
  1014. </Card>
  1015. </Grid>
  1016. </div>
  1017. </div>
  1018. <div
  1019. style={{
  1020. display: "inline-block",
  1021. width: "59%",
  1022. verticalAlign: "top",
  1023. marginLeft: 10,
  1024. }}
  1025. >
  1026. <Grid item xs={12} md={12} lg={12}>
  1027. <Card className="mb-5">
  1028. <CardHeader
  1029. className="text-slate-500"
  1030. title="Unsubmitted Time Sheet by Staff"
  1031. />
  1032. <div style={{ display: "inline-block", width: "99%" }}>
  1033. <div className="w-fit align-top mr-5 float-right">
  1034. {unsubmittedTimeSheetSelect === "Weekly" && (
  1035. <>
  1036. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid w-32">
  1037. Weekly
  1038. </button>
  1039. <button
  1040. onClick={() =>
  1041. unsubmittedTimeSheetOnClick("Monthly")
  1042. }
  1043. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-32"
  1044. >
  1045. Monthly
  1046. </button>
  1047. </>
  1048. )}
  1049. {unsubmittedTimeSheetSelect === "Monthly" && (
  1050. <>
  1051. <button
  1052. onClick={() =>
  1053. unsubmittedTimeSheetOnClick("Weekly")
  1054. }
  1055. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid w-32"
  1056. >
  1057. Weekly
  1058. </button>
  1059. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-r-md w-32">
  1060. Monthly
  1061. </button>
  1062. </>
  1063. )}
  1064. </div>
  1065. <div className="inline-block w-fit mt-2">
  1066. <div className="inline-block ml-6">
  1067. <Label className="text-slate-500 font-medium">
  1068. Team:&nbsp;
  1069. </Label>
  1070. </div>
  1071. <div className="inline-block ml-1 w-60">
  1072. <Select
  1073. placeholder="Team"
  1074. options={teamOptions}
  1075. isClearable={true}
  1076. />
  1077. </div>
  1078. <div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>
  1079. {/* <Label className="text-slate-500 font-medium ml-6">
  1080. Period:&nbsp;
  1081. </Label> */}
  1082. {unsubmittedTimeSheetSelect === "Weekly" && (
  1083. <LocalizationProvider dateAdapter={AdapterDayjs}>
  1084. <DatePicker
  1085. className="w-72 h-10 align-top"
  1086. label="Period:"
  1087. value={value}
  1088. format="DD-MM-YYYY"
  1089. onChange={(newValue) =>
  1090. selectWeeklyPeriodUnsubmittedTimeSheet(newValue)
  1091. }
  1092. showDaysOutsideCurrentMonth
  1093. displayWeekNumber
  1094. slots={{ day: Day }}
  1095. slotProps={{
  1096. day: (ownerState) =>
  1097. ({
  1098. selectedDay: value,
  1099. hoveredDay,
  1100. onPointerEnter: () =>
  1101. setHoveredDay(ownerState.day),
  1102. onPointerLeave: () => setHoveredDay(null),
  1103. }) as any,
  1104. }}
  1105. />
  1106. </LocalizationProvider>
  1107. )}
  1108. {unsubmittedTimeSheetSelect === "Monthly" && (
  1109. <LocalizationProvider dateAdapter={AdapterDayjs}>
  1110. <DatePicker
  1111. className="w-40 h-10 align-top"
  1112. onChange={(newValue) =>
  1113. selectUnsubmittedTimeSheetMonthlyPeriodFrom(newValue)
  1114. }
  1115. defaultValue={
  1116. totalManHoursByIndividualStaffMonthlyFromValue
  1117. }
  1118. label={"Form"}
  1119. views={["month", "year"]}
  1120. />
  1121. <DatePicker
  1122. className="w-40 h-10 align-top"
  1123. onChange={(newValue) =>
  1124. selectUnsubmittedTimeSheetMonthlyPeriodTo(newValue)
  1125. }
  1126. defaultValue={
  1127. totalManHoursByIndividualStaffMonthlyToValue
  1128. }
  1129. label={"To"}
  1130. views={["month", "year"]}
  1131. />
  1132. </LocalizationProvider>
  1133. )}
  1134. </div>
  1135. </div>
  1136. <ReactApexChart
  1137. options={unsubmittedTimeSheetOptions}
  1138. series={unsubmittedTimeSheetOptions.series}
  1139. type="bar"
  1140. height="380"
  1141. />
  1142. </div>
  1143. </Card>
  1144. <Card>
  1145. <Card>
  1146. <CardHeader
  1147. className="text-slate-500"
  1148. title="Manhours Spent by Individual Staff"
  1149. />
  1150. <div style={{ display: "inline-block", width: "99%" }}>
  1151. <div className="w-fit align-top mr-5 float-right">
  1152. {individualStaffManhoursSpentSelect === "Daily" && (
  1153. <>
  1154. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-l-md w-32">
  1155. Daily
  1156. </button>
  1157. <button
  1158. onClick={() =>
  1159. individualStaffManhoursSpentOnClick("Weekly")
  1160. }
  1161. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid w-32"
  1162. >
  1163. Weekly
  1164. </button>
  1165. <button
  1166. onClick={() =>
  1167. individualStaffManhoursSpentOnClick("Monthly")
  1168. }
  1169. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-32"
  1170. >
  1171. Monthly
  1172. </button>
  1173. </>
  1174. )}
  1175. {individualStaffManhoursSpentSelect === "Weekly" && (
  1176. <>
  1177. <button
  1178. onClick={() =>
  1179. individualStaffManhoursSpentOnClick("Daily")
  1180. }
  1181. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-l-md w-32"
  1182. >
  1183. Daily
  1184. </button>
  1185. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid w-32">
  1186. Weekly
  1187. </button>
  1188. <button
  1189. onClick={() =>
  1190. individualStaffManhoursSpentOnClick("Monthly")
  1191. }
  1192. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-r-md w-32"
  1193. >
  1194. Monthly
  1195. </button>
  1196. </>
  1197. )}
  1198. {individualStaffManhoursSpentSelect === "Monthly" && (
  1199. <>
  1200. <button
  1201. onClick={() =>
  1202. individualStaffManhoursSpentOnClick("Daily")
  1203. }
  1204. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid rounded-l-md w-32"
  1205. >
  1206. Daily
  1207. </button>
  1208. <button
  1209. onClick={() =>
  1210. individualStaffManhoursSpentOnClick("Weekly")
  1211. }
  1212. className="hover:cursor-pointer hover:bg-violet-50 text-lg bg-transparent border-violet-500 text-violet-500 border-solid w-32"
  1213. >
  1214. Weekly
  1215. </button>
  1216. <button className="text-lg bg-violet-100 border-violet-500 text-violet-500 border-solid rounded-r-md w-32">
  1217. Monthly
  1218. </button>
  1219. </>
  1220. )}
  1221. </div>
  1222. <div className="inline-block w-fit mt-2">
  1223. <div className="inline-block ml-6">
  1224. <Label className="text-slate-500 font-medium">
  1225. Staff Code and Name:&nbsp;
  1226. </Label>
  1227. </div>
  1228. <div className="inline-block ml-1 w-60">
  1229. <Select
  1230. placeholder="00338-Chris Wong"
  1231. options={teamOptions}
  1232. isClearable={true}
  1233. />
  1234. </div>
  1235. <div className="ml-6 mt-2" style={{ verticalAlign: "top" }}>
  1236. {/* <Label className="text-slate-500 font-medium ml-6">
  1237. Period:&nbsp;
  1238. </Label> */}
  1239. {individualStaffManhoursSpentSelect === "Daily" && (
  1240. <LocalizationProvider dateAdapter={AdapterDayjs}>
  1241. <DatePicker
  1242. className="w-40 h-10 align-top"
  1243. onChange={(newValue) =>
  1244. selectIndividualStaffMonthlyPeriodFrom(newValue)
  1245. }
  1246. defaultValue={
  1247. totalManHoursByIndividualStaffDailyFromValue
  1248. }
  1249. label={"Form"}
  1250. views={["day", "month", "year"]}
  1251. />
  1252. <DatePicker
  1253. className="w-40 h-10 align-top"
  1254. onChange={(newValue) =>
  1255. selectIndividualStaffMonthlyPeriodTo(newValue)
  1256. }
  1257. defaultValue={
  1258. totalManHoursByIndividualStaffDailyToValue
  1259. }
  1260. label={"To"}
  1261. views={["day", "month", "year"]}
  1262. />
  1263. </LocalizationProvider>
  1264. )}
  1265. {individualStaffManhoursSpentSelect === "Weekly" && (
  1266. <LocalizationProvider dateAdapter={AdapterDayjs}>
  1267. <DatePicker
  1268. className="w-72 h-10 align-top"
  1269. label="Period:"
  1270. value={value}
  1271. format="DD-MM-YYYY"
  1272. onChange={(newValue) =>
  1273. selectWeeklyPeriodIndividualStaff(newValue)
  1274. }
  1275. showDaysOutsideCurrentMonth
  1276. displayWeekNumber
  1277. slots={{ day: Day }}
  1278. slotProps={{
  1279. day: (ownerState) =>
  1280. ({
  1281. selectedDay: value,
  1282. hoveredDay,
  1283. onPointerEnter: () =>
  1284. setHoveredDay(ownerState.day),
  1285. onPointerLeave: () => setHoveredDay(null),
  1286. }) as any,
  1287. }}
  1288. />
  1289. </LocalizationProvider>
  1290. )}
  1291. {individualStaffManhoursSpentSelect === "Monthly" && (
  1292. <LocalizationProvider dateAdapter={AdapterDayjs}>
  1293. <DatePicker
  1294. className="w-40 h-10 align-top"
  1295. onChange={(newValue) =>
  1296. selectIndividualStaffMonthlyPeriodFrom(newValue)
  1297. }
  1298. defaultValue={
  1299. totalManHoursByIndividualStaffMonthlyFromValue
  1300. }
  1301. label={"Form"}
  1302. views={["month", "year"]}
  1303. />
  1304. <DatePicker
  1305. className="w-40 h-10 align-top"
  1306. onChange={(newValue) =>
  1307. selectIndividualStaffMonthlyPeriodTo(newValue)
  1308. }
  1309. defaultValue={
  1310. totalManHoursByIndividualStaffMonthlyToValue
  1311. }
  1312. label={"To"}
  1313. views={["month", "year"]}
  1314. />
  1315. </LocalizationProvider>
  1316. )}
  1317. </div>
  1318. </div>
  1319. <ReactApexChart
  1320. options={individualStaffOptions}
  1321. series={individualStaffOptions.series}
  1322. type="bar"
  1323. height="380"
  1324. />
  1325. </div>
  1326. </Card>
  1327. <div style={{ display: "inline-block", width: "50%" }}>
  1328. <div
  1329. style={{
  1330. display: "inline-block",
  1331. width: "47%",
  1332. marginTop: 10,
  1333. marginLeft: 10,
  1334. }}
  1335. >
  1336. <Card style={{ height: 90 }}>
  1337. <div className="text-slate-500 text-center text-base">
  1338. Total Normal Hours Spent
  1339. </div>
  1340. <div
  1341. className="text-center w-full text-3xl font-bold"
  1342. style={{ color: "#92c1e9" }}
  1343. >
  1344. 40.00
  1345. </div>
  1346. </Card>
  1347. <Card style={{ marginTop: 10, height: 90 }}>
  1348. <div className="text-slate-500 text-center text-base">
  1349. Total Leave Hours
  1350. </div>
  1351. <div
  1352. className="text-center w-full text-3xl font-bold"
  1353. style={{ color: "#898d8d", marginTop: 10 }}
  1354. >
  1355. 0.00
  1356. </div>
  1357. </Card>
  1358. </div>
  1359. <div
  1360. style={{
  1361. display: "inline-block",
  1362. width: "47%",
  1363. marginTop: 10,
  1364. marginLeft: 10,
  1365. }}
  1366. >
  1367. <Card style={{ height: 90 }}>
  1368. <div className="text-slate-500 text-center text-base">
  1369. Total Other Hours Spent
  1370. </div>
  1371. <div
  1372. className="text-center w-full text-3xl font-bold"
  1373. style={{ color: "#92c1e9" }}
  1374. >
  1375. 7.00
  1376. </div>
  1377. </Card>
  1378. <Card style={{ marginTop: 10, height: 90 }}>
  1379. <div className="text-slate-500 text-center text-base">
  1380. Remaining Hours
  1381. </div>
  1382. <div
  1383. className="text-center w-full text-3xl font-bold"
  1384. style={{ color: "#898d8d", marginTop: 10 }}
  1385. >
  1386. 0.00
  1387. </div>
  1388. </Card>
  1389. </div>
  1390. </div>
  1391. <div style={{ display: "inline-block", width: "50%",verticalAlign:"top",marginTop:10}}>
  1392. <Card>
  1393. <CardHeader className="text-slat-500" title="Effort Proportion for individual Staff"/>
  1394. <ReactApexChart
  1395. options={options2}
  1396. series={options2.series}
  1397. type="donut"
  1398. />
  1399. </Card>
  1400. </div>
  1401. </Card>
  1402. </Grid>
  1403. </div>
  1404. </Grid>
  1405. </>
  1406. );
  1407. };
  1408. export default StaffUtilization;