diff --git a/app/src/components/layout/sidebarRight/analysis/Analysis.tsx b/app/src/components/layout/sidebarRight/analysis/Analysis.tsx index 0e88e18..1ad18a0 100644 --- a/app/src/components/layout/sidebarRight/analysis/Analysis.tsx +++ b/app/src/components/layout/sidebarRight/analysis/Analysis.tsx @@ -14,9 +14,9 @@ const Analysis: React.FC = () => { const AnalysisPresets: AnalysisPresetsType = { "Throughput time": [ - { type: "default", inputs: { label: "Cycle time", activeOption: "s" } }, - { type: "default", inputs: { label: "machines / lines", activeOption: "item" } }, - { type: "default", inputs: { label: "Machine uptime", activeOption: "%" } }, + // { type: "default", inputs: { label: "Cycle time", activeOption: "s" } }, + // { type: "default", inputs: { label: "machines / lines", activeOption: "item" } }, + // { type: "default", inputs: { label: "Machine uptime", activeOption: "%" } }, ], "Production capacity": [ { type: "default", inputs: { label: "Shift length", activeOption: "hr" } }, diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/BarChartInput.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/BarChartInput.tsx index b0b328d..4e2ff22 100644 --- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/BarChartInput.tsx +++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/BarChartInput.tsx @@ -8,6 +8,7 @@ import { useWidgetStore } from "../../../../../store/useWidgetStore"; import axios from "axios"; import RenameInput from "../../../../ui/inputs/RenameInput"; import { useParams } from "react-router-dom"; +import { useSocketStore } from "../../../../../store/builder/store"; type Props = {}; @@ -26,6 +27,7 @@ const BarChartInput = (props: Props) => { const organization = email?.split("@")[1]?.split(".")[0]; const [isLoading, setLoading] = useState(true); const { projectId } = useParams(); + const { visualizationSocket } = useSocketStore(); useEffect(() => { @@ -92,6 +94,25 @@ const BarChartInput = (props: Props) => { inputDuration: any, inputName: any ) => { + // const userId = localStorage.getItem("userId"); + // let newWidget = { + // id: selectedChartId.id, + // panel: selectedChartId.panel, + // widgetName: inputName, + // Data: { + // measurements: inputMeasurement, + // duration: inputDuration, + // } + // } + // const adding3dWidget = { + // organization: organization, + // widget: newWidget, + // zoneUuid: selectedZone.zoneUuid, + // projectId, userId + // }; + // if (visualizationSocket) { + // visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget); + // } try { const response = await axios.post( `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`, diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/LineGrapInput.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/LineGrapInput.tsx index 912b7d1..be67fcd 100644 --- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/LineGrapInput.tsx +++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/LineGrapInput.tsx @@ -124,6 +124,7 @@ import { useWidgetStore } from "../../../../../store/useWidgetStore"; import axios from "axios"; import RenameInput from "../../../../ui/inputs/RenameInput"; import { useParams } from "react-router-dom"; +import { useSocketStore } from "../../../../../store/builder/store"; type Props = {}; @@ -142,6 +143,7 @@ const LineGrapInput = (props: Props) => { const organization = email?.split("@")[1]?.split(".")[0]; const [isLoading, setLoading] = useState(true); const { projectId } = useParams(); + const { visualizationSocket } = useSocketStore(); useEffect(() => { const fetchZoneData = async () => { @@ -207,6 +209,25 @@ const LineGrapInput = (props: Props) => { inputDuration: any, inputName: any ) => { + // const userId = localStorage.getItem("userId"); + // let newWidget = { + // id: selectedChartId.id, + // panel: selectedChartId.panel, + // widgetName: inputName, + // Data: { + // measurements: inputMeasurement, + // duration: inputDuration, + // } + // } + // const adding3dWidget = { + // organization: organization, + // widget: newWidget, + // zoneUuid: selectedZone.zoneUuid, + // projectId, userId + // }; + // if (visualizationSocket) { + // visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget); + // } try { const response = await axios.post( `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`, diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/PieChartInput.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/PieChartInput.tsx index 8136c70..875baa2 100644 --- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/PieChartInput.tsx +++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/PieChartInput.tsx @@ -8,6 +8,7 @@ import { useWidgetStore } from "../../../../../store/useWidgetStore"; import axios from "axios"; import RenameInput from "../../../../ui/inputs/RenameInput"; import { useParams } from "react-router-dom"; +import { useSocketStore } from "../../../../../store/builder/store"; type Props = {}; @@ -26,6 +27,7 @@ const PieChartInput = (props: Props) => { const organization = email?.split("@")[1]?.split(".")[0]; const [isLoading, setLoading] = useState(true); const { projectId } = useParams(); + const { visualizationSocket } = useSocketStore(); useEffect(() => { @@ -92,6 +94,26 @@ const PieChartInput = (props: Props) => { inputDuration: any, inputName: any ) => { + + // const userId = localStorage.getItem("userId"); + // let newWidget = { + // id: selectedChartId.id, + // panel: selectedChartId.panel, + // widgetName: inputName, + // Data: { + // measurements: inputMeasurement, + // duration: inputDuration, + // }, + // } + // const adding3dWidget = { + // organization: organization, + // widget: newWidget, + // zoneUuid: selectedZone.zoneUuid, + // projectId, userId + // }; + // if (visualizationSocket) { + // visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget); + // } try { const response = await axios.post( `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`, diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress1Input.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress1Input.tsx index 8647df7..1f4832e 100644 --- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress1Input.tsx +++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress1Input.tsx @@ -8,6 +8,7 @@ import { useWidgetStore } from "../../../../../store/useWidgetStore"; import axios from "axios"; import RenameInput from "../../../../ui/inputs/RenameInput"; import { useParams } from "react-router-dom"; +import { useSocketStore } from "../../../../../store/builder/store"; type Props = {}; @@ -26,6 +27,7 @@ const Progress1Input = (props: Props) => { const organization = email?.split("@")[1]?.split(".")[0]; const [isLoading, setLoading] = useState(true); const { projectId } = useParams(); + const { visualizationSocket } = useSocketStore(); useEffect(() => { @@ -92,6 +94,25 @@ const Progress1Input = (props: Props) => { inputDuration: any, inputName: any ) => { + // const userId = localStorage.getItem("userId"); + // let newWidget = { + // id: selectedChartId.id, + // panel: selectedChartId.panel, + // widgetName: inputName, + // Data: { + // measurements: inputMeasurement, + // duration: inputDuration, + // }, + // } + // const adding3dWidget = { + // organization: organization, + // widget: newWidget, + // zoneUuid: selectedZone.zoneUuid, + // projectId, userId + // }; + // if (visualizationSocket) { + // visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget); + // } try { const response = await axios.post( `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`, diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress2Input.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress2Input.tsx index 8765751..06a4282 100644 --- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress2Input.tsx +++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Progress2Input.tsx @@ -8,6 +8,7 @@ import { useWidgetStore } from "../../../../../store/useWidgetStore"; import axios from "axios"; import RenameInput from "../../../../ui/inputs/RenameInput"; import { useParams } from "react-router-dom"; +import { useSocketStore } from "../../../../../store/builder/store"; type Props = {}; @@ -26,6 +27,7 @@ const Progress2Input = (props: Props) => { const organization = email?.split("@")[1]?.split(".")[0]; const [isLoading, setLoading] = useState(true); const { projectId } = useParams(); + const { visualizationSocket } = useSocketStore(); useEffect(() => { @@ -92,6 +94,25 @@ const Progress2Input = (props: Props) => { inputDuration: any, inputName: any ) => { + // const userId = localStorage.getItem("userId"); + // let newWidget = { + // id: selectedChartId.id, + // panel: selectedChartId.panel, + // widgetName: inputName, + // Data: { + // measurements: inputMeasurement, + // duration: inputDuration, + // } + // } + // const adding3dWidget = { + // organization: organization, + // widget: newWidget, + // zoneUuid: selectedZone.zoneUuid, + // projectId, userId + // }; + // if (visualizationSocket) { + // visualizationSocket.emit("v1:viz-3D-widget:add", adding3dWidget); + // } try { const response = await axios.post( `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/V1/widget/save`, diff --git a/app/src/components/ui/analysis/ProductionCapacity.tsx b/app/src/components/ui/analysis/ProductionCapacity.tsx index 0bc8b91..7c2e883 100644 --- a/app/src/components/ui/analysis/ProductionCapacity.tsx +++ b/app/src/components/ui/analysis/ProductionCapacity.tsx @@ -91,7 +91,8 @@ const ThroughputSummary: React.FC = () => { const [isLoading, setIsLoading] = useState(true); useEffect(() => { - if (productionCapacityData >= 0) { + // console.log('productionCapacityData > 0: ', productionCapacityData > 0); + if (productionCapacityData > 0) { setIsLoading(false); console.log("productionCapacityData: ", productionCapacityData); } else { @@ -100,91 +101,93 @@ const ThroughputSummary: React.FC = () => { }, [productionCapacityData]); return ( -
-
-
-
-
Production Capacity
-
- {timeRange.startTime} - {timeRange.endTime} + <> + {!isLoading &&
+
+
+
+
Production Capacity
+
+ {timeRange.startTime} - {timeRange.endTime} +
+
+
+
-
- -
-
- {!isLoading ? ( - <> -
-
- {productionCapacityData}{" "} - Units/hour -
-
-
-
Asset usage
-
{parseFloat(inputValues["Yield rate"])}%
+ {!isLoading ? ( + <> +
+
+ {productionCapacityData}{" "} + Units/hour
- -
-
- -
-
-
Energy Consumption
-
-
- +
+
+
Asset usage
+
{parseFloat(inputValues["Yield rate"])}%
-
-
- {energyConsumption.energyConsumed} + +
+
+ +
+
+
Energy Consumption
+
+
+
-
{energyConsumption.unit}
-
-
-
-
-
Shift Utilization
-
-
{throughputData.assetUsage}%
- -
- {/* Dynamically create progress bars based on shiftUtilization array */} - {shiftUtilization.map((shift, index) => ( -
- ))} -
- -
- {/* Dynamically create shift indicators with random colors */} - {shiftUtilization.map((shift, index) => ( -
- - +
+
+ {energyConsumption.energyConsumed}
- ))} +
{energyConsumption.unit}
+
+
+
+
+
Shift Utilization
+
+
{throughputData.assetUsage}%
+ +
+ {/* Dynamically create progress bars based on shiftUtilization array */} + {shiftUtilization.map((shift, index) => ( +
+ ))} +
+ +
+ {/* Dynamically create shift indicators with random colors */} + {shiftUtilization.map((shift, index) => ( +
+ + +
+ ))} +
-
- - ) : ( - - )} -
-
+ + ) : ( + + )} +
+
} + ); }; diff --git a/app/src/components/ui/analysis/ROISummary.tsx b/app/src/components/ui/analysis/ROISummary.tsx index dc33663..a03b15c 100644 --- a/app/src/components/ui/analysis/ROISummary.tsx +++ b/app/src/components/ui/analysis/ROISummary.tsx @@ -83,136 +83,142 @@ const ROISummary = ({ const [isLoading, setIsLoading] = useState(false); const { roiSummary } = useROISummaryData(); + useEffect(() => { - if (roiSummary && typeof roiSummary === "object") { - setIsLoading(false); // Data loaded + if (roiSummary.productName) { + // If productName is set, assume data is loaded + setIsLoading(false); } else { - setIsLoading(true); // Show skeleton while loading + // If productName is empty, assume still loading + setIsLoading(true); } }, [roiSummary]); return ( -
-
-
-
-
ROI Summary
-
From {getCurrentDate()}
-
-
- -
-
- {!isLoading ? ( - <> -
- -
Product :
-
{roiSummary.productName}
-
-
- -
-
- {roiSummary.roiPercentage}% ROI with payback - in just {roiSummary.paybackPeriod} months + <> + + { + !isLoading &&
+
+
+
+
ROI Summary
+
From {getCurrentDate()}
+
+
+
-
-
- -
- you're on track to hit it by -
July 2029
+ {!isLoading ? ( + <> +
+ +
Product :
+
{roiSummary.productName}
-
-
-
-
- Total Cost Incurred - - - {roiSummary.totalCost} +
+ +
+
+ {roiSummary.roiPercentage}% ROI with payback + in just {roiSummary.paybackPeriod} months +
+
+
+
+ +
+ you're on track to hit it by +
July 2029
+
+
+
+
+
+ Total Cost Incurred + + + {roiSummary.totalCost} + +
+
+ Revenue Generated + + + + {roiSummary.revenueGenerated} + +
+
+
0 ? "profit" : "loss"}`} + > +
+ + Net Profit +
+
+ + {roiSummary.netProfit > 0 + ? roiSummary.netProfit + : roiSummary.netLoss} +
+
+
+
+
+
+
+ + Cost Breakdown +
+ + +
-
- Revenue Generated - - - - {roiSummary.revenueGenerated} - +
+ + + + + + + + + + + + {roiSummaryData.costBreakdown.map((row, index) => ( + + + + + + + + ))} + +
ItemUnit CostLabor CostTotal CostSelling Price
{row.item}{row.unitCost}{row.laborCost}{row.totalCost}{row.sellingPrice}
-
0 ? "profit" : "loss"}`} - > -
- - Net Profit -
-
- - {roiSummary.netProfit > 0 - ? roiSummary.netProfit - : roiSummary.netLoss} -
-
-
-
-
-
-
- - Cost Breakdown -
- - - - -
-
- - - - - - - - - - - - {roiSummaryData.costBreakdown.map((row, index) => ( - - - - - - - - ))} - -
ItemUnit CostLabor CostTotal CostSelling Price
{row.item}{row.unitCost}{row.laborCost}{row.totalCost}{row.sellingPrice}
-
-
- {/*
+ {/*
@@ -232,13 +238,14 @@ const ROISummary = ({
Get ROI Boost Tips
*/} - - ) : ( - - //
No Data
- )} -
-
+ + ) : ( + + //
No Data
+ )} +
+
} + ); }; diff --git a/app/src/components/ui/analysis/ThroughputSummary.tsx b/app/src/components/ui/analysis/ThroughputSummary.tsx index bf570f9..a01ac61 100644 --- a/app/src/components/ui/analysis/ThroughputSummary.tsx +++ b/app/src/components/ui/analysis/ThroughputSummary.tsx @@ -30,72 +30,79 @@ const ProductionCapacity = ({ const [isLoading, setIsLoading] = useState(false); useEffect(() => { - if (throughputData >= 0) { + console.log('typeof throughputData:', typeof throughputData); + console.log('throughputData > 0: ', throughputData > 0); + if (throughputData > 0) { // console.log('machineActiveTime: ', machineActiveTime); // console.log('materialCycleTime: ', materialCycleTime); // console.log('throughputData: ', throughputData); // console.log('productionCapacityData: ', productionCapacityData); + setIsLoading(false); + } else { setIsLoading(true); } }, [throughputData]) return ( -
-
-
-
-
Throughput Summary
-
- {timeRange.startTime} - {timeRange.endTime} + <> + + {!isLoading &&
+
+
+
+
Throughput Summary
+
+ {timeRange.startTime} - {timeRange.endTime} +
+
+
+
-
- -
+ {isLoading ? ( + <> +
+
+ {throughputData} Units/hour + +
+ + {/* Dynamic Progress Bar */} +
+ {[...Array(totalBars)].map((_, i) => ( +
+ {i < barsToFill ? ( +
+ ) : i === barsToFill ? ( +
+ ) : null} +
+ ))} +
+
+ +
+
+ Avg. Process Time + {materialCycleTime} secs/unit +
+
+ Machine Utilization + {machineActiveTime} + {/* {machineActiveTime} */} +
+
+ + ) : ( + + )}
- {isLoading ? ( - <> -
-
- {throughputData} Units/hour - -
- - {/* Dynamic Progress Bar */} -
- {[...Array(totalBars)].map((_, i) => ( -
- {i < barsToFill ? ( -
- ) : i === barsToFill ? ( -
- ) : null} -
- ))} -
-
- -
-
- Avg. Process Time - {materialCycleTime} secs/unit -
-
- Machine Utilization - {machineActiveTime} - {/* {machineActiveTime} */} -
-
- - ) : ( - - )} -
-
+
} + ); }; diff --git a/app/src/components/ui/simulation/simulationPlayer.tsx b/app/src/components/ui/simulation/simulationPlayer.tsx index e2f1c9d..1002a9b 100644 --- a/app/src/components/ui/simulation/simulationPlayer.tsx +++ b/app/src/components/ui/simulation/simulationPlayer.tsx @@ -165,7 +165,7 @@ const SimulationPlayer: React.FC = () => {
-
Hourly Simulation
+
ThroughPut Data
- ): boolean { + function isPointInPolygon(point: [number, number], polygon: Array<[number, number]>): boolean { const [x, z] = point; let inside = false; @@ -434,8 +431,6 @@ export default function Dropped3dWidgets() { } } }; - - const handleMouseMove = (event: MouseEvent) => { if (!rightClickSelected || !rightSelect) return; const selectedzoneUuid = Object.keys(zoneWidgetData).find(