diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/InputSelecterComponent.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/InputSelecterComponent.tsx
index 3b44fc2..2d82225 100644
--- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/InputSelecterComponent.tsx
+++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/InputSelecterComponent.tsx
@@ -14,8 +14,6 @@ import { useWidgetStore } from '../../../../../store/useWidgetStore'
const InputSelecterComponent = () => {
const { selectedChartId } = useWidgetStore();
- console.log('selectedChartId:',selectedChartId);
-
if (selectedChartId && selectedChartId.type && selectedChartId.type === 'bar' ) {
return (
diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget2InputCard3D.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget2InputCard3D.tsx
index bad0afc..c6d1509 100644
--- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget2InputCard3D.tsx
+++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget2InputCard3D.tsx
@@ -21,8 +21,6 @@ const Widget2InputCard3D = (props: Props) => {
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
- console.log(selectedChartId);
-
useEffect(() => {
const fetchZoneData = async () => {
diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget3InputCard3D.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget3InputCard3D.tsx
index c720e66..95fdc33 100644
--- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget3InputCard3D.tsx
+++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget3InputCard3D.tsx
@@ -19,9 +19,7 @@ const Widget3InputCard3D = () => {
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
- console.log(selectedChartId);
-
-
+
useEffect(() => {
const fetchZoneData = async () => {
try {
diff --git a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget4InputCard3D.tsx b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget4InputCard3D.tsx
index 0be5489..3244773 100644
--- a/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget4InputCard3D.tsx
+++ b/app/src/components/layout/sidebarRight/visualization/IotInputCards/Widget4InputCard3D.tsx
@@ -21,9 +21,7 @@ const Widget4InputCard3D = (props: Props) => {
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]
- console.log(selectedChartId);
-
-
+
useEffect(() => {
const fetchZoneData = async () => {
try {
diff --git a/app/src/components/ui/componets/Dropped3dWidget.tsx b/app/src/components/ui/componets/Dropped3dWidget.tsx
index f0d5e66..f43cce5 100644
--- a/app/src/components/ui/componets/Dropped3dWidget.tsx
+++ b/app/src/components/ui/componets/Dropped3dWidget.tsx
@@ -1,5 +1,5 @@
import { useThree } from "@react-three/fiber";
-import React, { useState, useEffect } from "react";
+import React, { useState, useEffect, useRef } from "react";
import { useAsset3dWidget, useSocketStore, useWidgetSubOption } from "../../../store/store";
import useModuleStore from "../../../store/useModuleStore";
import { ThreeState } from "../../../types/world/worldTypes";
@@ -13,30 +13,43 @@ import { generateUniqueId } from "../../../functions/generateUniqueId";
import { adding3dWidgets } from "../../../services/realTimeVisulization/zoneData/add3dWidget";
import { get3dWidgetZoneData } from "../../../services/realTimeVisulization/zoneData/get3dWidgetData";
import { use3DWidget } from "../../../store/useDroppedObjectsStore";
-import { useZoneWidgetStore } from "../../../store/useZone3DWidgetStore";
+import { useLeftData, useRightClickSelected, useRightSelected, useTopData, useZoneWidgetStore } from "../../../store/useZone3DWidgetStore";
+import { useWidgetStore } from "../../../store/useWidgetStore";
+import EditWidgetOption from "../menu/EditWidgetOption";
export default function Dropped3dWidgets() {
const { widgetSelect } = useAsset3dWidget();
const { activeModule } = useModuleStore();
- const { raycaster, gl, scene }: ThreeState = useThree();
+ const { raycaster, gl, scene, mouse, camera }: ThreeState = useThree();
const { widgetSubOption } = useWidgetSubOption();
const { selectedZone } = useSelectedZoneStore();
+ const { top, setTop } = useTopData()
+ const { left, setLeft } = useLeftData()
+ const { rightSelect, setRightSelect } = useRightSelected()
// ✅ Use Zustand Store instead of useState
- const { zoneWidgetData, setZoneWidgetData, addWidget } = useZoneWidgetStore();
+ const { zoneWidgetData, setZoneWidgetData, addWidget, updateWidgetPosition } = useZoneWidgetStore();
const { setWidgets3D } = use3DWidget();
const { visualizationSocket } = useSocketStore();
+ const { rightClickSelected, setRightClickSelected } = useRightClickSelected()
+
+ const plane = useRef(new THREE.Plane(new THREE.Vector3(0, 1, 0), 0)); // Floor plane for horizontal move
+ const verticalPlane = useRef(new THREE.Plane(new THREE.Vector3(0, 0, 1), 0)); // Vertical plane for vertical move
+ const planeIntersect = useRef(new THREE.Vector3());
+ // let [verticalPlane, setFloorPlanesVertical] = useState(
+ // new THREE.Plane(new THREE.Vector3(0, 1, 0))
+ // );
useEffect(() => {
if (activeModule !== "visualization") return;
if (!selectedZone.zoneId) return;
- const email = localStorage.getItem("email") || "";
- const organization = email?.split("@")[1]?.split(".")[0];
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
async function get3dWidgetData() {
let result = await get3dWidgetZoneData(selectedZone.zoneId, organization);
- console.log('result: ', result);
+
setWidgets3D(result);
const formattedWidgets = result.map((widget: any) => ({
@@ -89,13 +102,13 @@ export default function Dropped3dWidgets() {
widget: newWidget,
zoneId: selectedZone.zoneId
}
- console.log('add3dWidget: ', add3dWidget);
+
if (visualizationSocket) {
visualizationSocket.emit("v2:viz-3D-widget:add", add3dWidget)
}
// let response = await adding3dWidgets(selectedZone.zoneId, organization, newWidget);
- // console.log('response: ', response);
+ //
// if (response.message === "Widget created successfully") {
addWidget(selectedZone.zoneId, newWidget);
@@ -111,23 +124,142 @@ export default function Dropped3dWidgets() {
const activeZoneWidgets = zoneWidgetData[selectedZone.zoneId] || [];
+ useEffect(() => {
+ if (!rightClickSelected) return;
+ const email = localStorage.getItem("email") || "";
+ const organization = email?.split("@")[1]?.split(".")[0];
+ if (rightSelect === "Duplicate") {
+ const widgetToDuplicate = activeZoneWidgets.find(w => w.id === rightClickSelected);
+ if (!widgetToDuplicate) return;
+ const newWidget = {
+ id: generateUniqueId(),
+ type: widgetToDuplicate.type,
+ position: [
+ widgetToDuplicate.position[0] + 0.5, // Slightly shift position
+ widgetToDuplicate.position[1],
+ widgetToDuplicate.position[2] + 0.5,
+ ] as [number, number, number],
+ };
+ let add3dWidget = {
+ organization,
+ widget: newWidget,
+ zoneId: selectedZone.zoneId
+ };
+ // if (visualizationSocket) {
+ // visualizationSocket.emit("v2:viz-3D-widget:add", add3dWidget);
+ // }
+ addWidget(selectedZone.zoneId, newWidget);
+ setRightSelect(null);
+ setRightClickSelected(null);
+ }
+ if (rightSelect === "Delete") {
+ let deleteWidget = {
+ organization,
+ widgetId: rightClickSelected,
+ zoneId: selectedZone.zoneId
+ };
+ // if (visualizationSocket) {
+ // visualizationSocket.emit("v2:viz-3D-widget:delete", deleteWidget);
+ // }
+ setZoneWidgetData(selectedZone.zoneId, activeZoneWidgets.filter(w => w.id !== rightClickSelected));
+ setRightClickSelected(null);
+ setRightSelect(null);
+ }
+ if (rightSelect === "Horizontal Move") {
+
+ }
+ if (rightSelect === "Vertical Move") {
+
+ }
+
+ }, [rightSelect, rightClickSelected]);
+
+ useEffect(() => {
+ const handleMouseMove = (event: MouseEvent) => {
+ if (!rightClickSelected || !rightSelect) return;
+
+
+ const selectedZone = Object.keys(zoneWidgetData).find(zoneId =>
+ zoneWidgetData[zoneId].some(widget => widget.id === rightClickSelected)
+ );
+ if (!selectedZone) return;
+
+ const selectedWidget = zoneWidgetData[selectedZone].find(widget => widget.id === rightClickSelected);
+ if (!selectedWidget) return;
+
+ const rect = gl.domElement.getBoundingClientRect();
+ mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
+ mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
+
+ raycaster.setFromCamera(mouse, camera);
+
+ if (rightSelect === "Horizontal Move" && raycaster.ray.intersectPlane(plane.current, planeIntersect.current)) {
+
+ updateWidgetPosition(selectedZone, rightClickSelected, [
+ planeIntersect.current.x,
+ selectedWidget.position[1],
+ planeIntersect.current.z
+ ]);
+ }
+
+ if (rightSelect === "Vertical Move") {
+ if (raycaster.ray.intersectPlane(verticalPlane.current, planeIntersect.current)) {
+ updateWidgetPosition(selectedZone, rightClickSelected, [
+ selectedWidget.position[0],
+ planeIntersect.current.y, // Ensure Y value updates correctly
+ selectedWidget.position[2]
+ ]);
+ } else {
+ console.log("No Intersection with Vertical Plane");
+ }
+ }
+ };
+
+ const handleMouseUp = () => {
+
+ if (rightClickSelected && (rightSelect === "Horizontal Move" || rightSelect === "Vertical Move")) {
+
+ setTimeout(() => {
+ setRightClickSelected(null);
+ setRightSelect(null);
+ }, 50);
+ }
+ };
+
+ // Attach events to window instead of gl.domElement
+ window.addEventListener("mousemove", handleMouseMove);
+ window.addEventListener("mouseup", handleMouseUp);
+
+ return () => {
+ window.removeEventListener("mousemove", handleMouseMove);
+ window.removeEventListener("mouseup", handleMouseUp);
+ };
+ }, [rightClickSelected, rightSelect, zoneWidgetData, gl]);
+
+
+
+
return (
<>
{activeZoneWidgets.map(({ id, type, position }) => {
- console.log('Typeeeeeeeeeeee',type);
+ const handleRightClick = (event: React.MouseEvent) => {
+ event.preventDefault();
+ setRightClickSelected(id)
+ };
switch (type) {
case "ui-Widget 1":
- return
;
+ return
;
case "ui-Widget 2":
- return
;
+ return
;
case "ui-Widget 3":
- return
;
+ return
;
case "ui-Widget 4":
- return
;
+ return
;
default:
return null;
}
})}
+
>
);
}
diff --git a/app/src/components/ui/componets/RealTimeVisulization.tsx b/app/src/components/ui/componets/RealTimeVisulization.tsx
index 619cbb0..915e3b3 100644
--- a/app/src/components/ui/componets/RealTimeVisulization.tsx
+++ b/app/src/components/ui/componets/RealTimeVisulization.tsx
@@ -23,6 +23,8 @@ import SocketRealTimeViz from "../../../modules/visualization/realTimeVizSocket.
import RenderOverlay from "../../templates/Overlay";
import ConfirmationPopup from "../../layout/confirmationPopup/ConfirmationPopup";
import DroppedObjects from "./DroppedFloatingWidgets";
+import EditWidgetOption from "../menu/EditWidgetOption";
+import { useRightClickSelected } from "../../../store/useZone3DWidgetStore";
type Side = "top" | "bottom" | "left" | "right";
@@ -55,8 +57,9 @@ const RealTimeVisulization: React.FC = () => {
const [droppedObjects, setDroppedObjects] = useState
([]);
const [zonesData, setZonesData] = useState({});
const { selectedZone, setSelectedZone } = useSelectedZoneStore();
- const { zones } = useZones();
+
+ const { rightClickSelected, setRightClickSelected } = useRightClickSelected()
const [openConfirmationPopup, setOpenConfirmationPopup] = useState(false);
const [floatingWidgets, setFloatingWidgets] = useState<
@@ -93,7 +96,7 @@ const RealTimeVisulization: React.FC = () => {
{}
);
setZonesData(formattedData);
- } catch (error) {}
+ } catch (error) { }
}
GetZoneData();
@@ -178,7 +181,6 @@ const RealTimeVisulization: React.FC = () => {
.getState()
.addObject(selectedZone.zoneName, newObject);
// }
-
// Update floating widgets state
setFloatingWidgets((prevWidgets) => ({
...prevWidgets,
@@ -192,9 +194,10 @@ const RealTimeVisulization: React.FC = () => {
],
},
}));
- } catch (error) {}
+ } catch (error) { }
};
+ function handleRightClickSel(){}
return (
{
left: isPlaying || activeModule !== "visualization" ? "0%" : "",
}}
>
- {/*
-
- */}
{openConfirmationPopup && (
{
{activeModule === "visualization" && selectedZone.zoneName !== "" && }
{activeModule === "visualization" && }
- {/* */}
- {/*
-
- */}
+
+ {activeModule === "visualization" && widgetSubOption === "3D" && rightClickSelected && }
+
{activeModule === "visualization" && (
<>
{
-// const { getTemplate } = useTemplateStore.getState();
-// const { setSelectedZone } = useSelectedZoneStore.getState();
-
-// // Find the template by ID
-// const template: Template | undefined = getTemplate(templateId);
-
-// if (!template) {
-// console.error("Template not found!");
-// return;
-// }
-
-// // Update the selected zone with the template data
-// setSelectedZone((prev) => ({
-// ...prev,
-// panelOrder: template.panelOrder,
-// activeSides: Array.from(new Set([...prev.activeSides, ...template.panelOrder])),
-// widgets: template.widgets, // Keep widget structure the same
-// }));
-
-// console.log("Dropped template applied:", template);
-// };
diff --git a/app/src/components/ui/menu/EditWidgetOption.tsx b/app/src/components/ui/menu/EditWidgetOption.tsx
index 9ef67af..ce5261a 100644
--- a/app/src/components/ui/menu/EditWidgetOption.tsx
+++ b/app/src/components/ui/menu/EditWidgetOption.tsx
@@ -1,15 +1,26 @@
-import React from "react";
+import React, { useEffect } from "react";
+import { useLeftData, useRightSelected, useTopData } from "../../../store/useZone3DWidgetStore";
interface EditWidgetOptionProps {
options: string[];
}
const EditWidgetOption: React.FC = ({ options }) => {
+ const { top, setTop } = useTopData()
+ const { left, setLeft } = useLeftData()
+ const { rightSelect, setRightSelect } = useRightSelected()
+
+ useEffect(() => {
+
+ console.log('left: ', left);
+ console.log('top: ', top);
+ }, [top, left])
+
return (
-
+
{options.map((option, index) => (
-
+
setRightSelect(option)}>
{option}
))}
diff --git a/app/src/store/store.ts b/app/src/store/store.ts
index 87f937c..bd903f2 100644
--- a/app/src/store/store.ts
+++ b/app/src/store/store.ts
@@ -12,7 +12,7 @@ export const useSocketStore = create
((set: any, get: any) => ({
}
const socket = io(
- `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}`,
+ `http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
{
reconnection: false,
auth: { email, organization },
diff --git a/app/src/store/useZone3DWidgetStore.ts b/app/src/store/useZone3DWidgetStore.ts
index fbb8e74..850623f 100644
--- a/app/src/store/useZone3DWidgetStore.ts
+++ b/app/src/store/useZone3DWidgetStore.ts
@@ -1,33 +1,77 @@
+
import { create } from "zustand";
type WidgetData = {
- id: string;
- type: string;
- position: [number, number, number];
+ id: string;
+ type: string;
+ position: [number, number, number];
+ tempPosition?: [number, number, number];
};
type ZoneWidgetStore = {
- zoneWidgetData: Record;
- setZoneWidgetData: (zoneId: string, widgets: WidgetData[]) => void;
- addWidget: (zoneId: string, widget: WidgetData) => void;
+ zoneWidgetData: Record;
+ setZoneWidgetData: (zoneId: string, widgets: WidgetData[]) => void;
+ addWidget: (zoneId: string, widget: WidgetData) => void;
+ updateWidgetPosition: (zoneId: string, widgetId: string, newPosition: [number, number, number]) => void;
};
export const useZoneWidgetStore = create((set) => ({
- zoneWidgetData: {},
-
- setZoneWidgetData: (zoneId, widgets) =>
- set((state) => ({
- zoneWidgetData: {
- ...state.zoneWidgetData,
- [zoneId]: widgets,
- },
- })),
-
- addWidget: (zoneId, widget) =>
- set((state) => ({
- zoneWidgetData: {
- ...state.zoneWidgetData,
- [zoneId]: [...(state.zoneWidgetData[zoneId] || []), widget],
- },
- })),
+ zoneWidgetData: {},
+
+ setZoneWidgetData: (zoneId, widgets) =>
+ set((state) => ({
+ zoneWidgetData: { ...state.zoneWidgetData, [zoneId]: widgets },
+ })),
+
+ addWidget: (zoneId, widget) =>
+ set((state) => ({
+ zoneWidgetData: {
+ ...state.zoneWidgetData,
+ [zoneId]: [...(state.zoneWidgetData[zoneId] || []), widget],
+ },
+ })),
+
+ updateWidgetPosition: (zoneId, widgetId, newPosition) =>
+ set((state) => {
+ const widgets = state.zoneWidgetData[zoneId] || [];
+ return {
+ zoneWidgetData: {
+ ...state.zoneWidgetData,
+ [zoneId]: widgets.map((widget) =>
+ widget.id === widgetId ? { ...widget, position: newPosition } : widget
+ ),
+ },
+ };
+ }),
+}));
+
+
+interface RightClickStore {
+ rightClickSelected: string | null;
+ setRightClickSelected: (x: string | null) => void;
+}
+
+export const useRightClickSelected = create((set) => ({
+ rightClickSelected: null, // Default to null
+ setRightClickSelected: (x) => set({ rightClickSelected: x }),
+}));
+
+export const useTopData = create((set: any) => ({
+ top: 0,
+ setTop: (x: any) => set({ top: x }),
+}));
+
+export const useLeftData = create((set: any) => ({
+ left: 0,
+ setLeft: (x: any) => set({ left: x }),
+}));
+
+interface RightSelectStore {
+ rightSelect: string | null;
+ setRightSelect: (x: string | null) => void;
+}
+
+export const useRightSelected = create((set) => ({
+ rightSelect: null, // Default state is null
+ setRightSelect: (x) => set({ rightSelect: x }),
}));
diff --git a/app/src/styles/pages/realTimeViz.scss b/app/src/styles/pages/realTimeViz.scss
index e64ec08..a79823c 100644
--- a/app/src/styles/pages/realTimeViz.scss
+++ b/app/src/styles/pages/realTimeViz.scss
@@ -716,11 +716,6 @@
}
-.editWidgetOptions-wrapper {
-
- height: 100vh;
- width: 100vw;
-}
.editWidgetOptions {
position: absolute;