"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 { DataGrid, 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 { getPossibleInstrumentationHookFilenames } from "next/dist/build/utils"; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Collapse from '@mui/material/Collapse'; import IconButton from '@mui/material/IconButton'; import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import { useSearchParams } from 'next/navigation'; import {fetchResourceSummaryDetailResult} from "@/app/api/resourcesummary/actions"; const ProjectResourceSummary: React.FC = () => { const searchParams = useSearchParams(); const projectId = searchParams.get('projectId'); const [SearchCriteria, setSearchCriteria] = React.useState({}); const { t } = useTranslation("dashboard"); const [selectionModel, setSelectionModel]: any[] = React.useState([]); const [projectName, setProjectName]:any = React.useState("NA"); const [projectFee, setProjectFee]:any = React.useState(0); const [status, setStatus]:any = React.useState("NA"); const [plannedResources, setPlannedResources]:any = React.useState(0); const [actualResourcesSpent, setActualResourcesSpent]:any = React.useState(0); const [remainingResources, setRemainingResources]:any = React.useState(0); const [dataList, setDataList]:any = React.useState(); const [rows,setRows]:any[] = React.useState([]); //[subStage, subTaskCount, subTotalPlanned, subTotalActual, subG1Planned, subG1Actual, subG2Planned, subG2Actual, subG3Planned, subG3Actual, subG4Planned, subG4Actual, subG5Planned, subG5Actual]:any[] function createData([stage, taskCount, totalPlanned, totalActual, g1Planned, g1Actual, g2Planned, g2Actual, g3Planned, g3Actual, g4Planned, g4Actual, g5Planned, g5Actual]: any[], task:any[]) { return { stage, taskCount, g1Planned, g1Actual, g2Planned, g2Actual, g3Planned, g3Actual, g4Planned, g4Actual, g5Planned, g5Actual, totalPlanned, totalActual, task:task // subStage, // subTaskCount, // subTotalPlanned, // subTotalActual, // subG1Planned, // subG1Actual, // subG2Planned, // subG2Actual, // subG3Planned, // subG3Actual, // subG4Planned, // subG4Actual, // subG5Planned, // subG5Actual } } const fetchData = async () => { var intProjectId = 0 if (projectId !== null) { intProjectId = parseInt(projectId); } if (intProjectId !== 0) { const result = await fetchResourceSummaryDetailResult(intProjectId); setProjectName(result[0].summaryInformation[0].projectCodeAndName) setProjectFee(result[0].summaryInformation[0].totalFee) setStatus(result[0].summaryInformation[0].status) setPlannedResources(result[0].summaryInformation[0].plannedResources) setActualResourcesSpent(result[0].summaryInformation[0].resourcesSpent) setRemainingResources(result[0].summaryInformation[0].remainingResources) console.log(result); const mainStageResult = result[0].summaryMainStage const subStageResult = result[0].summarySubStage const mainStageFullList = [] const subStageFullList = [] var tgID = mainStageResult[0].id var tID = subStageResult[0].id var subTgId = subStageResult[0].tgId var firstTg = true var firstT = true var mainStageList = [] var subStageList = [] var subStageSecondLayerList = [] var arrayNumber = 0 for (var i = 0; i < subStageResult.length ; i++) { if (subStageResult[i].id !== tID) { subStageSecondLayerList.push(subStageList) if (subStageResult[i].tgId !== subTgId) { subStageFullList.push(subStageSecondLayerList) subStageSecondLayerList = [] subTgId = subStageResult[i].tgId } tID = subStageResult[i].id firstT = true subStageList = [] } if (firstT === true) { subStageList.push(subStageResult[i].name) subStageList.push(subStageResult[i].taskCount) subStageList.push(subStageResult[i].totalPlannedResource) subStageList.push(subStageResult[i].totalActualResourcesSpent) firstT = false } if (subStageResult[i].id === tID) { subStageList.push(subStageResult[i].plannedResources) subStageList.push(subStageResult[i].actualResourcesSpent) } } console.log(subStageFullList) for (var i = 0; i < mainStageResult.length; i++) { if (mainStageResult[i].id !== tgID) { mainStageFullList.push(createData(mainStageList,subStageFullList[arrayNumber])) arrayNumber += 1 tgID = mainStageResult[i].id firstTg = true mainStageList = [] } if (firstTg === true) { mainStageList.push(mainStageResult[i].name) mainStageList.push(mainStageResult[i].taskCount) mainStageList.push(mainStageResult[i].totalPlannedResources) mainStageList.push(mainStageResult[i].totalActualResourcesSpent) firstTg = false } if (mainStageResult[i].id === tgID) { mainStageList.push(mainStageResult[i].plannedResources) mainStageList.push(mainStageResult[i].actualResourcesSpent) } } setRows(mainStageFullList) } } useEffect(() => { fetchData() }, [projectId]); function createTaskData(stage:any, taskCount:any, g1Planned:any, g1Actual:any, g2Planned:any, g2Actual:any, g3Planned:any, g3Actual:any, g4Planned:any, g4Actual:any, g5Planned:any, g5Actual:any, totalPlanned:any, totalActual:any) { return { stage, taskCount, g1Planned, g1Actual, g2Planned, g2Actual, g3Planned, g3Actual, g4Planned, g4Actual, g5Planned, g5Actual, totalPlanned, totalActual, } } const task1Rows:any = [ {stage:"1.1 Preparation of preliminary...",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"}, {stage:"1.2 Cash flow forecast",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"}, {stage:"1.3 Cost studies for alterative design solutions",taskCount:"-",g1Planned:"-",g1Actual:"115.00",g2Planned:"-", g2Actual:"36.00", g3Planned:"-", g3Actual:"28.00", g4Planned: "-", g4Actual:"7.00", g5Planned:"-", g5Actual:"1.75", totalPlanned:"-", totalActual:"188.00"}, {stage:"1.4 Attend design co-ordiantion / project",taskCount:"-",g1Planned:"-",g1Actual:"29.00",g2Planned:"-", g2Actual:"9.00", g3Planned:"-", g3Actual:"7.00", g4Planned: "-", g4Actual:"2.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"48.00"}, {stage:"1.5 Prepare / Review RIC",taskCount:"-",g1Planned:"-",g1Actual:"88.00",g2Planned:"-", g2Actual:"27.00", g3Planned:"-", g3Actual:"21.00", g4Planned: "-", g4Actual:"5.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"141.75"} ] const data:any = [ "Stage 1 - Design & Cost Planning / Estimating", "5", "576.00", "576.00", "192.00", "180.00", "144.00", "140.00", "38.40", "38.00", "9.60", "9.75", "960.00", "943.75", ]; // const rows = [ // createData(data,task1Rows), // // createData("Stage 2 - Tender Documentation","11", "384.00", "382.00", "128.00", "130.00", "96.00", "79.00", "25.60", "25.00", "6.40", "4.00", "640.00", "620.00",task2Rows), // // createData("Stage 3 - Tender Analysis & Report & Contract Documentation","7", "384.00", "300.00", "128.00", "130.00", "96.00", "79.00", "25.60", "25.00", "6.40", "4.00", "640.00", "538.00",task3Rows), // // createData("Stage 4 - Construction", "13", "480.00", "400.00", "160.00", "160.00", "120.00", "128.00", "32.00", "25.00", "8.00", "3.00", "800.00", "716.00",task4Rows), // // createData("Stage 5 - Miscellaneous", "4", "96.00", "-", "32.00", "-", "24.00", "-0", "6.40", "-", "1.600", "-", "160.00", "-",task5Rows), // // createData("","Total", "1920.00", "1658.00", "640.00", "600.00", "480.00", "426.00", "128.00", "113.00", "32.00", "20.75", "3,200.00", "2817.75",task6Rows), // ]; // const taskRows = [ // createTaskData("1.1 Preparation of preliminary...","-","-","172.00","-","54.00","-","42.00","-","12.00","-","3.00","-","283.00"), // ]; function Row(props:any) { const { row } = props; const [open, setOpen] = React.useState(false); return ( *': { borderBottom: 'unset' } }}> {row.task.length > 0 && ( setOpen(!open)} > {open ? : } )} {row.stage} {row.taskCount} {row.g1Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g1Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g2Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g2Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g3Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g3Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g4Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g4Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g5Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.g5Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.totalPlanned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.totalActual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} {row.task.map((taskRow:any) => (
{taskRow[0]}
{taskRow[1]}
{taskRow[4].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[5].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[6].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[7].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[8].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[9].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[10].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[11].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[12].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[13].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[2].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
{taskRow[3].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
))}
); } const projectResourcesRows = [ {id: 1,stage:"Stage 1 - Design & Cost Planning / Estimating",taskCount:"5",g1Planned:"576.00",g1Actual:"576.00",g2Planned:"192.00", g2Actual:"180.00", g3Planned:"144.00", g3Actual:"140.00", g4Planned: "38.40", g4Actual:"38S.00", g5Planned:"9.60", g5Actual:"9.75", totalPlanned:"960.00", totalActual:"943.75"}, {id: 2,stage:"1.1 Preparation of preliminary...",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"}, {id: 3,stage:"1.2 Cash flow forecast",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"}, {id: 4,stage:"1.3 Cost studies for alterative design solutions",taskCount:"-",g1Planned:"-",g1Actual:"115.00",g2Planned:"-", g2Actual:"36.00", g3Planned:"-", g3Actual:"28.00", g4Planned: "-", g4Actual:"7.00", g5Planned:"-", g5Actual:"1.75", totalPlanned:"-", totalActual:"188.00"}, {id: 5,stage:"1.4 Attend design co-ordiantion / project",taskCount:"-",g1Planned:"-",g1Actual:"29.00",g2Planned:"-", g2Actual:"9.00", g3Planned:"-", g3Actual:"7.00", g4Planned: "-", g4Actual:"2.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"48.00"}, {id: 6,stage:"1.5 Prepare / Review RIC",taskCount:"-",g1Planned:"-",g1Actual:"88.00",g2Planned:"-", g2Actual:"27.00", g3Planned:"-", g3Actual:"21.00", g4Planned: "-", g4Actual:"5.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"141.75"}, {id: 7,stage:"Stage 2 - Tender Documentation",taskCount:"11",g1Planned:"384.00",g1Actual:"382.00",g2Planned:"128.00", g2Actual:"130.00", g3Planned:"96.00", g3Actual:"79.00", g4Planned: "25.60", g4Actual:"25.00", g5Planned:"6.40", g5Actual:"4.00", totalPlanned:"640.00", totalActual:"620.00"}, {id: 8,stage:"Stage 3 - Tender Analysis & Report & Contract Documentation",taskCount:"7",g1Planned:"384.00",g1Actual:"300.00",g2Planned:"128.00", g2Actual:"130.00", g3Planned:"96.00", g3Actual:"79.00", g4Planned: "25.60", g4Actual:"25.00", g5Planned:"6.40", g5Actual:"4.00", totalPlanned:"640.00", totalActual:"538.00"}, {id: 9,stage:"Stage 4 - Construction",taskCount:"13",g1Planned:"480.00",g1Actual:"400.00",g2Planned:"160.00", g2Actual:"160.00", g3Planned:"120.00", g3Actual:"128.00", g4Planned: "32.00", g4Actual:"25.00", g5Planned:"8.00", g5Actual:"3.00", totalPlanned:"800.00", totalActual:"716.00"}, {id: 10,stage:"Stage 5 - Miscellaneous",taskCount:"4",g1Planned:"96.00",g1Actual:"-",g2Planned:"32.00", g2Actual:"-", g3Planned:"24.00", g3Actual:"-0", g4Planned: "6.40", g4Actual:"-", g5Planned:"1.600", g5Actual:"-", totalPlanned:"160.00", totalActual:"-"}, {id: 11,stage:"",taskCount:"Total",g1Planned:"1920.00",g1Actual:"1658.00",g2Planned:"640.00", g2Actual:"600.00", g3Planned:"480.00", g3Actual:"426.00", g4Planned: "128.00", g4Actual:"113.00", g5Planned:"32.00", g5Actual:"20.75", totalPlanned:"3,200.00", totalActual:"2817.75"}, ] const columns2 = [ { id: 'stage', field: 'stage', headerName: "Stage", flex: 2, }, { id: 'taskCount', field: 'taskCount', headerName: "Task Count", flex: 0.5, }, { id: 'g1Planned', field: 'g1Planned', headerName: "Planned", flex: 0.7, }, { id: 'g1Actual', field: 'g1Actual', headerName: "Actual", flex: 0.7, }, { id: 'g2Planned', field: 'g2Planned', headerName: "Planned", flex: 0.7, }, { id: 'g2Actual', field: 'g2Actual', headerName: "Actual", flex: 0.7, }, { id: 'g3Planned', field: 'g3Planned', headerName: "Planned", flex: 0.7, }, { id: 'g3Actual', field: 'g3Actual', headerName: "Actual", flex: 0.7, }, { id: 'g4Planned', field: 'g4Planned', headerName: "Planned", flex: 0.7, }, { id: 'g4Actual', field: 'g4Actual', headerName: "Actual", flex: 0.7, }, { id: 'g5Planned', field: 'g5Planned', headerName: "Planned", flex: 0.7, }, { id: 'g5Actual', field: 'g5Actual', headerName: "Actual", flex: 0.7, }, { id: 'totalPlanned', field: 'totalPlanned', headerName: "Planned", flex: 0.7, }, { id: 'totalActual', field: 'totalActual', headerName: "Actual", flex: 0.7, }, ]; const columnGroupingModel = [ { groupId: 'G1', children: [{ field: 'g1Planned' },{ field: 'g1Actual' }], headerClassName: 'groupColor', }, { groupId: 'G2', children: [{ field: 'g2Planned' },{ field: 'g2Actual' }], headerClassName: 'groupColor', }, { groupId: 'G3', children: [{ field: 'g3Planned' },{ field: 'g3Actual' }], headerClassName: 'groupColor', }, { groupId: 'G4', children: [{ field: 'g4Planned' },{ field: 'g4Actual' }], headerClassName: 'groupColor', }, { groupId: 'G5', children: [{ field: 'g5Planned' },{ field: 'g5Actual' }], headerClassName: 'groupColor', }, { groupId: 'Total', children: [{ field: 'totalPlanned' },{ field: 'totalActual' }], headerClassName: 'totalGroupColor', }, ]; return (
Project
{projectName}
Project Fee
HKD ${projectFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
Status
{status}
Planned Resources
{plannedResources.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Manhours
Actual Resources Spent
{actualResourcesSpent.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Manhours
Remaining Resources
{remainingResources.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Manhours
{/*
*/} {/*
*/} G1 G2 G3 G4 G5 Total Stage Task Count Planned Actual Planned Actual Planned Actual Planned Actual Planned Actual Planned Actual {rows.map((row:any) => ( ))}
{/*
*/}
); }; export default ProjectResourceSummary;