|
- "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 { 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 { ClientSubsidiaryProjectResult } from "@/app/api/clientprojects/actions";
- import { ClientProjectResult} from "@/app/api/clientprojects";
- import { ConstructionOutlined } from "@mui/icons-material";
- import ReactApexChart from "react-apexcharts";
- import { ApexOptions } from "apexcharts";
- import { useSearchParams } from 'next/navigation';
- import { fetchAllClientSubsidiaryProjects} from "@/app/api/clientprojects/actions";
- // const ReactApexChart = dynamic(() => import('react-apexcharts'), { ssr: false });
-
- interface Props {
- // clientSubsidiaryProjectResult: ClientSubsidiaryProjectResult[];
- }
-
- const ProgressByClient: React.FC<Props> = () => {
- const searchParams = useSearchParams();
- const customerId = searchParams.get('customerId');
- const subsidiaryId = searchParams.get('subsidiaryId');
- const [activeTab, setActiveTab] = useState("financialSummary");
- const [SearchCriteria, setSearchCriteria] = React.useState({});
- const { t } = useTranslation("dashboard");
-
- const [clientCode, setClientCode] = useState("");
- const [clientName, setClientName] = useState("");
- const [subsidiaryClientCode, setSubsidiaryClientCode] = useState("");
- const [subsidiaryClientName, setSubsidiaryClientName] = useState("");
- const [projectArray, setProjectArray]: any[] = useState([]);
- const [percentageArray, setPercentageArray]: any[] = useState([]);
- const [colorArray, setColorArray]: any[] = useState([]);
- const [selectionModel, setSelectionModel]: any[] = React.useState([]);
- const [pieChartColor, setPieChartColor]: any[] = React.useState([]);
- const [totalSpentPercentage, setTotalSpentPercentage]: any = React.useState();
- const [projectBudgetManhour, setProjectBudgetManhour]: any =
- React.useState("-");
- const [actualManhourSpent, setActualManhourSpent]: any = React.useState("-");
- const [remainedManhour, setRemainedManhour]: any = React.useState("-");
- const [lastUpdate, setLastUpdate]: any = React.useState("-");
- const [dropdownDemo, setDropdownDemo] = useState("");
- const [dateDemo, setDateDemo] = useState(null);
- const [checkboxDemo, setCheckboxDemo] = useState(false);
- const [receiptFromDate, setReceiptFromDate] = useState(null);
- const [receiptToDate, setReceiptToDate] = useState(null);
- const [selectedRows, setSelectedRows]:any[] = useState([]);
- const [chartProjectName, setChartProjectName]:any[] = useState([]);
- const [chartManhourConsumptionPercentage, setChartManhourConsumptionPercentage]:any[] = useState([]);
- const color = ["#f57f90", "#94f7d6", "#87c5f5", "#ab95f5", "#fcd68b"];
- const [clientSubsidiaryProjectResult, setClientSubsidiaryProjectResult]:any[] = useState([]);
-
- const fetchData = async () => {
- if (customerId && subsidiaryId) {
- try {
- if (subsidiaryId === '-'){
- console.log("ss")
- const clickResult = await fetchAllClientSubsidiaryProjects(
- Number(customerId),Number(0))
- console.log(clickResult)
- setClientSubsidiaryProjectResult(clickResult);
- } else {
- const clickResult = await fetchAllClientSubsidiaryProjects(
- Number(customerId),
- Number(subsidiaryId))
- console.log(clickResult)
- setClientSubsidiaryProjectResult(clickResult);
- }
-
-
- } catch (error) {
- console.error('Error fetching client subsidiary projects:', error);
- }
- }
- }
-
- useEffect(() => {
- const projectName = []
- const manhourConsumptionPercentage = []
- for (let i = 0; i < clientSubsidiaryProjectResult.length; i++){
- clientSubsidiaryProjectResult[i].color = color[i]
- projectName.push(clientSubsidiaryProjectResult[i].projectName)
- manhourConsumptionPercentage.push(clientSubsidiaryProjectResult[i].manhourConsumptionPercentage)
- }
- setChartProjectName(projectName)
- setChartManhourConsumptionPercentage(manhourConsumptionPercentage)
- }, [clientSubsidiaryProjectResult]);
-
- useEffect(() => {
- fetchData()
- }, [customerId,subsidiaryId]);
-
-
-
- const rows2 = [
- {
- id: 1,
- project: "Consultancy Project 123",
- team: "XXX",
- teamLeader: "XXX",
- currentStage: "Contract Documentation",
- budgetedManhour: "200.00",
- spentManhour: "120.00",
- remainedManhour: "80.00",
- comingPaymentMilestone: "31/03/2024",
- alert: false,
- color: "#f57f90",
- },
- {
- id: 2,
- project: "Consultancy Project 456",
- team: "XXX",
- teamLeader: "XXX",
- currentStage: "Report Preparation",
- budgetedManhour: "400.00",
- spentManhour: "200.00",
- remainedManhour: "200.00",
- comingPaymentMilestone: "20/02/2024",
- alert: false,
- color: "#94f7d6",
- },
- {
- id: 3,
- project: "Construction Project A",
- team: "YYY",
- teamLeader: "YYY",
- currentStage: "Construction",
- budgetedManhour: "187.50",
- spentManhour: "200.00",
- remainedManhour: "12.50",
- comingPaymentMilestone: "13/12/2023",
- alert: true,
- color: "#87c5f5",
- },
- {
- id: 4,
- project: "Construction Project B",
- team: "XXX",
- teamLeader: "XXX",
- currentStage: "Post Construction",
- budgetedManhour: "100.00",
- spentManhour: "40.00",
- remainedManhour: "60.00",
- comingPaymentMilestone: "05/01/2024",
- alert: false,
- color: "#ab95f5",
- },
- {
- id: 5,
- project: "Construction Project C",
- team: "YYY",
- teamLeader: "YYY",
- currentStage: "Construction",
- budgetedManhour: "300.00",
- spentManhour: "150.00",
- remainedManhour: "150.00",
- comingPaymentMilestone: "31/03/2024",
- alert: false,
- color: "#fcd68b",
- },
- ];
-
- const columns2 = [
- {
- id: "color",
- field: "color",
- headerName: "",
- renderCell: (param: any) => {
- return (
- <span
- className="dot"
- style={{
- height: "15px",
- width: "15px",
- borderRadius: "50%",
- backgroundColor: `${param.row.color}`,
- display: "inline-block",
- }}
- ></span>
- );
- },
- flex:0.1
- },
- {
- id: "projectName",
- field: "projectName",
- headerName: "Project",
- minWidth:300
- },
- {
- id: "team",
- field: "team",
- headerName: "Team",
- minWidth: 50
- },
- {
- id: "teamLead",
- field: "teamLead",
- headerName: "Team Leader",
- minWidth: 70
- },
- {
- id: "expectedStage",
- field: "expectedStage",
- headerName: "Expected Stage",
- minWidth: 300
- },
- {
- id: "budgetedManhour",
- field: "budgetedManhour",
- headerName: "Budgeted Manhour",
- minWidth: 70
- },
- {
- id: "spentManhour",
- field: "spentManhour",
- headerName: "Spent Manhour",
- renderCell: (params: any) => {
- if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
- return (
- <span className="text-red-300">{params.row.spentManhour}</span>
- );
- } else {
- console.log(params)
- return <span>{params.row.spentManhour}</span>;
- }
- },
- minWidth: 70
- },
- {
- id: "remainedManhour",
- field: "remainedManhour",
- headerName: "Remained Manhour",
- renderCell: (params: any) => {
- if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
- return (
- <span className="text-red-300">({params.row.remainedManhour})</span>
- );
- } else {
- return <span>{params.row.remainedManhour}</span>;
- }
- },
- minWidth: 70
- },
- {
- id: "comingPaymentMilestone",
- field: "comingPaymentMilestone",
- headerName: "Coming Payment Milestone",
- minWidth: 100
- },
- {
- id: "alert",
- field: "alert",
- headerName: "Alert",
- renderCell: (params: any) => {
- if (params.row.alert === true) {
- return (
- <span className="text-red-300 text-center">
- <ReportProblemIcon />
- </span>
- );
- } else {
- return <span></span>;
- }
- },
- flex:0.1
- },
- ];
- const optionstest: ApexOptions = {
- chart: {
- height: 350,
- type: "line",
- },
- stroke: {
- width: [0, 0, 2, 2],
- },
- plotOptions: {
- bar: {
- horizontal: false,
- distributed: false,
- },
- },
- dataLabels: {
- enabled: false,
- },
- xaxis: {
- categories: [
- "Q1",
- "Q2",
- "Q3",
- "Q4",
- "Q5",
- "Q6",
- "Q7",
- "Q8",
- "Q9",
- "Q10",
- "Q11",
- "Q12",
- ],
- },
- yaxis: [
- {
- title: {
- text: "Monthly Income and Expenditure(HKD)",
- },
- min: 0,
- max: 350000,
- tickAmount: 5,
- labels: {
- formatter: function (val) {
- return val.toLocaleString()
- }
- }
- },
- {
- show: false,
- seriesName: "Monthly_Expenditure",
- title: {
- text: "Monthly Expenditure (HKD)",
- },
- min: 0,
- max: 350000,
- tickAmount: 5,
- },
- {
- seriesName: "Cumulative_Income",
- opposite: true,
- title: {
- text: "Cumulative Income and Expenditure(HKD)",
- },
- min: 0,
- max: 850000,
- tickAmount: 5,
- labels: {
- formatter: function (val) {
- return val.toLocaleString()
- }
- }
- },
- {
- show: false,
- seriesName: "Cumulative_Expenditure",
- opposite: true,
- title: {
- text: "Cumulative Expenditure (HKD)",
- },
- min: 0,
- max: 850000,
- tickAmount: 5,
- },
- ],
- grid: {
- borderColor: "#f1f1f1",
- },
- annotations: {},
- series: [
- {
- name: "Monthly_Income",
- type: "column",
- color: "#ffde91",
- data: [0, 110000, 0, 0, 185000, 0, 0, 189000, 0, 0, 300000, 0],
- },
- {
- name: "Monthly_Expenditure",
- type: "column",
- color: "#82b59a",
- data: [
- 0, 160000, 120000, 120000, 55000, 55000, 55000, 55000, 55000, 70000,
- 55000, 55000,
- ],
- },
- {
- name: "Cumulative_Income",
- type: "line",
- color: "#EE6D7A",
- data: [
- 0, 100000, 100000, 100000, 300000, 300000, 300000, 500000, 500000,
- 500000, 800000, 800000,
- ],
- },
- {
- name: "Cumulative_Expenditure",
- type: "line",
- color: "#7cd3f2",
- data: [
- 0, 198000, 240000, 400000, 410000, 430000, 510000, 580000, 600000,
- 710000, 730000, 790000,
- ],
- },
- ],
- };
-
- const options2: ApexOptions = {
- chart: {
- type: "donut",
- },
- colors: colorArray,
- plotOptions: {
- pie: {
- donut: {
- labels: {
- show: true,
- name: {
- show: true,
- },
- value: {
- show: true,
- fontWeight: 500,
- fontSize: "30px",
- color: "#3e98c7",
- },
- total: {
- show: true,
- showAlways: true,
- label: "Spent",
- fontFamily: "sans-serif",
- formatter: function (val) {
- return totalSpentPercentage + "%";
- },
- },
- },
- },
- },
- },
- labels: projectArray,
- legend: {
- show: false,
- },
- responsive: [
- {
- breakpoint: 480,
- options: {
- chart: {
- width: 200,
- },
- legend: {
- position: "bottom",
- show: false,
- },
- },
- },
- ],
- };
-
- const options: ApexOptions = {
- chart: {
- type: "bar",
- height: 350,
- },
- series: [{
- name: "Project Resource Consumption Percentage",
- data: chartManhourConsumptionPercentage,
- },],
- colors: ["#f57f90", "#94f7d6", "#87c5f5", "#ab95f5", "#fcd68b"],
- plotOptions: {
- bar: {
- horizontal: true,
- distributed: true,
- },
- },
- dataLabels: {
- enabled: false,
- },
- xaxis: {
- categories: chartProjectName,
- },
- yaxis: {
- title: {
- text: "Projects",
- },
- labels: {
- maxWidth: 200,
- style: {
- cssClass: "apexcharts-yaxis-label",
- },
- },
- },
- title: {
- text: "Project Resource Consumption Percentage",
- align: "center",
- },
- grid: {
- borderColor: "#f1f1f1",
- },
- annotations: {},
- };
-
- const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => {
- const selectedRowsData:any = clientSubsidiaryProjectResult.filter((row:any) =>
- newSelectionModel.includes(row.projectId),
- );
- console.log(selectedRowsData);
- const projectArray = [];
- const pieChartColorArray = [];
- let totalSpent = 0;
- let totalBudgetManhour = 0;
- const percentageArray = [];
- for (let i = 0; i <= selectedRowsData.length; i++) {
- if (i === selectedRowsData.length && i > 0) {
- projectArray.push("Remained");
- } else if (selectedRowsData.length > 0) {
- projectArray.push(selectedRowsData[i].projectName);
- totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour);
- totalSpent += Number(selectedRowsData[i].spentManhour);
- pieChartColorArray.push(color[i]);
- }
- }
- for (let i = 0; i <= selectedRowsData.length; i++) {
- if (i === selectedRowsData.length && i > 0) {
- const remainedManhour = totalBudgetManhour - totalSpent;
- percentageArray.push(
- Number(((remainedManhour / totalBudgetManhour) * 100).toFixed(1)),
- );
- } else if (selectedRowsData.length > 0) {
- const percentage = (
- (Number(selectedRowsData[i].spentManhour) / totalBudgetManhour) *
- 100
- ).toFixed(1);
- percentageArray.push(Number(percentage));
- }
- }
- setProjectBudgetManhour(totalBudgetManhour.toFixed(2));
- setActualManhourSpent(totalSpent.toFixed(2));
- setRemainedManhour((totalBudgetManhour - totalSpent).toFixed(2));
- setLastUpdate(new Date().toLocaleDateString("en-GB"));
- setSelectionModel(newSelectionModel);
- console.log(projectArray);
- setProjectArray(projectArray);
- setPercentageArray(percentageArray);
- console.log(percentageArray);
- setTotalSpentPercentage(
- ((totalSpent / totalBudgetManhour) * 100).toFixed(1),
- );
- if (projectArray.length > 0 && projectArray.includes("Remained")) {
- const nonLastRecordColors = pieChartColorArray;
- setColorArray([
- ...nonLastRecordColors.slice(0, projectArray.length - 1),
- "#a3a3a3",
- ]);
- } else {
- setColorArray(pieChartColorArray);
- }
- };
-
- const applySearch = (data: any) => {
- console.log(data);
- setSearchCriteria(data);
- };
- return (
- <Grid item sm>
- {/* <CustomSearchForm applySearch={applySearch} fields={InputFields}/> */}
- {/* <CustomDatagrid rows={rows} columns={columns} columnWidth={200} dataGridHeight={300}/> */}
- <div style={{ display: "inline-block", width: "70%" }}>
- <Grid item xs={12} md={12} lg={12}>
- <Card>
- <CardHeader className="text-slate-500" title="Project Resource Consumption" />
- <div style={{ display: "inline-block", width: "99%" }}>
- <ReactApexChart
- options={options}
- series={options.series}
- type="bar"
- height={350}
- />
- </div>
- {/* <div style={{display:"inline-block",width:"20%",verticalAlign:"top",textAlign:"center"}}>
- <p><strong><u>Stage Deadline</u></strong></p>
- {stageDeadline.map((date, index) => {
- const marginTop = index === 0 ? 25 : 20;
- return (
- <p style={{marginTop:marginTop}} key={index}>{date}</p>
- );
- })}
- </div> */}
- <CardHeader
- className="text-slate-500"
- title="Current Stage Due Date"
- />
- <div
- style={{ display: "inline-block", width: "99%", marginLeft: 10 }}
- >
- <CustomDatagrid
- rows={clientSubsidiaryProjectResult}
- columns={columns2}
- columnWidth={200}
- dataGridHeight={300}
- checkboxSelection={true}
- onRowSelectionModelChange={handleSelectionChange}
- selectionModel={selectionModel}
- />
- </div>
- </Card>
- </Grid>
- </div>
- <div
- style={{
- display: "inline-block",
- width: "30%",
- verticalAlign: "top",
- marginLeft: 0,
- }}
- >
- <Grid item xs={12} md={12} lg={12}>
- <Card style={{ marginLeft: 15, marginRight: 20 }}>
- <CardHeader
- className="text-slate-500"
- title="Overall Progress per Project"
- />
- {percentageArray.length === 0 && (
- <div
- className="mt-10 mb-10 ml-5 mr-5 text-lg font-medium text-center"
- style={{ color: "#898d8d" }}
- >
- Please select the project you want to check.
- </div>
- )}
- {percentageArray.length > 0 && (
- <ReactApexChart
- options={options2}
- series={percentageArray}
- type="donut"
- />
- )}
- </Card>
- </Grid>
- <Grid item xs={12} md={12} lg={12}>
- <Card style={{ marginLeft: 15, marginRight: 20, marginTop: 20 }}>
- <div>
- <div
- className="mt-5 text-lg font-medium"
- style={{ color: "#898d8d" }}
- >
- <span style={{ marginLeft: "5%" }}>Project Budget Manhour</span>
- </div>
- <div
- className="mt-2 text-2xl font-extrabold"
- style={{ color: "#6b87cf" }}
- >
- <span style={{ marginLeft: "5%" }}>{projectBudgetManhour}</span>
- </div>
- </div>
- <hr />
- <div>
- <div
- className="mt-2 text-lg font-medium"
- style={{ color: "#898d8d" }}
- >
- <span style={{ marginLeft: "5%" }}>Actual Manhour Spent</span>
- </div>
- <div
- className="mt-2 text-2xl font-extrabold"
- style={{ color: "#6b87cf" }}
- >
- <span style={{ marginLeft: "5%" }}>{actualManhourSpent}</span>
- </div>
- </div>
- <hr />
- <div>
- <div
- className="mt-2 text-lg font-medium"
- style={{ color: "#898d8d" }}
- >
- <span style={{ marginLeft: "5%" }}>Remained Manhour</span>
- </div>
- <div
- className="mt-2 text-2xl font-extrabold"
- style={{ color: "#6b87cf" }}
- >
- <span style={{ marginLeft: "5%" }}>{remainedManhour}</span>
- </div>
- </div>
- <hr />
- <div>
- <div
- className="mt-2 text-lg font-medium"
- style={{ color: "#898d8d" }}
- >
- <span style={{ marginLeft: "5%" }}>Last Update</span>
- </div>
- <div
- className="mt-2 mb-5 text-2xl font-extrabold"
- style={{ color: "#6b87cf" }}
- >
- <span style={{ marginLeft: "5%" }}>{lastUpdate}</span>
- </div>
- </div>
- </Card>
- </Grid>
- </div>
- </Grid>
- );
- };
-
- export default ProgressByClient;
|