feat: Add default values to analysis presets and enhance input handling in components

This commit is contained in:
Gomathi 2025-06-11 16:33:21 +05:30
parent 5d03a2bc61
commit 7e85cf4e53
10 changed files with 108 additions and 63 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { AIIcon } from "../../../icons/ExportCommonIcons";
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
import { AnalysisPresetsType } from "../../../../types/analysis";
@ -19,55 +19,66 @@ const Analysis: React.FC = () => {
// { type: "default", inputs: { label: "Machine uptime", activeOption: "%" } },
],
"Production capacity": [
{ type: "range", inputs: { label: "Shift length", activeOption: "hr" } },
{ type: "default", inputs: { label: "Shifts / day", activeOption: "unit" } },
{ type: "default", inputs: { label: "Working days / year", activeOption: "days" } },
{ type: "default", inputs: { label: "Yield rate", activeOption: "%" } },
{ type: "range", inputs: { label: "Shift length", activeOption: "hr", defaultValue: 8 } },
{ type: "default", inputs: { label: "Shifts / day", activeOption: "unit", defaultValue: 2 } },
{ type: "default", inputs: { label: "Working days / year", activeOption: "days", defaultValue: 300 } },
{ type: "default", inputs: { label: "Yield rate", activeOption: "%", defaultValue: 90 } },
],
ROI: [
{
type: "default",
inputs: { label: "Selling price", activeOption: "INR" },
inputs: { label: "Selling price", activeOption: "INR", defaultValue: 1500 },
},
{
type: "default",
inputs: { label: "Material cost", activeOption: "INR" },
inputs: { label: "Material cost", activeOption: "INR", defaultValue: 300 },
},
{
type: "default",
inputs: { label: "Labor Cost", activeOption: "INR" },
inputs: { label: "Labor Cost", activeOption: "INR", defaultValue: 200 },
},
{
type: "default",
inputs: { label: "Maintenance cost", activeOption: "INR" },
inputs: { label: "Maintenance cost", activeOption: "INR", defaultValue: 1200 },
},
{
type: "default",
inputs: { label: "Electricity cost", activeOption: "INR" },
inputs: { label: "Electricity cost", activeOption: "INR", defaultValue: 1000 },
},
{
type: "default",
inputs: { label: "Fixed costs", activeOption: "INR" },
inputs: { label: "Fixed costs", activeOption: "INR", defaultValue: 5000 },
},
{
type: "default",
inputs: { label: "Initial Investment", activeOption: "INR" },
inputs: { label: "Initial Investment", activeOption: "INR", defaultValue: 100000 },
},
{
type: "default",
inputs: { label: "Salvage value", activeOption: "Hrs" },
inputs: { label: "Salvage value", activeOption: "Hrs", defaultValue: 5000 },
},
{
type: "default",
inputs: { label: "Production period", activeOption: "yrs" },
inputs: { label: "Production period", activeOption: "yrs", defaultValue: 5 },
},
{
type: "default",
inputs: { label: "Tax rate", activeOption: "%" },
inputs: { label: "Tax rate", activeOption: "%", defaultValue: 30 },
},
],
};
useEffect(() => {
Object.values(AnalysisPresets).forEach((category) => {
category.forEach((item) => {
const { label, defaultValue } = item.inputs;
if (defaultValue !== undefined) {
updateInputValue(label, defaultValue.toString());
}
});
});
}, []);
const { inputValues, setInputValues, updateInputValue } = useInputValues();
return (

View File

@ -10,7 +10,8 @@ interface InputRendererProps {
onInputChange: (label: string, value: string) => void;
}
const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets,inputValues, onInputChange }) => {
const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets, inputValues, onInputChange }) => {
return (
<div key={`main-${keyName}`} className="analysis-inputs">
{presets.map((preset, index) => {
@ -19,7 +20,7 @@ const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets,i
<InputWithDropDown
key={index}
label={preset.inputs.label}
value={inputValues[preset.inputs.label] || ""}
value={preset.inputs.defaultValue?.toString() || inputValues[preset.inputs.label] || ""}
activeOption={preset.inputs.activeOption}
onChange={(newValue) => onInputChange(preset.inputs.label, newValue)}
/>
@ -32,7 +33,7 @@ const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets,i
label={preset.inputs.label}
min={0}
max={8}
value={5}
value={Number(preset.inputs.defaultValue) || Number(inputValues[preset.inputs.label]) || 5}
/>
);
}

View File

@ -26,6 +26,7 @@ const ProductionCapacity = ({
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
console.log('throughputData: ', throughputData);
if (throughputData > 0) {
setIsLoading(false);
} else {

View File

@ -122,7 +122,7 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
zoneUuid: selectedZone.zoneUuid,
zoneName: newName,
};
const response = await zoneCameraUpdate(zonesdata, organization,projectId);
const response = await zoneCameraUpdate(zonesdata, organization, projectId);
if (response.message === "zone updated") {
setSelectedZone((prev) => ({ ...prev, zoneName: newName }));
setZones((prevZones: any[]) =>
@ -143,9 +143,10 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
let response = await setFloorItemApi(
organization,
zoneAssetId.id,
newName
newName,
projectId
);
// console.log("response: ", response);
console.log("response: ", response);
setName(zoneAssetId.id, response.modelName);
}

View File

@ -16,6 +16,7 @@ export default function ROIData() {
useEffect(() => {
if (!isPlaying) {
console.log("running ROIData effect");
setRoiSummaryData({
productName: "",
roiPercentage: 0,
@ -25,11 +26,10 @@ export default function ROIData() {
netProfit: 0,
netLoss: 0,
})
return;
}
if (inputValues === undefined) return;
const electricityCost = parseFloat(inputValues["Electricity cost"]);
const fixedCost = parseFloat(inputValues["Fixed costs"]);
const laborCost = parseFloat(inputValues["Labor Cost"]);
@ -69,15 +69,6 @@ export default function ROIData() {
const paybackPeriod = initialInvestment / (annualProfit || 1); // Avoid division by 0
//
//
//
//
//
//
//
//
setRoiSummaryData({
productName: selectedProduct.productName,
roiPercentage: parseFloat((roiPercentage / 100).toFixed(2)), // normalized to 0.x format
@ -99,14 +90,6 @@ export default function ROIData() {
const netProfitForTarget = profitForTargetUnits > 0 ? profitForTargetUnits : 0;
const netLossForTarget = profitForTargetUnits < 0 ? -profitForTargetUnits : 0;
//
//
//
//
//
//
const productData = getProductById(selectedProduct.productUuid);
@ -140,11 +123,30 @@ export default function ROIData() {
return [...prev, newData];
}
});
// console.log('compareProducts: ', compareProducts);
}
}, [inputValues, productionCapacityData]);
}, [inputValues, productionCapacityData, selectedProduct?.productUuid]);
useEffect(() => {
console.log('compareProducts: ', compareProducts);
}, [compareProducts]);
useEffect(() => {
// Clear ROI summary data when product changes
setRoiSummaryData({
productName: "",
roiPercentage: 0,
paybackPeriod: 0,
totalCost: 0,
revenueGenerated: 0,
netProfit: 0,
netLoss: 0,
});
// Optionally clear comparison data for this product only
setCompareProducts(prev => prev.filter(p => p.productUuid !== selectedProduct.productUuid));
}, [selectedProduct?.productUuid]);
return (
<></>

View File

@ -1,12 +1,15 @@
import React, { useEffect } from 'react'
import { useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
import { useProductContext } from '../../products/productContext';
export default function ProductionCapacityData() {
const { throughputData } = useThroughPutData()
const { productionCapacityData, setProductionCapacityData } = useProductionCapacityData()
const { inputValues } = useInputValues();
const { isPlaying } = usePlayButtonStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
useEffect(() => {
if (!isPlaying) {
@ -16,12 +19,17 @@ export default function ProductionCapacityData() {
if (!inputValues || throughputData === undefined) return;
const shiftLength = parseFloat(inputValues["Shift length"]);
console.log('shiftLength: ', shiftLength);
const shiftsPerDay = parseFloat(inputValues["Shifts / day"]);
const workingDaysPerYear = parseFloat(inputValues["Working days / year"]);
const yieldRate = parseFloat(inputValues["Yield rate"]);
if (!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) &&
!isNaN(yieldRate) && throughputData >= 0) {
!isNaN(yieldRate) && throughputData > 0) {
// Total units produced per day before yield
const dailyProduction = throughputData * shiftLength * shiftsPerDay;
@ -42,6 +50,11 @@ export default function ProductionCapacityData() {
setProductionCapacityData(Number(productionPerHour.toFixed(2)));
}
}, [throughputData, inputValues]);
useEffect(() => {
setProductionCapacityData(0);
}, [selectedProduct?.productUuid]);
return (
<></>

View File

@ -83,7 +83,7 @@ export default function ThroughPutData() {
.forEach(storage => {
if (storage.activeTime > 0) {
// totalActiveTime += storage.activeTime;
//
//
}
});
}
@ -107,15 +107,15 @@ export default function ThroughPutData() {
fetchProductSequenceData();
}
// if (materialCycleTime <= 0) return
}, [products, selectedProduct, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]);
}, [products, selectedProduct?.productUuid, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]);
useEffect(() => {
let timeoutId: ReturnType<typeof setTimeout>;
async function getMachineActive() {
const productData = getProductById(selectedProduct.productUuid);
let anyArmActive;
let anyVehicleActive;
let anyMachineActive;
if (productData) {
const productSequenceData = await determineExecutionMachineSequences([productData]);
if (productSequenceData?.length > 0) {
@ -182,11 +182,15 @@ export default function ThroughPutData() {
}
}
if (isPlaying) {
setTimeout(() => {
timeoutId = setTimeout(() => {
getMachineActive();
}, 500)
}, 1500);
}
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct])
return () => {
if (timeoutId) clearTimeout(timeoutId);
};
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct?.productUuid])
useEffect(() => {
if (machineActiveTime > 0 && materialCycleTime > 0 && machineCount > 0) {
@ -196,7 +200,16 @@ export default function ThroughPutData() {
setThroughputData(Number(throughput.toFixed(2))); // Keep as number
//
}
}, [machineActiveTime, materialCycleTime, machineCount]);
}, [machineActiveTime, materialCycleTime, machineCount, selectedProduct?.productUuid]);
useEffect(() => {
totalActiveTime = 0;
totalItems = 0;
setMachineCount(0);
setMachineActiveTime(0);
setMaterialCycleTime(0);
setProcessBar([]);
setThroughputData(0);
}, [selectedProduct?.productUuid]);
return (
<>

View File

@ -3,24 +3,25 @@ export const setFloorItemApi = async (
organization: string,
modelUuid?: string,
modelName?: string,
projectId?: string,
modelfileID?: string,
position?: Object,
rotation?: Object,
isLocked?: boolean,
isVisible?: boolean
isVisible?: boolean,
) => {
try {
const body: any = {
organization,
modelUuid,
modelName,
projectId,
position,
rotation,
modelfileID,
isLocked,
isVisible,
};
const response = await fetch(`${url_Backend_dwinzo}/api/V1/setAsset`, {
method: "POST",
headers: {

View File

@ -88,6 +88,7 @@ export const createMaterialStore = () => {
clearMaterials: () => {
set((state) => {
state.materials = [];
state.materialHistory = [];
});
},

View File

@ -5,6 +5,7 @@ type Preset = {
activeOption: string;
min?: number;
max?: number;
defaultValue?: string | number;
};
};