Display completion percentage for each Work Area header #174
79
src/components/Charts/ProgressDonutChart.jsx
Normal file
79
src/components/Charts/ProgressDonutChart.jsx
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import React from "react";
|
||||||
|
import ReactApexChart from "react-apexcharts";
|
||||||
|
|
||||||
|
const ProgressDonutChart = ({ completed = 0, planned = 1 }) => {
|
||||||
|
const percentage = planned > 0 ? Math.round((completed / planned) * 100) : 0;
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
chart: {
|
||||||
|
height: 10,
|
||||||
|
type: "radialBar",
|
||||||
|
toolbar: { show: false },
|
||||||
|
},
|
||||||
|
plotOptions: {
|
||||||
|
radialBar: {
|
||||||
|
startAngle: 0,
|
||||||
|
endAngle: 360,
|
||||||
|
hollow: {
|
||||||
|
margin: 0,
|
||||||
|
size: "10%",
|
||||||
|
background: "#fff",
|
||||||
|
dropShadow: {
|
||||||
|
enabled: true,
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
blur: 3,
|
||||||
|
opacity: 0.45,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
track: {
|
||||||
|
background: "#f5f5f5",
|
||||||
|
strokeWidth: "10%",
|
||||||
|
dropShadow: { enabled: false },
|
||||||
|
},
|
||||||
|
dataLabels: {
|
||||||
|
show: true,
|
||||||
|
name: {
|
||||||
|
offsetY: -10,
|
||||||
|
color: "#888",
|
||||||
|
fontSize: "14px",
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
formatter: (val) => `${val}%`,
|
||||||
|
color: "#111",
|
||||||
|
fontSize: "11px",
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fill: {
|
||||||
|
type: "gradient",
|
||||||
|
gradient: {
|
||||||
|
shade: "dark",
|
||||||
|
type: "horizontal",
|
||||||
|
shadeIntensity: 0.5,
|
||||||
|
gradientToColors: ["#ABE5A1"],
|
||||||
|
opacityFrom: 1,
|
||||||
|
opacityTo: 1,
|
||||||
|
stops: [0, 100],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
lineCap: "round",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div id="chart">
|
||||||
|
<ReactApexChart
|
||||||
|
options={options}
|
||||||
|
series={[percentage]}
|
||||||
|
type="radialBar"
|
||||||
|
height={100}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProgressDonutChart;
|
@ -13,10 +13,10 @@ const Floor = ({ floor, workAreas, forBuilding }) => {
|
|||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="4" className="text-start table-cell">
|
<td colSpan="4" className="text-start table-cell">
|
||||||
<div className="row ps-2">
|
<div className="row ps-2">
|
||||||
{/* <div className="col-1 col-md-1 d-flex justify-content-between align-items-center " >
|
{/* <div className="col-1 col-md-1 d-flex justify-content-between align-items-center " >
|
||||||
<button
|
<button
|
||||||
className="btn me-2"
|
className="btn me-2"
|
||||||
>
|
>
|
||||||
@ -25,7 +25,7 @@ const Floor = ({ floor, workAreas, forBuilding }) => {
|
|||||||
</div> */}
|
</div> */}
|
||||||
<div className="col-12 ps-8">
|
<div className="col-12 ps-8">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col">
|
<div className="d-flex col-5">
|
||||||
{" "}
|
{" "}
|
||||||
<span className="fw-semibold text-primary">
|
<span className="fw-semibold text-primary">
|
||||||
Floor:
|
Floor:
|
||||||
@ -34,6 +34,13 @@ const Floor = ({ floor, workAreas, forBuilding }) => {
|
|||||||
{floor.floorName}
|
{floor.floorName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-start col-5">
|
||||||
|
{" "}
|
||||||
|
<span className="fw-semibold text-primary">
|
||||||
|
Work Area:
|
||||||
|
</span>{" "}
|
||||||
|
<span className="fw-normal text-danger">Not Available</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,7 +68,6 @@ const InfraTable = ({ buildings }) => {
|
|||||||
showToast("Failed to save floor", "error");
|
showToast("Failed to save floor", "error");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
||||||
showToast("Error occurred while saving floor", "error");
|
showToast("Error occurred while saving floor", "error");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -95,14 +94,14 @@ const InfraTable = ({ buildings }) => {
|
|||||||
No floors have been added yet. Start by adding floors to manage
|
No floors have been added yet. Start by adding floors to manage
|
||||||
this building.
|
this building.
|
||||||
</p>
|
</p>
|
||||||
<button
|
{/* <button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-xs btn-primary"
|
className="btn btn-xs btn-primary"
|
||||||
onClick={() => handleAddFloor(building)}
|
onClick={() => handleAddFloor(building)}
|
||||||
>
|
>
|
||||||
<i className="bx bx-plus-circle me-2"></i>
|
<i className="bx bx-plus-circle me-2"></i>
|
||||||
Add Floors
|
Add Floors
|
||||||
</button>
|
</button> */}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -13,6 +13,9 @@ import {
|
|||||||
MANAGE_TASK,
|
MANAGE_TASK,
|
||||||
} from "../../../utils/constants";
|
} from "../../../utils/constants";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
import ProgressDonutChart from "../../Charts/ProgressDonutChart";
|
||||||
|
import ProgressBar from "../../common/ProgressBar";
|
||||||
|
import { componentsToColor } from "pdf-lib";
|
||||||
|
|
||||||
const WorkArea = ({ workArea, floor, forBuilding }) => {
|
const WorkArea = ({ workArea, floor, forBuilding }) => {
|
||||||
const [workItems, setWorkItems] = useState([]);
|
const [workItems, setWorkItems] = useState([]);
|
||||||
@ -24,7 +27,10 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
|
|||||||
const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
|
const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
|
||||||
const ManageAndAssignTak = useHasUserPermission(ASSIGN_REPORT_TASK);
|
const ManageAndAssignTak = useHasUserPermission(ASSIGN_REPORT_TASK);
|
||||||
|
|
||||||
const [percentComplete, setPercentComplete] = useState(0);
|
const [workAreaStatus, setWorkAreaStatus] = useState({
|
||||||
|
completed: 0,
|
||||||
|
planned: 100,
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const totalCompleted = workItems.reduce(
|
const totalCompleted = workItems.reduce(
|
||||||
@ -37,7 +43,8 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
|
|||||||
);
|
);
|
||||||
const percent =
|
const percent =
|
||||||
totalPlanned > 0 ? (totalCompleted / totalPlanned) * 100 : 0;
|
totalPlanned > 0 ? (totalCompleted / totalPlanned) * 100 : 0;
|
||||||
setPercentComplete(Math.min(percent, 100)); // cap at 100%
|
//setPercentComplete(Math.min(percent, 100)); // cap at 100%
|
||||||
|
setWorkAreaStatus({ completed: totalCompleted, planned: totalPlanned });
|
||||||
}, [workItems]);
|
}, [workItems]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -172,26 +179,32 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
|
|||||||
}}
|
}}
|
||||||
></i>
|
></i>
|
||||||
|
|
||||||
<div className="d-flex justify-content-start gap-12">
|
<div className="d-flex justify-content-start row w-100 align-items-center">
|
||||||
<div className="d-flex">
|
<div className="d-flex col-5">
|
||||||
<span className="fw-semibold small">Floor: </span>
|
<span className="fw-semibold text-primary small">
|
||||||
<span className="fw-normal text-darkgreen small">
|
Floor:
|
||||||
|
</span>
|
||||||
|
<span className="fw-normal text-darkgreen small px-2">
|
||||||
{floor.floorName}
|
{floor.floorName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-start ">
|
<div className="text-start col-5">
|
||||||
<span className="fw-semibold text-primary small">
|
<span className="fw-semibold text-primary small">
|
||||||
Work Area:
|
Work Area:
|
||||||
</span>
|
</span>
|
||||||
<span className="fw-normal text-darkgreen small">
|
<span className="fw-normal text-darkgreen small px-2">
|
||||||
{workArea.areaName}
|
{workArea.areaName}
|
||||||
</span>
|
</span>
|
||||||
{workArea?.workItems?.length > 0 && (
|
|
||||||
<span className="small-text px-3">
|
|
||||||
{percentComplete.toFixed(2) + "%"}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
{workArea?.workItems?.length > 0 && (
|
||||||
|
<div className="col-2">
|
||||||
|
<ProgressBar
|
||||||
|
completedWork={workAreaStatus.completed}
|
||||||
|
plannedWork={workAreaStatus.planned}
|
||||||
|
className="m-0 text-info"
|
||||||
|
></ProgressBar>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user