Merge branch 'realTimeVisulization' of http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev into realTimeVisulization

This commit is contained in:
2025-03-26 18:46:00 +05:30
18 changed files with 1465 additions and 1162 deletions

View File

@@ -49,25 +49,22 @@ const SideBarRight: React.FC = () => {
{activeModule === "simulation" && ( {activeModule === "simulation" && (
<> <>
<div <div
className={`sidebar-action-list ${ className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""
subModule === "mechanics" ? "active" : "" }`}
}`}
onClick={() => setSubModule("mechanics")} onClick={() => setSubModule("mechanics")}
> >
<MechanicsIcon isActive={activeList === "mechanics"} /> <MechanicsIcon isActive={activeList === "mechanics"} />
</div> </div>
<div <div
className={`sidebar-action-list ${ className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""
subModule === "simulations" ? "active" : "" }`}
}`}
onClick={() => setSubModule("simulations")} onClick={() => setSubModule("simulations")}
> >
<SimulationIcon isActive={activeList === "simulations"} /> <SimulationIcon isActive={activeList === "simulations"} />
</div> </div>
<div <div
className={`sidebar-action-list ${ className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""
subModule === "analysis" ? "active" : "" }`}
}`}
onClick={() => setSubModule("analysis")} onClick={() => setSubModule("analysis")}
> >
<AnalysisIcon isActive={activeList === "analysis"} /> <AnalysisIcon isActive={activeList === "analysis"} />
@@ -78,7 +75,18 @@ const SideBarRight: React.FC = () => {
)} )}
{/* process builder */} {/* process builder */}
{toggleUI && {toggleUI &&
activeList === "properties" && subModule === "zoneProperties" &&
activeModule === "builder" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
{/* <GlobalProperties /> */}
<ZoneProperties />
{/* <AsstePropertiies /> */}
</div>
</div>
)}
{toggleUI &&
subModule === "properties" &&
activeModule !== "visualization" && ( activeModule !== "visualization" && (
<div className="sidebar-right-container"> <div className="sidebar-right-container">
<div className="sidebar-right-content-container"> <div className="sidebar-right-content-container">
@@ -88,7 +96,6 @@ const SideBarRight: React.FC = () => {
</div> </div>
</div> </div>
)} )}
{/* simulation */} {/* simulation */}
{toggleUI && activeModule === "simulation" && ( {toggleUI && activeModule === "simulation" && (

View File

@@ -1,9 +1,11 @@
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import RenameInput from "../../../ui/inputs/RenameInput"; import RenameInput from "../../../ui/inputs/RenameInput";
import Vector3Input from "../customInput/Vector3Input"; import Vector3Input from "../customInput/Vector3Input";
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
const ZoneProperties: React.FC = () => { const ZoneProperties: React.FC = () => {
const [Edit, setEdit] = useState(false); const [Edit, setEdit] = useState(false);
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
function handleSetView() { function handleSetView() {
setEdit(false); setEdit(false);
@@ -16,17 +18,21 @@ const ZoneProperties: React.FC = () => {
setEdit(true); setEdit(true);
} }
} }
useEffect(() => {
console.log(' selectedZone.zoneName: ', selectedZone.zoneName);
}, [selectedZone])
return ( return (
<div className="zone-properties-container"> <div className="zone-properties-container">
<div className="header"> <div className="header">
<RenameInput value="Selected Zone Name" /> <RenameInput value={selectedZone.zoneName ? selectedZone.zoneName : ""} />
<div className="button" onClick={handleEditView}> <div className="button" onClick={handleEditView}>
{Edit ? "Cancel" : "Edit"} {Edit ? "Cancel" : "Edit"}
</div> </div>
</div> </div>
<Vector3Input onChange={() => {}} header="Viewport Target" /> <Vector3Input onChange={() => { }} header="Viewport Target" />
<Vector3Input onChange={() => {}} header="Viewport Position" /> <Vector3Input onChange={() => { }} header="Viewport Position" />
{Edit && ( {Edit && (
<div className="button-save" onClick={handleSetView}> <div className="button-save" onClick={handleSetView}>
Set View Set View

View File

@@ -4,6 +4,7 @@ import {
EyeIcon, EyeIcon,
LockIcon, LockIcon,
} from "../../icons/RealTimeVisulationIcons"; } from "../../icons/RealTimeVisulationIcons";
import { panelData } from "../../../services/realTimeVisulization/zoneData/panel";
// Define the type for `Side` // Define the type for `Side`
type Side = "top" | "bottom" | "left" | "right"; type Side = "top" | "bottom" | "left" | "right";
@@ -15,6 +16,9 @@ interface ButtonsProps {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: { widgets: {
id: string; id: string;
type: string; type: string;
@@ -29,6 +33,9 @@ interface ButtonsProps {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: { widgets: {
id: string; id: string;
type: string; type: string;
@@ -108,7 +115,7 @@ const AddButtons: React.FC<ButtonsProps> = ({
panelOrder: newActiveSides, panelOrder: newActiveSides,
}; };
// Update the selectedZone state // Delete the selectedZone state
console.log('updatedZone: ', updatedZone); console.log('updatedZone: ', updatedZone);
setSelectedZone(updatedZone); setSelectedZone(updatedZone);
} else { } else {
@@ -120,6 +127,10 @@ const AddButtons: React.FC<ButtonsProps> = ({
activeSides: newActiveSides, activeSides: newActiveSides,
panelOrder: newActiveSides, panelOrder: newActiveSides,
}; };
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
let response = panelData(organization, selectedZone.zoneId, newActiveSides)
console.log('response: ', response);
// Update the selectedZone state // Update the selectedZone state
console.log('updatedZone: ', updatedZone); console.log('updatedZone: ', updatedZone);
@@ -128,65 +139,73 @@ const AddButtons: React.FC<ButtonsProps> = ({
}; };
return ( return (
<div> <>
{(["top", "right", "bottom", "left"] as Side[]).map((side) => (
<div key={side} className={`side-button-container ${side}`}>
<button
className={`side-button ${side}`}
onClick={() => handlePlusButtonClick(side)}
title={
selectedZone.activeSides.includes(side)
? `Remove all items and close ${side} panel`
: `Activate ${side} panel`
}
>
+
</button>
{/* Extra Buttons */} <div>
{selectedZone.activeSides.includes(side) && ( {(["top", "right", "bottom", "left"] as Side[]).map((side) => (
<div className="extra-Bs"> <div key={side} className={`side-button-container ${side}`}>
{/* Hide Panel */} {/* "+" Button */}
<div <button
className={`icon ${hiddenPanels.includes(side) ? "active" : "" className={`side-button ${side}`}
}`} onClick={() => handlePlusButtonClick(side)}
title={ title={
hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel" selectedZone.activeSides.includes(side)
} ? `Remove all items and close ${side} panel`
onClick={() => toggleVisibility(side)} : `Activate ${side} panel`
> }
<EyeIcon >
fill={hiddenPanels.includes(side) ? "white" : "#1D1E21"} +
/> </button>
</div>
{/* Clean Panel */} {/* Extra Buttons */}
<div {selectedZone.activeSides.includes(side) && (
className="icon" <div className="extra-Bs">
title="Clean Panel" {/* Hide Panel */}
onClick={() => cleanPanel(side)} <div
> className={`icon ${hiddenPanels.includes(side) ? "active" : ""
<CleanPannel /> }`}
</div> title={
hiddenPanels.includes(side) ? "Show Panel" : "Hide Panel"
}
onClick={() => toggleVisibility(side)}
>
<EyeIcon
fill={
hiddenPanels.includes(side)
? "white"
: "#1D1E21"
}
/>
</div>
{/* Lock/Unlock Panel */} {/* Clean Panel */}
<div <div
className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : "" className="icon"
}`} title="Clean Panel"
title={ onClick={() => cleanPanel(side)}
selectedZone.lockedPanels.includes(side) >
? "Unlock Panel" <CleanPannel />
: "Lock Panel" </div>
}
onClick={() => toggleLockPanel(side)} {/* Lock/Unlock Panel */}
> <div
<LockIcon fill={selectedZone.lockedPanels.includes(side) ? "#ffffff" : "#1D1E21"} /> className={`icon ${selectedZone.lockedPanels.includes(side) ? "active" : ""
}`}
title={
selectedZone.lockedPanels.includes(side)
? "Unlock Panel"
: "Lock Panel"
}
onClick={() => toggleLockPanel(side)}
>
<LockIcon fill={selectedZone.lockedPanels.includes(side) ? "#ffffff" : "#1D1E21"} />
</div>
</div> </div>
</div> )}
)} </div>
</div> ))}
))} </div>
</div> </>
); );
}; };

View File

@@ -11,6 +11,9 @@ interface DisplayZoneProps {
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
widgets: Widget[]; widgets: Widget[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
}; };
}; };
selectedZone: { selectedZone: {
@@ -18,6 +21,9 @@ interface DisplayZoneProps {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: { widgets: {
id: string; id: string;
type: string; type: string;
@@ -32,6 +38,9 @@ interface DisplayZoneProps {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: { widgets: {
id: string; id: string;
type: string; type: string;
@@ -152,16 +161,16 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
return ( return (
<div <div
ref={containerRef} ref={containerRef}
className={`zoon-wrapper ${selectedZone.activeSides.includes("bottom") && "bottom" className={`zoon-wrapper ${selectedZone?.activeSides?.includes("bottom") && "bottom"
}`} }`}
> >
{Object.keys(zonesData).map((zoneName, index) => ( {Object.keys(zonesData).map((zoneName, index) => (
<div <div
key={index} key={index}
className={`zone ${selectedZone.zoneName === zoneName ? "active" : "" className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
}`} }`}
onClick={() => { onClick={() => {
console.log('zoneName: ', zoneName);
setSelectedZone({ setSelectedZone({
zoneName, zoneName,
@@ -169,12 +178,15 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
panelOrder: zonesData[zoneName].panelOrder || [], panelOrder: zonesData[zoneName].panelOrder || [],
lockedPanels: zonesData[zoneName].lockedPanels || [], lockedPanels: zonesData[zoneName].lockedPanels || [],
widgets: zonesData[zoneName].widgets || [], widgets: zonesData[zoneName].widgets || [],
}) zoneId: zonesData[zoneName]?.zoneId || "",
zoneViewPortTarget: zonesData[zoneName].zoneViewPortTarget || [],
zoneViewPortPosition:
zonesData[zoneName].zoneViewPortPosition || [],
});
// setSelectedZone({ // setSelectedZone({
// zoneName, // zoneName,
// ...zonesData[zoneName], // ...zonesData[zoneName],
// }); // });
console.log(selectedZone);
}} }}
> >
{zoneName} {zoneName}

View File

@@ -0,0 +1,59 @@
import { useState } from "react";
import { useThree } from "@react-three/fiber";
import * as THREE from "three";
const DroppedObjects = () => {
const { camera } = useThree(); // Now inside Canvas ✅
const [objects, setObjects] = useState<{ id: number; position: [number, number, number] }[]>([]);
// Function to convert drop event into 3D position
const handleDrop = (event: DragEvent) => {
event.preventDefault();
const data = event.dataTransfer?.getData("text/plain");
if (!data) return;
try {
const cardData = JSON.parse(data);
if (!cardData.className.includes("floating total-card")) {
console.log("Drop rejected: Incorrect element.");
return;
}
// Convert 2D drop position to 3D world coordinates
const x = (event.clientX / window.innerWidth) * 2 - 1;
const y = -(event.clientY / window.innerHeight) * 2 + 1;
// Raycasting to determine the drop position in 3D
const raycaster = new THREE.Raycaster();
const mouseVector = new THREE.Vector2(x, y);
raycaster.setFromCamera(mouseVector, camera);
// Intersect with a ground plane (assume y = 0)
const groundPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
const intersection = new THREE.Vector3();
raycaster.ray.intersectPlane(groundPlane, intersection);
console.log("Spawn Object at:", intersection);
// Add the dropped object to the scene state
setObjects((prev) => [...prev, { id: Date.now(), position: [intersection.x, intersection.y, intersection.z] }]);
} catch (error) {
console.error("Invalid data:", error);
}
};
return (
<group>
{/* Render dropped objects as green boxes */}
{objects.map((obj) => (
<mesh key={obj.id} position={obj.position}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="green" />
</mesh>
))}
</group>
);
};
export default DroppedObjects;

View File

@@ -20,6 +20,9 @@ interface PanelProps {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: Widget[]; widgets: Widget[];
}; };
setSelectedZone: React.Dispatch< setSelectedZone: React.Dispatch<
@@ -28,6 +31,9 @@ interface PanelProps {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: Widget[]; widgets: Widget[];
}> }>
>; >;

View File

@@ -6,7 +6,8 @@ import { useSelectedZoneStore } from "../../../store/useZoneStore";
import DisplayZone from "./DisplayZone"; import DisplayZone from "./DisplayZone";
import Scene from "../../../modules/scene/scene"; import Scene from "../../../modules/scene/scene";
import useModuleStore from "../../../store/useModuleStore"; import useModuleStore from "../../../store/useModuleStore";
import { getZonesApi } from "../../../services/realTimeVisulization/zoneData/getZones"; import { useZones } from "../../../store/store";
type Side = "top" | "bottom" | "left" | "right"; type Side = "top" | "bottom" | "left" | "right";
@@ -17,7 +18,9 @@ type FormattedZoneData = Record<
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneCentrePoint: number[]; zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[]
widgets: Widget[]; widgets: Widget[];
} }
>; >;
@@ -28,12 +31,6 @@ type Widget = {
panel: Side; panel: Side;
data: any; data: any;
}; };
type Zone = {
zoneId: string;
zoneName: string;
points: number[][];
layer: number;
};
const RealTimeVisulization: React.FC = () => { const RealTimeVisulization: React.FC = () => {
const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]); const [hiddenPanels, setHiddenPanels] = React.useState<Side[]>([]);
@@ -43,45 +40,30 @@ const RealTimeVisulization: React.FC = () => {
const [zonesData, setZonesData] = useState<FormattedZoneData>({}); const [zonesData, setZonesData] = useState<FormattedZoneData>({});
const { selectedZone, setSelectedZone } = useSelectedZoneStore(); const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const { zones } = useZones()
useEffect(() => { useEffect(() => {
async function GetZoneData() { const data = Array.isArray(zones) ? zones : [];
try { console.log('data: ', data);
const response: { data: Zone[] } | undefined = await getZonesApi( const formattedData = data.reduce<FormattedZoneData>((acc, zone) => {
"hexrfactory" acc[zone.zoneName] = {
); activeSides: [],
panelOrder: [],
lockedPanels: [],
zoneId: zone.zoneId,
zoneViewPortTarget: zone.viewPortCenter,
zoneViewPortPosition: zone.viewPortposition,
widgets: [],
};
return acc;
}, {});
if (!response || !response.data) { setZonesData(formattedData);
return; }, [zones]);
}
const formattedData = response?.data?.reduce<FormattedZoneData>(
(acc, zone) => {
acc[zone.zoneName] = {
activeSides: [],
panelOrder: [],
lockedPanels: [],
zoneCentrePoint: [],
widgets: [],
};
return acc;
},
{}
);
setZonesData(formattedData);
} catch (error) { }
}
GetZoneData();
}, []);
useEffect(() => {
console.log('zonesData: ', zonesData);
}, [zonesData]);
useEffect(() => { useEffect(() => {
setZonesData((prev) => { setZonesData((prev) => {
if (!selectedZone) return prev; if (!selectedZone) return prev;
return { return {
...prev, ...prev,
[selectedZone.zoneName]: { [selectedZone.zoneName]: {
@@ -89,12 +71,32 @@ const RealTimeVisulization: React.FC = () => {
activeSides: selectedZone.activeSides || [], activeSides: selectedZone.activeSides || [],
panelOrder: selectedZone.panelOrder || [], panelOrder: selectedZone.panelOrder || [],
lockedPanels: selectedZone.lockedPanels || [], lockedPanels: selectedZone.lockedPanels || [],
zoneId: selectedZone.zoneId || "",
zoneViewPortTarget: selectedZone.zoneViewPortTarget || [],
zoneViewPortPosition: selectedZone.zoneViewPortPosition || [],
widgets: selectedZone.widgets || [], widgets: selectedZone.widgets || [],
}, },
}; };
}); });
}, [selectedZone]); }, [selectedZone]);
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
const canvas = document.querySelector(".scene-container");
if (canvas) {
// Extract relevant properties manually
const dragEvent = new DragEvent("drop", {
bubbles: true,
cancelable: true,
dataTransfer: event.dataTransfer, // Attach dataTransfer manually ✅
});
console.log('dragEvent: ', dragEvent);
canvas.dispatchEvent(dragEvent);
}
};
return ( return (
<div <div
ref={containerRef} ref={containerRef}
@@ -113,7 +115,14 @@ const RealTimeVisulization: React.FC = () => {
width: "100%", width: "100%",
borderRadius: isPlaying || activeModule !== "visualization" ? "" : "6px", borderRadius: isPlaying || activeModule !== "visualization" ? "" : "6px",
}} }}
onDrop={handleDrop}
> >
{/* {objects.map((obj) => (
<mesh key={obj.id} position={obj.position}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="green" />
</mesh>
))} */}
<Scene /> <Scene />
</div> </div>
{activeModule === "visualization" && ( {activeModule === "visualization" && (
@@ -124,7 +133,7 @@ const RealTimeVisulization: React.FC = () => {
setSelectedZone={setSelectedZone} setSelectedZone={setSelectedZone}
/> />
{!isPlaying && ( {!isPlaying && selectedZone?.zoneName !== "" && (
<AddButtons <AddButtons
hiddenPanels={hiddenPanels} hiddenPanels={hiddenPanels}
setHiddenPanels={setHiddenPanels} setHiddenPanels={setHiddenPanels}
@@ -134,9 +143,10 @@ const RealTimeVisulization: React.FC = () => {
)} )}
<Panel <Panel
hiddenPanels={hiddenPanels}
selectedZone={selectedZone} selectedZone={selectedZone}
setSelectedZone={setSelectedZone} setSelectedZone={setSelectedZone}
hiddenPanels={hiddenPanels}
/> />
</> </>
)} )}

View File

@@ -0,0 +1,96 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { useThree } from "@react-three/fiber";
import * as THREE from "three";
import { useSelectedZoneStore } from "../../../store/useZoneStore";
export default function ZoneCentreTarget() {
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const [previousZoneCentre, setPreviousZoneCentre] = useState<number[] | null>(null);
const sphereRef = useRef<THREE.Mesh>(null);
const { camera, controls }: any = useThree();
useEffect(() => {
if (
selectedZone.zoneViewPortTarget &&
JSON.stringify(previousZoneCentre) !== JSON.stringify(selectedZone.zoneViewPortTarget)
) {
setPreviousZoneCentre(selectedZone.zoneViewPortTarget);
}
}, [selectedZone.zoneViewPortTarget, previousZoneCentre]);
const centrePoint = useMemo(() => {
if (!previousZoneCentre || !selectedZone.zoneViewPortTarget) return null;
return previousZoneCentre.map((value, index) =>
(value + selectedZone.zoneViewPortTarget[index]) / 2
);
}, [previousZoneCentre, selectedZone.zoneViewPortTarget]);
useEffect(() => {
if (selectedZone.zoneName !== "") {
if (sphereRef.current) {
sphereRef.current.position.set(selectedZone.zoneViewPortTarget[0], selectedZone.zoneViewPortTarget[1], selectedZone.zoneViewPortTarget[2]);
}
if (centrePoint) {
if (centrePoint.length > 0) {
let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition);
let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget);
const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize();
const worldUp = new THREE.Vector3(0, 0, 1);
const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize();
const up = new THREE.Vector3().crossVectors(direction, right).normalize();
const offsetPosition = up.clone().multiplyScalar(20);
camPosition.add(offsetPosition);
const setCam = async () => {
controls.setLookAt(centrePoint[0], 100, centrePoint[2], ...centrePoint, true);
setTimeout(() => {
controls?.setLookAt(
...camPosition.toArray(),
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
}, 400)
};
setCam();
} else {
let camPosition = new THREE.Vector3(...selectedZone.zoneViewPortPosition);
let CamTarget = new THREE.Vector3(...selectedZone.zoneViewPortTarget);
const direction = new THREE.Vector3().subVectors(CamTarget, camPosition).normalize();
const worldUp = new THREE.Vector3(0, 0, 1);
const right = new THREE.Vector3().crossVectors(worldUp, direction).normalize();
const up = new THREE.Vector3().crossVectors(direction, right).normalize();
const offsetPosition = up.clone().multiplyScalar(20);
camPosition.add(offsetPosition);
const setCam = async () => {
controls?.setLookAt(
...camPosition.toArray(),
selectedZone.zoneViewPortTarget[0],
selectedZone.zoneViewPortTarget[1],
selectedZone.zoneViewPortTarget[2],
true
);
};
setCam();
}
}
}
}, [selectedZone.zoneViewPortTarget, camera, controls]);
return (
<> </>
);
}

View File

@@ -2,7 +2,8 @@ import React, { useEffect, useState } from "react";
import List from "./List"; import List from "./List";
import { AddIcon, ArrowIcon, FocusIcon } from "../../icons/ExportCommonIcons"; import { AddIcon, ArrowIcon, FocusIcon } from "../../icons/ExportCommonIcons";
import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect"; import KebabMenuListMultiSelect from "./KebebMenuListMultiSelect";
import { getZonesApi } from "../../../services/realTimeVisulization/zoneData/getZones"; import { useZones } from "../../../store/store";
import { useSelectedZoneStore } from "../../../store/useZoneStore";
interface DropDownListProps { interface DropDownListProps {
value?: string; // Value to display in the DropDownList value?: string; // Value to display in the DropDownList
@@ -29,24 +30,23 @@ const DropDownList: React.FC<DropDownListProps> = ({
defaultOpen = false, defaultOpen = false,
listType = "default", listType = "default",
}) => { }) => {
const [isOpen, setIsOpen] = useState<boolean>(defaultOpen); const [isOpen, setIsOpen] = useState<boolean>(defaultOpen);
const { zones, setZones } = useZones()
const handleToggle = () => { const handleToggle = () => {
setIsOpen((prev) => !prev); // Toggle the state setIsOpen((prev) => !prev); // Toggle the state
}; };
const [zoneDataList, setZoneDataList] = useState<{ id: string; name: string }[]>([]); const [zoneDataList, setZoneDataList] = useState<{ id: string; name: string }[]>([]);
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
useEffect(() => { useEffect(() => {
async function GetZoneData() { const value = (zones || []).map((val: { zoneId: string; zoneName: string }) => ({
const response = await getZonesApi("hexrfactory") id: val.zoneId,
console.log('response: ', response.data); name: val.zoneName
setZoneDataList([{ id: "1", name: "zone1" }, }));
{ id: "2", name: "Zone 2" },]) setZoneDataList(prev => (JSON.stringify(prev) !== JSON.stringify(value) ? value : prev));
} }, [zones]);
GetZoneData()
}, [])
return ( return (
<div className="dropdown-list-container"> <div className="dropdown-list-container">

View File

@@ -1,6 +1,9 @@
import React from "react"; import React from "react";
import RenameInput from "../inputs/RenameInput"; import RenameInput from "../inputs/RenameInput";
import { EyeIcon, LockIcon, RmoveIcon } from "../../icons/ExportCommonIcons"; import { EyeIcon, LockIcon, RmoveIcon } from "../../icons/ExportCommonIcons";
import { useSelectedZoneStore } from "../../../store/useZoneStore";
import { getZoneData } from "../../../services/realTimeVisulization/zoneData/getZones";
import { useSubModuleStore } from "../../../store/useModuleStore";
interface ListProps { interface ListProps {
items?: { id: string; name: string }[]; // Optional array of items to render items?: { id: string; name: string }[]; // Optional array of items to render
@@ -8,7 +11,28 @@ interface ListProps {
} }
const List: React.FC<ListProps> = ({ items = [] }) => { const List: React.FC<ListProps> = ({ items = [] }) => {
console.log('items: ', items); const { selectedZone, setSelectedZone } = useSelectedZoneStore();
const { subModule, setSubModule } = useSubModuleStore();
async function handleSelectZone(id: string) {
setSubModule("zoneProperties")
const email = localStorage.getItem('email')
const organization = (email!.split("@")[1]).split(".")[0];
let response = await getZoneData(id, organization)
console.log('response: ', response);
setSelectedZone({
zoneName: response?.zoneName,
activeSides: response?.activeSides || [],
panelOrder: response?.panelOrder || [],
lockedPanels: response?.lockedPanels || [],
widgets: response?.widgets || [],
zoneId: response?.zoneId,
zoneViewPortTarget: response?.viewPortCenter || [],
zoneViewPortPosition:
response?.viewPortposition || [],
});
}
return ( return (
<> <>
{items.length > 0 ? ( {items.length > 0 ? (
@@ -16,7 +40,7 @@ const List: React.FC<ListProps> = ({ items = [] }) => {
{items.map((item, index) => ( {items.map((item, index) => (
<li key={index} className="list-container"> <li key={index} className="list-container">
<div className="list-item"> <div className="list-item">
<div className="value"> <div className="value" onClick={() => handleSelectZone(item.id)}>
<RenameInput value={item.name} /> <RenameInput value={item.name} />
</div> </div>
<div className="options-container"> <div className="options-container">

View File

@@ -13,8 +13,19 @@ const SimpleCard: React.FC<SimpleCardProps> = ({
value, value,
per, per,
}) => { }) => {
const handleDragStart = (event: React.DragEvent<HTMLDivElement>) => {
const cardData = JSON.stringify({
header,
value,
per,
className: event.currentTarget.className, // Store the class name
});
event.dataTransfer.setData("text/plain", cardData);
};
return ( return (
<div className="floating total-card" draggable> <div className="floating total-card" draggable onDragStart={handleDragStart}>
<div className="header-wrapper"> <div className="header-wrapper">
<div className="header">{header}</div> <div className="header">{header}</div>
<div className="data-values"> <div className="data-values">

View File

@@ -112,7 +112,7 @@ export default async function assetManager(
) { ) {
if (!activePromises.get(taskId)) return; // Stop processing if task is canceled if (!activePromises.get(taskId)) return; // Stop processing if task is canceled
const existingModel = itemsGroup.current.getObjectByProperty("uuid", item.modeluuid); const existingModel = itemsGroup?.current?.getObjectByProperty("uuid", item.modeluuid);
if (existingModel) { if (existingModel) {
// console.log(`Model ${item.modelname} already exists in the scene.`); // console.log(`Model ${item.modelname} already exists in the scene.`);
resolve(); resolve();

View File

@@ -65,6 +65,8 @@ const ZoneGroup: React.FC = () => {
zoneId: zone.zoneId, zoneId: zone.zoneId,
zoneName: zone.zoneName, zoneName: zone.zoneName,
points: zone.points, points: zone.points,
viewPortCenter: zone.viewPortCenter,
viewPortposition: zone.viewPortposition,
layer: zone.layer layer: zone.layer
})); }));
@@ -145,7 +147,7 @@ const ZoneGroup: React.FC = () => {
const target: [number, number, number] | null = calculateCenter(zone.points); const target: [number, number, number] | null = calculateCenter(zone.points);
if (!target) return; if (!target) return;
const position = [target[0], 75, target[2]]; const position = [target[0], 10, target[2]];
const input = { const input = {
userId: userId, userId: userId,
@@ -186,7 +188,7 @@ const ZoneGroup: React.FC = () => {
const target: [number, number, number] | null = calculateCenter(zone.points); const target: [number, number, number] | null = calculateCenter(zone.points);
if (!target) return; if (!target) return;
const position = [target[0], 75, target[2]]; const position = [target[0], 10, target[2]];
const input = { const input = {
userId: userId, userId: userId,

View File

@@ -745,6 +745,7 @@ export default function SocketResponses({
return return
} }
if (data.message === "zone deleted") { if (data.message === "zone deleted") {
console.log('data: ', data);
const updatedZones = zones.filter((zone: any) => zone.zoneId !== data.data.zoneId); const updatedZones = zones.filter((zone: any) => zone.zoneId !== data.data.zoneId);
setZones(updatedZones); setZones(updatedZones);

View File

@@ -1,4 +1,4 @@
import { useMemo } from "react"; import { useMemo, useState } from "react";
import { Canvas } from "@react-three/fiber"; import { Canvas } from "@react-three/fiber";
import { Environment, KeyboardControls } from "@react-three/drei"; import { Environment, KeyboardControls } from "@react-three/drei";
@@ -15,6 +15,11 @@ import background from "../../assets/textures/hdr/mudroadpuresky2k.hdr";
import SelectionControls from "./controls/selection/selectionControls"; import SelectionControls from "./controls/selection/selectionControls";
import MeasurementTool from "./tools/measurementTool"; import MeasurementTool from "./tools/measurementTool";
import Simulation from "../simulation/simulation"; import Simulation from "../simulation/simulation";
import ZoneCentreTarget from "../../components/ui/componets/zoneCameraTarget";
import { useThree } from "@react-three/fiber";
import * as THREE from "three";
import DroppedObjects from "../../components/ui/componets/DroppedFloatingWidgets";
// import Simulation from "./simulationtemp/simulation"; // import Simulation from "./simulationtemp/simulation";
export default function Scene() { export default function Scene() {
@@ -27,6 +32,9 @@ export default function Scene() {
// { name: "jump", keys: ["Space"] }, // { name: "jump", keys: ["Space"] },
], []) ], [])
return ( return (
<KeyboardControls map={map}> <KeyboardControls map={map}>
<Canvas <Canvas
@@ -36,12 +44,15 @@ export default function Scene() {
onContextMenu={(e) => { onContextMenu={(e) => {
e.preventDefault(); e.preventDefault();
}} }}
> >
<DroppedObjects/>
<Controls /> <Controls />
<TransformControl /> <TransformControl />
<SelectionControls /> <SelectionControls />
<MeasurementTool /> <MeasurementTool />
<World /> <World />
<ZoneCentreTarget />
{/* <Simulation /> */} {/* <Simulation /> */}
<Simulation /> <Simulation />
<PostProcessing /> <PostProcessing />

View File

@@ -1,25 +1,23 @@
let url_Backend_dwinzo = `http://185.100.212.76:5000`; let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const getZonesApi = async (organization: string) => { export const getZoneData = async (zoneId: string, organization: string) => {
try { try {
const response = await fetch(`${url_Backend_dwinzo}/api/v2/findZones/${organization}`, { const response = await fetch(
method: "GET", `${url_Backend_dwinzo}/api/v2/A_zone/${zoneId}/${organization}`,
headers: { {
"Content-Type": "application/json", method: "GET",
}, headers: {
}); "Content-Type": "application/json",
},
}
);
// if (!response.ok) { if (!response.ok) {
// throw new Error("Failed to get Zones"); throw new Error("Failed to fetch zoneData");
// }
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
} }
return await response.json();
} catch (error: any) {
throw new Error(error.message);
}
}; };

View File

@@ -0,0 +1,31 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
type Side = "top" | "bottom" | "left" | "right";
export const panelData = async (organization: string, zoneID: string, panelOrder: Side[]) => {
console.log('panelOrder: ', panelOrder);
console.log('zoneID: ', zoneID);
console.log('organization: ', organization);
try {
const response = await fetch(`${url_Backend_dwinzo}/api/v1/panel/save`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ organization, zoneID, panelOrder }),
});
if (!response.ok) {
throw new Error("Failed to add panelOrder for Zone");
}
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@@ -15,21 +15,31 @@ interface SelectedZoneState {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string;
zoneViewPortTarget: number[];
zoneViewPortPosition: number[];
widgets: Widget[]; widgets: Widget[];
} }
interface SelectedZoneStore { interface SelectedZoneStore {
selectedZone: SelectedZoneState; selectedZone: SelectedZoneState;
setSelectedZone: (zone: Partial<SelectedZoneState> | ((prev: SelectedZoneState) => SelectedZoneState)) => void; setSelectedZone: (
zone:
| Partial<SelectedZoneState>
| ((prev: SelectedZoneState) => SelectedZoneState)
) => void;
} }
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({ export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
selectedZone: { selectedZone: {
zoneName: "", zoneName: "", // Empty string initially
activeSides: [], activeSides: [], // Empty array
panelOrder: [], panelOrder: [], // Empty array
lockedPanels: [], lockedPanels: [], // Empty array
widgets: [], zoneId: "",
zoneViewPortTarget: [],
zoneViewPortPosition: [],
widgets: [], // Empty array
}, },
setSelectedZone: (zone) => setSelectedZone: (zone) =>
set((state) => ({ set((state) => ({