diff --git a/app/src/components/ui/analysis/ProductionCapacity.tsx b/app/src/components/ui/analysis/ProductionCapacity.tsx index ab64229..3e6fe03 100644 --- a/app/src/components/ui/analysis/ProductionCapacity.tsx +++ b/app/src/components/ui/analysis/ProductionCapacity.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { Line } from "react-chartjs-2"; import { Chart as ChartJS, @@ -9,11 +9,11 @@ import { } from "chart.js"; import { PowerIcon, ProductionCapacityIcon } from "../../icons/analysis"; import SkeletonUI from "../../templates/SkeletonUI"; -import { useMachineUptime } from "../../../store/builder/store"; +import { useMachineUptime, useProductionCapacityData } from "../../../store/builder/store"; ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement); -const ThroughputSummary:React.FC = () => { +const ThroughputSummary: React.FC = () => { // Define all data internally within the component const timeRange = { startTime: "08:00 AM", @@ -33,6 +33,7 @@ const ThroughputSummary:React.FC = () => { { shift: 3, percentage: 30, color: "#7981F5" }, ]; + const { productionCapacityData } = useProductionCapacityData() const chartOptions = { @@ -85,7 +86,16 @@ const ThroughputSummary:React.FC = () => { }, ], }; - const isLoading = false; + + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + if (productionCapacityData >= 0) { + setIsLoading(true); + console.log('productionCapacityData: ', productionCapacityData); + } + + }, [productionCapacityData]) return (
@@ -106,7 +116,7 @@ const ThroughputSummary:React.FC = () => { <>
- {throughputData.totalThroughput}{" "} + {productionCapacityData}{" "} Units/hour
diff --git a/app/src/components/ui/analysis/ROISummary.tsx b/app/src/components/ui/analysis/ROISummary.tsx index e0edb74..da9d496 100644 --- a/app/src/components/ui/analysis/ROISummary.tsx +++ b/app/src/components/ui/analysis/ROISummary.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { CostBreakDownIcon, LightBulpIcon, @@ -9,6 +9,8 @@ import { import SemiCircleProgress from "./SemiCircleProgress"; import { ArrowIcon } from "../../icons/ExportCommonIcons"; import SkeletonUI from "../../templates/SkeletonUI"; +import { useROISummaryData } from "../../../store/builder/store"; +import { set } from "immer/dist/internal"; const ROISummary = ({ roiSummaryData = { @@ -79,8 +81,21 @@ const ROISummary = ({ const year = now.getFullYear(); return `${day} ${month}, ${year}`; } + const [isLoading, setIsLoading] = useState(false); + const { roiSummary } = useROISummaryData(); + + useEffect(() => { + if (roiSummary && typeof roiSummary === 'object') { + + console.log('roiSummary: ', roiSummary); + setIsLoading(true) + } + + }, [roiSummary]) + + + - const isLoading = false; return (
@@ -104,8 +119,8 @@ const ROISummary = ({
- +{roiSummaryData.roiPercentage}% ROI with payback - in just {roiSummaryData.paybackPeriod} months + +{roiSummary.roiPercentage}% ROI with payback + in just {roiSummary.paybackPeriod} months
@@ -122,7 +137,7 @@ const ROISummary = ({ Total Cost Incurred - {roiSummaryData.totalCost} + {roiSummary.totalCost}
@@ -130,14 +145,13 @@ const ROISummary = ({ - {roiSummaryData.revenueGenerated} + {roiSummary.revenueGenerated}
@@ -145,9 +159,9 @@ const ROISummary = ({
- {roiSummaryData.netProfit - ? roiSummaryData.netProfit - : roiSummaryData.netLoss} + {roiSummary.netProfit + ? roiSummary.netProfit + : roiSummary.netLoss}
@@ -164,9 +178,8 @@ const ROISummary = ({
{row.item} diff --git a/app/src/components/ui/analysis/ThroughputSummary.tsx b/app/src/components/ui/analysis/ThroughputSummary.tsx index 3665837..e87027b 100644 --- a/app/src/components/ui/analysis/ThroughputSummary.tsx +++ b/app/src/components/ui/analysis/ThroughputSummary.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { useMachineCount, useMachineUptime, useMaterialCycle, useThroughPutData } from "../../../store/builder/store"; +import { useMachineCount, useMachineUptime, useMaterialCycle, useProductionCapacityData, useThroughPutData } from "../../../store/builder/store"; import { ThroughputSummaryIcon, } from "../../icons/analysis"; @@ -17,23 +17,25 @@ const ProductionCapacity = ({ const { machineActiveTime } = useMachineUptime(); const { materialCycleTime } = useMaterialCycle(); const { throughputData } = useThroughPutData() - - - const progressPercent = machineActiveTime; - - - const totalBars = 6; - const barsToFill = Math.floor((progressPercent / 100) * totalBars); - const partialFillPercent = - ((progressPercent / 100) * totalBars - barsToFill) * 100; - - const [isLoading, setIsLoading] = useState(false); - - useEffect(() => { - if (throughputData > 0) { - console.log('machineActiveTime: ', machineActiveTime); - console.log('materialCycleTime: ', materialCycleTime); - console.log('throughputData: ', throughputData); + const { productionCapacityData } = useProductionCapacityData() + + const progressPercent = machineActiveTime; + + + const totalBars = 6; + const barsToFill = Math.floor((progressPercent / 100) * totalBars); + const partialFillPercent = + ((progressPercent / 100) * totalBars - barsToFill) * 100; + + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + if (throughputData >= 0) { + console.log('machineActiveTime: ', machineActiveTime); + console.log('materialCycleTime: ', materialCycleTime); + console.log('throughputData: ', throughputData); + console.log('productionCapacityData: ', productionCapacityData); + setIsLoading(true); } @@ -59,6 +61,7 @@ const ProductionCapacity = ({
{throughputData} Units/hour +
{/* Dynamic Progress Bar */} diff --git a/app/src/modules/simulation/analysis/ROI/roiData.tsx b/app/src/modules/simulation/analysis/ROI/roiData.tsx index f23ceb5..e2d854c 100644 --- a/app/src/modules/simulation/analysis/ROI/roiData.tsx +++ b/app/src/modules/simulation/analysis/ROI/roiData.tsx @@ -1,10 +1,12 @@ -import React, { useEffect } from 'react' -import { useInputValues, useProductionCapacityData } from '../../../../store/builder/store'; +import React, { useEffect, useState } from 'react' +import { useInputValues, useProductionCapacityData, useROISummaryData } from '../../../../store/builder/store'; export default function ROIData() { const { inputValues } = useInputValues(); const { productionCapacityData } = useProductionCapacityData() + + const { setRoiSummaryData } = useROISummaryData(); useEffect(() => { if (inputValues === undefined) return; @@ -53,6 +55,7 @@ export default function ROIData() { let TotalAnnualCost = MaterialCost + LaborCost + EnergyCost + MaintenceCost; console.log('TotalAnnualCost: ', TotalAnnualCost); + //Profit for Year let ProfitforYear = RevenueForYear - TotalAnnualCost; console.log('ProfitforYear: ', ProfitforYear); @@ -70,7 +73,16 @@ export default function ROIData() { // Payback Period const paybackPeriod = initialInvestment / ProfitforYear; console.log('paybackPeriod: ', paybackPeriod); + + setRoiSummaryData({ + roiPercentage: ROIData, + paybackPeriod, + totalCost: TotalAnnualCost, + revenueGenerated: RevenueForYear, + netProfit: NetProfit > 0 ? NetProfit : 0, + netLoss: NetProfit < 0 ? -NetProfit : 0 + }); } diff --git a/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx b/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx index b860bb1..77e68ff 100644 --- a/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx +++ b/app/src/modules/simulation/analysis/productionCapacity/productionCapacityData.tsx @@ -19,7 +19,7 @@ export default function ProductionCapacityData() { // console.log('yieldRate: ', yieldRate); - if (!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) && !isNaN(yieldRate) && throughputData > 0) { + if (!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) && !isNaN(yieldRate) && throughputData >= 0) { //Daily Output const dailyProduction = throughputData * shiftLength * shiftsPerDay; console.log("DailyProduction: ", dailyProduction.toFixed(2)); diff --git a/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx b/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx index 8d7d676..899dca9 100644 --- a/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx +++ b/app/src/modules/simulation/analysis/throughPut/throughPutData.tsx @@ -19,7 +19,7 @@ export default function ThroughPutData() { const { machines } = useMachineStore(); const { conveyors } = useConveyorStore(); const { storageUnits } = useStorageUnitStore(); - const { materials } = useMaterialStore(); + const { materialHistory } = useMaterialStore(); const { machineCount, setMachineCount } = useMachineCount(); const { machineActiveTime, setMachineActiveTime } = useMachineUptime(); @@ -33,20 +33,14 @@ export default function ThroughPutData() { // Setting machine count useEffect(() => { if (materialCycleTime < 0) return - // console.log('materialCycleTime: ', materialCycleTime); const fetchProductSequenceData = async () => { const productData = getProductById(selectedProduct.productId); if (productData) { - const productSequenceData = await determineExecutionMachineSequences([productData]); - // console.log('productSequenceData: ', productSequenceData); - + const productSequenceData = await determineExecutionMachineSequences([productData]) if (productSequenceData?.length > 0) { let totalItems = 0; let totalActiveTime = 0; - productSequenceData.forEach((sequence) => { - // console.log('sequence: ', sequence); - sequence.forEach((item) => { if (item.type === "roboticArm") { armBots.filter(arm => arm.modelUuid === item.modelUuid) @@ -62,7 +56,7 @@ export default function ThroughPutData() { if (vehicle.activeTime >= 0) { // totalActiveTime += vehicle.activeTime; - // totalActiveTime += 10; + totalActiveTime += 34; } }); } else if (item.type === "machine") { @@ -70,7 +64,7 @@ export default function ThroughPutData() { .forEach(machine => { if (machine.activeTime >= 0) { // totalActiveTime += machine.activeTime; - // totalActiveTime += 12; + totalActiveTime += 12; } }); } else if (item.type === "transfer") { @@ -78,7 +72,7 @@ export default function ThroughPutData() { .forEach(conveyor => { if (conveyor.activeTime >= 0) { // totalActiveTime += conveyor.activeTime; - // totalActiveTime += 7; + totalActiveTime += 89; } }); } else if (item.type === "storageUnit") { @@ -86,12 +80,11 @@ export default function ThroughPutData() { .forEach(storage => { if (storage.activeTime >= 0) { // totalActiveTime += storage.activeTime; - // totalActiveTime += 9; + totalActiveTime += 45; } }); } }); - totalItems += sequence.length; }); @@ -107,16 +100,17 @@ export default function ThroughPutData() { // Setting material cycle time useEffect(() => { - materials.map((material) => { - // console.log('material: ', material); - // const totalCycleTime = material.endTime - material.startTime;//dynamic - const staticStartTime = 50; - const staticEndTime = 100; - const totalCycleTime = staticEndTime - staticStartTime; - setMaterialCycleTime(totalCycleTime) + materialHistory.forEach((material) => { + const start = material.material.startTime ?? 0; + const end = material.material.endTime ?? 0; + + if (start === 0 || end === 0) return; + + const totalCycleTime = end - start; + setMaterialCycleTime(totalCycleTime.toFixed(2)); // Set the material cycle time in the store + }); + }, [materialHistory]); - }) - }, [materials]); useEffect(() => { @@ -125,12 +119,12 @@ export default function ThroughPutData() { const throughput = (3600 / materialCycleTime) * machineCount * (avgProcessTime / 100); // ✅ division by 100 setThroughputData(throughput.toFixed(2)); // Set the throughput data in the store - // console.log('---Throughput Results---'); - // console.log('Total Active Time:', machineActiveTime); - // console.log('Material Cycle Time:', materialCycleTime); - // console.log('Machine Count:', machineCount); - // console.log('Average Process Time (%):', avgProcessTime); - // console.log('Calculated Throughput:', throughput); + console.log('---Throughput Results---'); + console.log('Total Active Time:', machineActiveTime); + console.log('Material Cycle Time:', materialCycleTime); + console.log('Machine Count:', machineCount); + console.log('Average Process Time (%):', avgProcessTime); + console.log('Calculated Throughput:', throughput); } }, [machineActiveTime, materialCycleTime, machineCount]); @@ -141,68 +135,3 @@ export default function ThroughPutData() { ); } - - - - // useEffect(() => { - // if (!isPlaying) return; - - // const intervalMs = 1000 - - // if (!armBot.isActive && armBot.state == "idle" && (currentPhase == "rest" || currentPhase == "init") && !isIdleRef.current) { - // isIdleRef.current = true - - // // Stop the timer - // // 🚨 1. Clear Active Timer - // if (activeTimerId.current) { - // clearInterval(activeTimerId.current); - // activeTimerId.current = null; - // } - // incrementActiveTime(armBot.modelUuid, activeSecondsElapsed.current) - // console.log(`✅ Active Cycle completed in ${activeSecondsElapsed.current} seconds`); - - // // 🚨 2. Reset active timer seconds after logging - // // activeSecondsElapsed.current = 0; - - // // 🚨 3. Start Idle Timer (clean old idle timer first) - // if (idleTimerId.current) { - // clearInterval(idleTimerId.current); - // idleTimerId.current = null; - // } - - // idleSecondsElapsed.current = 0; - // idleTimerId.current = setInterval(() => { - // if (!isPausedRef.current) { - // idleSecondsElapsed.current += 1; - // console.log(`🕒 Idle Timer: ${idleSecondsElapsed.current} seconds`); - // } - // }, intervalMs); - // } - // if (armBot.isActive && armBot.state != "idle" && currentPhase !== "rest" && armBot.currentAction && isIdleRef.current) { - // isIdleRef.current = false - - // if (armBot.currentAction) { - // // 🚨 Clear Idle Timer - // if (idleTimerId.current) { - // clearInterval(idleTimerId.current); - // idleTimerId.current = null; - // } - // incrementIdleTime(armBot.modelUuid, idleSecondsElapsed.current) - // console.log(`🕒 Idle Cycle completed in: ${idleSecondsElapsed.current} seconds`); - // idleSecondsElapsed.current = 0; - - // // 🚨 Start Active Timer - // if (activeTimerId.current) { - // clearInterval(activeTimerId.current); - // } - // // activeSecondsElapsed.current = 0; - // activeTimerId.current = setInterval(() => { - // if (!isPausedRef.current) { - // activeSecondsElapsed.current += 1 - // console.log(`🕒 Active Timer: ${activeSecondsElapsed.current} seconds`); - // } - // }, intervalMs); - // } - // } - - // }, [armBot, currentPhase, isPlaying]) \ No newline at end of file diff --git a/app/src/modules/simulation/roboticArm/instances/armInstance/roboticArmInstance.tsx b/app/src/modules/simulation/roboticArm/instances/armInstance/roboticArmInstance.tsx index 6de5f1d..4b0829e 100644 --- a/app/src/modules/simulation/roboticArm/instances/armInstance/roboticArmInstance.tsx +++ b/app/src/modules/simulation/roboticArm/instances/armInstance/roboticArmInstance.tsx @@ -234,7 +234,7 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) { cancelAnimationFrame(animationFrameIdRef.current!); animationFrameIdRef.current = null; const roundedActiveTime = Math.round(activeSecondsElapsed.current); // Get the final rounded active time - console.log('Final Active Time:', roundedActiveTime, 'seconds'); + // console.log('🚨Final Active Time:',armBot.modelUuid, roundedActiveTime, 'seconds'); incrementActiveTime(armBot.modelUuid, roundedActiveTime); activeSecondsElapsed.current = 0; @@ -242,7 +242,7 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) { cancelAnimationFrame(animationFrameIdRef.current!); animationFrameIdRef.current = null; const roundedIdleTime = Math.round(idleSecondsElapsed.current); // Get the final rounded idle time - console.log('Final Idle Time:', roundedIdleTime, 'seconds'); + // console.log('🕒 Final Idle Time:', armBot.modelUuid,roundedIdleTime, 'seconds'); incrementIdleTime(armBot.modelUuid, roundedIdleTime); idleSecondsElapsed.current = 0; @@ -260,10 +260,6 @@ function RoboticArmInstance({ armBot }: { armBot: ArmBotStatus }) { }, [armBot.isActive, armBot.state, currentPhase]) - useEffect(() => { - - console.log('armBots: ', armBots); - }, [armBots]) useEffect(() => { const targetMesh = scene?.getObjectByProperty("uuid", armBot.modelUuid); diff --git a/app/src/store/builder/store.ts b/app/src/store/builder/store.ts index b4534b5..7c72855 100644 --- a/app/src/store/builder/store.ts +++ b/app/src/store/builder/store.ts @@ -492,4 +492,30 @@ export const useInputValues = create((set) => ({ [label]: value, }, })), +})); + +export interface ROISummaryData { + roiPercentage: number; + paybackPeriod: number; + totalCost: number; + revenueGenerated: number; + netProfit: number; + netLoss: number; +} + +interface ROISummaryStore { + roiSummary: ROISummaryData; + setRoiSummaryData: (values: ROISummaryData) => void; +} + +export const useROISummaryData = create((set) => ({ + roiSummary: { + roiPercentage: 0, + paybackPeriod: 0, + totalCost: 0, + revenueGenerated: 0, + netProfit: 0, + netLoss: 0, + }, + setRoiSummaryData: (values) => set({ roiSummary: values }), })); \ No newline at end of file