"use client"; import * as React from "react"; import Grid from "@mui/material/Grid"; import { useState,useEffect, useMemo } from 'react' import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; import {Card,CardHeader} from '@mui/material'; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; import ReactApexChart from 'react-apexcharts'; import { ApexOptions } from 'apexcharts'; import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; import ReportProblemIcon from '@mui/icons-material/ReportProblem'; import dynamic from 'next/dynamic'; import '../../app/global.css'; import { AnyARecord, AnyCnameRecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import { Suspense } from "react"; import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; import {Input,Label} from "reactstrap"; import Select, {components} from 'react-select'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import dayjs, { Dayjs } from 'dayjs'; import isBetweenPlugin from 'dayjs/plugin/isBetween'; import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay'; import { styled } from '@mui/material/styles'; dayjs.extend(isBetweenPlugin); interface CustomPickerDayProps extends PickersDayProps { isSelected: boolean; isHovered: boolean; } const CustomPickersDay = styled(PickersDay, { shouldForwardProp: (prop) => prop !== 'isSelected' && prop !== 'isHovered', })(({ theme, isSelected, isHovered, day }) => ({ borderRadius: 0, ...(isSelected && { backgroundColor: theme.palette.primary.main, color: theme.palette.primary.contrastText, '&:hover, &:focus': { backgroundColor: theme.palette.primary.main, }, }), ...(isHovered && { backgroundColor: theme.palette.primary[theme.palette.mode], '&:hover, &:focus': { backgroundColor: theme.palette.primary[theme.palette.mode], }, }), ...(day.day() === 0 && { borderTopLeftRadius: '50%', borderBottomLeftRadius: '50%', }), ...(day.day() === 6 && { borderTopRightRadius: '50%', borderBottomRightRadius: '50%', }), })) as React.ComponentType; const isInSameWeek = (dayA: Dayjs, dayB: Dayjs | null | undefined) => { if (dayB == null) { return false; } return dayA.isSame(dayB, 'week'); }; function Day( props: PickersDayProps & { selectedDay?: Dayjs | null; hoveredDay?: Dayjs | null; }, ) { const { day, selectedDay, hoveredDay, ...other } = props; return ( ); } const StaffUtilization: React.FC = () => { const todayDate = new Date; const firstDayOfWeek = new Date; const lastDayOfWeek = new Date; firstDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 1); lastDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 7); const firstDayOfMonth = new Date(todayDate.getFullYear(), todayDate.getMonth(), 1); const lastDayOfMonth = new Date(todayDate.getFullYear(), todayDate.getMonth() + 1, 0); const [firstDayOfWeekString, setFirstDayOfWeekString] = React.useState(dayjs(firstDayOfWeek).format('DD MMM YYYY')); const [lastDayOfWeekString, setLastDayOfWeekString] = React.useState(dayjs(lastDayOfWeek).format('DD MMM YYYY')); const [firstDayOfMonthString, setFirstDayOfMonthString] = React.useState(dayjs(firstDayOfMonth).format('DD MMM YYYY')); const [lastDayOfMonthString, setLastDayOfMonthString] = React.useState(dayjs(lastDayOfMonth).format('DD MMM YYYY')) const [selectionModel, setSelectionModel] : any[] = React.useState([]); const [manHoursSpentPeriod, setManHoursSpentPeriod] : any[] = React.useState(firstDayOfWeekString + " to " + lastDayOfWeekString); const [teamTotalManhoursSpentSelect, setTeamTotalManhoursSpentSelect] :any = React.useState("Weekly") const [staffGradeManhoursSpentSelect, setStaffGradeManhoursSpentSelect] :any = React.useState("Weekly") const [individualStaffManhoursSpentSelect, setIndividualStaffManhoursSpentSelect] :any = React.useState("Daily") const weekDates :any[] = []; const monthDates :any[] = []; const currentDate = dayjs(); const sixMonthsAgo = currentDate.subtract(6, 'month'); for (let i = 0; i < 7; i++) { const currentDate = new Date(firstDayOfWeek); currentDate.setDate(firstDayOfWeek.getDate() + i); const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); weekDates.push(formattedDate); } for (let date = sixMonthsAgo.clone(); date.isBefore(currentDate, 'month'); date = date.add(1, 'month')) { monthDates.push(date.format('MM-YYYY')); } monthDates.push(currentDate.format('MM-YYYY')); // for (let i = firstDayOfMonth.getDate(); i <= lastDayOfMonth.getDate(); i++) { // const currentDate = new Date(todayDate.getFullYear(), todayDate.getMonth(), i); // const formattedDate = dayjs(currentDate).format('DD MMM'); // monthDates.push(formattedDate); // } const [teamTotalManhoursSpentPeriod, setTeamTotalManhoursSpentPeriod] : any[] = React.useState(weekDates) const [teamTotalManhoursByStaffGrade, setTeamTotalManhoursByStaffGrade] : any[] = React.useState(weekDates) const [individualStaffManhoursSpentPeriod, setIndividualStaffManhoursSpentPeriod] : any[] = React.useState(weekDates) const [teamTotalManhoursSpentPlanData, setTeamTotalManhoursSpentPlanData] : any[] = React.useState([42,42,42,42,42,0,0]) const [teamTotalManhoursSpentActualData, setTeamTotalManhoursSpentActualData] : any[] = React.useState([45,42,60,42,58,0,0]) const [hoveredDay, setHoveredDay] = React.useState(null); const [value, setValue] = React.useState(dayjs()); const [weeklyValueByStaffGrade, setWeeklyValueByStaffGrade] = React.useState(dayjs()); const [weeklyValueByIndividualStaff, setWeeklyValueByIndividualStaff] = React.useState(dayjs()); const [staffGradeManhoursSpentValue, setStaffGradeManhoursSpentValue] = React.useState(dayjs()); const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] = React.useState(dayjs(new Date).subtract(6, 'month')); const [totalManHoursMonthlyToValue, setTotalManHoursMonthlyToValue] = React.useState(dayjs()); const [totalManHoursByStaffGradeMonthlyFromValue, setTotalManHoursByStaffGradeMonthlyFromValue] = React.useState(dayjs(new Date).subtract(6, 'month')); const [totalManHoursByStaffGradeMonthlyToValue, setTotalManHoursByStaffGradeMonthlyToValue] = React.useState(dayjs()); const [totalManHoursByIndividualStaffMonthlyFromValue, setTotalManHoursByIndividualStaffMonthlyFromValue] = React.useState(dayjs(new Date).subtract(6, 'month')); const [totalManHoursByIndividualStaffMonthlyToValue, setTotalManHoursByIndividualStaffMonthlyToValue] = React.useState(dayjs()); const [totalManHoursByIndividualStaffDailyFromValue, setTotalManHoursByIndividualStaffDailyFromValue] = React.useState(dayjs(new Date).subtract(6, 'day')); const [totalManHoursByIndividualStaffDailyToValue, setTotalManHoursByIndividualStaffDailyToValue] = React.useState(dayjs()); const [totalManHoursMaxValue, setTotalManHoursMaxValue] = React.useState(75); const teamOptions = [ { value: 1, label: 'XXX Team' }, { value: 2, label: 'YYY Team' }, { value: 3, label: 'ZZZ Team' } ] const columns = [ { id: 'projectCode', field: 'projectCode', headerName: "Project Code", flex: 1, }, { id: 'projectName', field: 'projectName', headerName: "Project Name", flex: 1, }, { id: 'team', field: 'team', headerName: "Team", flex: 1, }, { id: 'teamLeader', field: 'teamLeader', headerName: "Team Leader", flex: 1, }, { id: 'startDate', field: 'startDate', headerName: "Start Date", flex: 1, }, { id: 'targetEndDate', field: 'targetEndDate', headerName: "Target End Date", flex: 1, }, { id: 'client', field: 'client', headerName: "Client", flex: 1, }, { id: 'subsidiary', field: 'subsidiary', headerName: "Subsidiary", flex: 1, }, ]; const options: ApexOptions = { chart: { height: 350, type: 'line', }, stroke: { width: [2, 2] }, plotOptions: { bar: { horizontal: false, distributed: false, }, }, dataLabels: { enabled: true }, xaxis: { categories: teamTotalManhoursSpentPeriod }, yaxis: [ { title: { text: 'Team Total Manhours Spent (Hour)' }, min: 0, max: totalManHoursMaxValue, tickAmount: 5 }, ], grid: { borderColor: '#f1f1f1', }, annotations: { }, series:[ { name:"Planned", type:"line", color: "#efbe7d", data:teamTotalManhoursSpentPlanData }, { name:"Actual", type:"line", color: "#7cd3f2", data:teamTotalManhoursSpentActualData } ] }; const staffGradeOptions: ApexOptions = { chart: { height: 350, type: 'line', }, stroke: { width: [2, 2] }, plotOptions: { bar: { horizontal: true, distributed: false, }, }, dataLabels: { enabled: true }, xaxis: { categories: [ "Grade 1: A. QS / QS Trainee", "Grade 2: QS", "Grade 3: Senior QS", "Grade 4: Manager", "Grade 5: Director" ] }, yaxis: [ { title: { text: 'Staff Grade' }, min: 0, max: 60, tickAmount: 5 }, ], grid: { borderColor: '#f1f1f1', }, annotations: { }, series:[ { name:"Planned", type:"bar", color: "#efbe7d", data:[35,45,35,20,10] }, { name:"Actual", type:"bar", color: "#00acb1", data:[25,26,33,20,11] } ] }; const individualStaffOptions: ApexOptions = { chart: { height: 350, type: 'line', }, stroke: { width: [1] }, plotOptions: { bar: { horizontal: true, distributed: false, }, }, dataLabels: { enabled: true }, xaxis: { categories: [ "Consultancy Project 123 (CUST-001, Subsidiary A)", "Consultancy Project 456 (CUST-001, Subsidiary A)", "Construction Project A (CUST-001, Subsidiary A)", "Construction Project B (CUST-001, Subsidiary A)", "Construction Project C (CUST-001, Subsidiary A)" ] }, yaxis: [ { title: { text: 'Project' }, min: 0, max: 12, tickAmount: 5 }, ], grid: { borderColor: '#f1f1f1', }, annotations: { }, series:[ { name:"Manhours(Hour)", type:"bar", color: "#00acb1", data:[12,12,11,12,0] } ] }; const teamTotalManhoursSpentOnClick = (r:any) => { setTeamTotalManhoursSpentSelect(r) if (r === "Weekly") { setValue(dayjs(new Date)) setTeamTotalManhoursSpentPeriod(weekDates) setTeamTotalManhoursSpentPlanData([42,42,42,42,42,0,0]) setTeamTotalManhoursSpentActualData([45,42,60,42,58,0,0]) setTotalManHoursMaxValue(75) } else if (r === "Monthly") { setTeamTotalManhoursSpentPeriod(monthDates) setTeamTotalManhoursSpentPlanData([840,840,840,840,840,840]) setTeamTotalManhoursSpentActualData([900,840,1200,840,1160,840]) setTotalManHoursMaxValue(1250) } }; const individualStaffManhoursSpentOnClick = (r:any) => { setIndividualStaffManhoursSpentSelect(r) // if (r === "Weekly") { // setValue(dayjs(new Date)) // setTeamTotalManhoursSpentPeriod(weekDates) // setTeamTotalManhoursSpentPlanData([42,42,42,42,42,0,0]) // setTeamTotalManhoursSpentActualData([45,42,60,42,58,0,0]) // setTotalManHoursMaxValue(75) // } else if (r === "Monthly") { // setTeamTotalManhoursSpentPeriod(monthDates) // setTeamTotalManhoursSpentPlanData([840,840,840,840,840,840]) // setTeamTotalManhoursSpentActualData([900,840,1200,840,1160,840]) // setTotalManHoursMaxValue(1250) // } }; const selectWeeklyPeriod = (r:any) => { const selectDate = new Date(r); const firstDayOfWeek = new Date; firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); const weekDates :any[] = []; for (let i = 0; i < 7; i++) { const currentDate = new Date(firstDayOfWeek); currentDate.setDate(firstDayOfWeek.getDate() + i); const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); weekDates.push(formattedDate); } setTeamTotalManhoursSpentPeriod(weekDates) setValue(dayjs(firstDayOfWeek)) } const selectWeeklyPeriodByStaffGrade = (r:any) => { const selectDate = new Date(r); const firstDayOfWeek = new Date; firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); const weekDates :any[] = []; for (let i = 0; i < 7; i++) { const currentDate = new Date(firstDayOfWeek); currentDate.setDate(firstDayOfWeek.getDate() + i); const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); weekDates.push(formattedDate); } setTeamTotalManhoursByStaffGrade(weekDates) setWeeklyValueByStaffGrade(dayjs(firstDayOfWeek)) } const selectWeeklyPeriodIndividualStaff = (r:any) => { const selectDate = new Date(r); const firstDayOfWeek = new Date; firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); const weekDates :any[] = []; for (let i = 0; i < 7; i++) { const currentDate = new Date(firstDayOfWeek); currentDate.setDate(firstDayOfWeek.getDate() + i); const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); weekDates.push(formattedDate); } setIndividualStaffManhoursSpentPeriod(weekDates) setWeeklyValueByIndividualStaff(dayjs(firstDayOfWeek)) } const selectMonthlyPeriodFrom = (r:any) => { const monthDates :any[] = []; const monthPlanData :any[] = []; const monthActualData :any[] = []; const selectFromDate = dayjs(r); for (let date = selectFromDate.clone(); date.isBefore(totalManHoursMonthlyToValue, 'month'); date = date.add(1, 'month')) { monthDates.push(date.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) } monthDates.push(totalManHoursMonthlyToValue.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) setTeamTotalManhoursSpentPlanData(monthPlanData) setTeamTotalManhoursSpentActualData(monthActualData) setTeamTotalManhoursSpentPeriod(monthDates) } const selectMonthlyPeriodTo = (r:any) => { const monthDates :any[] = []; const monthPlanData :any[] = []; const monthActualData :any[] = []; const selectToDate = dayjs(r); for (let date = totalManHoursMonthlyFromValue.clone(); date.isBefore(selectToDate, 'month'); date = date.add(1, 'month')) { monthDates.push(date.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) } monthDates.push(selectToDate.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) setTeamTotalManhoursSpentPlanData(monthPlanData) setTeamTotalManhoursSpentActualData(monthActualData) setTeamTotalManhoursSpentPeriod(monthDates) } const selectStaffGradeMonthlyPeriodFrom = (r:any) => { const monthDates :any[] = []; const monthPlanData :any[] = []; const monthActualData :any[] = []; const selectFromDate = dayjs(r); for (let date = selectFromDate.clone(); date.isBefore(totalManHoursMonthlyToValue, 'month'); date = date.add(1, 'month')) { monthDates.push(date.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) } monthDates.push(totalManHoursMonthlyToValue.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) // setTeamTotalManhoursSpentPlanData(monthPlanData) // setTeamTotalManhoursSpentActualData(monthActualData) setTeamTotalManhoursByStaffGrade(weekDates) } const selectStaffGradeMonthlyPeriodTo = (r:any) => { const monthDates :any[] = []; const monthPlanData :any[] = []; const monthActualData :any[] = []; const selectToDate = dayjs(r); for (let date = totalManHoursMonthlyFromValue.clone(); date.isBefore(selectToDate, 'month'); date = date.add(1, 'month')) { monthDates.push(date.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) } monthDates.push(selectToDate.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) // setTeamTotalManhoursSpentPlanData(monthPlanData) // setTeamTotalManhoursSpentActualData(monthActualData) setTeamTotalManhoursByStaffGrade(weekDates) } const selectIndividualStaffMonthlyPeriodFrom = (r:any) => { const monthDates :any[] = []; const monthPlanData :any[] = []; const monthActualData :any[] = []; const selectFromDate = dayjs(r); for (let date = selectFromDate.clone(); date.isBefore(totalManHoursMonthlyToValue, 'month'); date = date.add(1, 'month')) { monthDates.push(date.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) } monthDates.push(totalManHoursMonthlyToValue.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) // setTeamTotalManhoursSpentPlanData(monthPlanData) // setTeamTotalManhoursSpentActualData(monthActualData) setIndividualStaffManhoursSpentPeriod(weekDates) } const selectIndividualStaffMonthlyPeriodTo = (r:any) => { const monthDates :any[] = []; const monthPlanData :any[] = []; const monthActualData :any[] = []; const selectToDate = dayjs(r); for (let date = totalManHoursMonthlyFromValue.clone(); date.isBefore(selectToDate, 'month'); date = date.add(1, 'month')) { monthDates.push(date.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) } monthDates.push(selectToDate.format('MM-YYYY')); monthPlanData.push(840) monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) // setTeamTotalManhoursSpentPlanData(monthPlanData) // setTeamTotalManhoursSpentActualData(monthActualData) setIndividualStaffManhoursSpentPeriod(weekDates) } return ( <>
{teamTotalManhoursSpentSelect === "Weekly" && ( <> )} {teamTotalManhoursSpentSelect === "Monthly" && ( <> )}
*/}
{individualStaffManhoursSpentSelect === "Daily" && ( <> )} {individualStaffManhoursSpentSelect === "Weekly" && ( <> )} {individualStaffManhoursSpentSelect === "Monthly" && ( <> )}