diff --git a/app/package-lock.json b/app/package-lock.json index a75803e..0d4359a 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -14,6 +14,7 @@ "react-chartjs-2": "^5.3.0", "react-dom": "^19.0.0", "react-router-dom": "^7.3.0", + "socket.io-client": "^4.8.1", "zustand": "^5.0.3" }, "devDependencies": { @@ -1655,6 +1656,12 @@ "win32" ] }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, "node_modules/@types/axios": { "version": "0.14.4", "resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.4.tgz", @@ -2795,6 +2802,45 @@ "dev": true, "license": "ISC" }, + "node_modules/engine.io-client": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -3708,7 +3754,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -4607,6 +4652,68 @@ "node": ">=8" } }, + "node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -4996,6 +5103,35 @@ "node": ">=0.10.0" } }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/app/package.json b/app/package.json index 37cf89e..c77f6fc 100644 --- a/app/package.json +++ b/app/package.json @@ -16,6 +16,7 @@ "react-chartjs-2": "^5.3.0", "react-dom": "^19.0.0", "react-router-dom": "^7.3.0", + "socket.io-client": "^4.8.1", "zustand": "^5.0.3" }, "devDependencies": { diff --git a/app/src/components/ui/componets/AddButtons.tsx b/app/src/components/ui/componets/AddButtons.tsx index e1c238a..4ce789a 100644 --- a/app/src/components/ui/componets/AddButtons.tsx +++ b/app/src/components/ui/componets/AddButtons.tsx @@ -1,3 +1,199 @@ +// import React from "react"; +// import { +// CleanPannel, +// EyeIcon, +// LockIcon, +// } from "../../icons/RealTimeVisulationIcons"; + +// // Define the type for `Side` +// type Side = "top" | "bottom" | "left" | "right"; + +// // Define the type for the props passed to the Buttons component +// interface ButtonsProps { +// selectedZone: { +// zoneName: string; +// activeSides: Side[]; +// panelOrder: Side[]; +// lockedPanels: Side[]; +// widgets: { +// id: string; +// type: string; +// title: string; +// panel: Side; +// data: any; +// }[]; +// }; +// setSelectedZone: React.Dispatch< +// React.SetStateAction<{ +// zoneName: string; +// activeSides: Side[]; +// panelOrder: Side[]; +// lockedPanels: Side[]; +// widgets: { +// id: string; +// type: string; +// title: string; +// panel: Side; +// data: any; +// }[]; +// }> +// >; +// hiddenPanels: Side[]; // Add this prop for hidden panels +// setHiddenPanels: React.Dispatch>; // Add this prop for updating hidden panels +// } + +// const AddButtons: React.FC = ({ +// selectedZone, +// setSelectedZone, +// setHiddenPanels, +// hiddenPanels, +// }) => { +// // Local state to track hidden panels + +// // Function to toggle lock/unlock a panel +// const toggleLockPanel = (side: Side) => { +// const newLockedPanels = selectedZone.lockedPanels.includes(side) +// ? selectedZone.lockedPanels.filter((panel) => panel !== side) +// : [...selectedZone.lockedPanels, side]; + +// const updatedZone = { +// ...selectedZone, +// lockedPanels: newLockedPanels, +// }; + +// // Update the selectedZone state +// setSelectedZone(updatedZone); +// }; + +// // Function to toggle visibility of a panel +// const toggleVisibility = (side: Side) => { +// const isHidden = hiddenPanels.includes(side); +// if (isHidden) { +// // If the panel is already hidden, remove it from the hiddenPanels array +// setHiddenPanels(hiddenPanels.filter((panel) => panel !== side)); +// } else { +// // If the panel is visible, add it to the hiddenPanels array +// setHiddenPanels([...hiddenPanels, side]); +// } +// }; + +// // Function to clean all widgets from a panel +// const cleanPanel = (side: Side) => { +// const cleanedWidgets = selectedZone.widgets.filter( +// (widget) => widget.panel !== side +// ); + +// const updatedZone = { +// ...selectedZone, +// widgets: cleanedWidgets, +// }; + +// // Update the selectedZone state +// setSelectedZone(updatedZone); +// }; + +// // Function to handle "+" button click +// const handlePlusButtonClick = (side: Side) => { +// if (selectedZone.activeSides.includes(side)) { +// // If the panel is already active, remove all widgets and close the panel +// const cleanedWidgets = selectedZone.widgets.filter( +// (widget) => widget.panel !== side +// ); +// const newActiveSides = selectedZone.activeSides.filter((s) => s !== side); + +// const updatedZone = { +// ...selectedZone, +// widgets: cleanedWidgets, +// activeSides: newActiveSides, +// panelOrder: newActiveSides, +// }; + +// // Update the selectedZone state +// setSelectedZone(updatedZone); +// } else { +// // If the panel is not active, activate it +// const newActiveSides = [...selectedZone.activeSides, side]; + +// const updatedZone = { +// ...selectedZone, +// activeSides: newActiveSides, +// panelOrder: newActiveSides, +// }; + +// // Update the selectedZone state +// setSelectedZone(updatedZone); +// } +// }; + +// return ( +//
+// {(["top", "right", "bottom", "left"] as Side[]).map((side) => ( +//
+// {/* "+" Button */} +// + +// {/* Extra Buttons */} +// {selectedZone.activeSides.includes(side) && ( +//
+// {/* Hide Panel */} +//
toggleVisibility(side)} +// > +// +//
+ +// {/* Clean Panel */} +//
cleanPanel(side)} +// > +// +//
+ +// {/* Lock/Unlock Panel */} +//
toggleLockPanel(side)} +// > +// +//
+//
+// )} +//
+// ))} +//
+// ); +// }; + +// export default AddButtons; + + + + import React from "react"; import { CleanPannel, diff --git a/app/src/components/ui/componets/DisplayZone.tsx b/app/src/components/ui/componets/DisplayZone.tsx index 3999827..9833d89 100644 --- a/app/src/components/ui/componets/DisplayZone.tsx +++ b/app/src/components/ui/componets/DisplayZone.tsx @@ -1,188 +1,3 @@ -import React, { useEffect, useRef } from "react"; -import { Widget } from "../../../store/useWidgetStore"; - -// Define the type for `Side` -type Side = "top" | "bottom" | "left" | "right"; - -interface DisplayZoneProps { - zonesData: { - [key: string]: { - zoneId: string; - activeSides: Side[]; - panelOrder: Side[]; - lockedPanels: Side[]; - widgets: Widget[]; - }; - }; - selectedZone: { - zoneId: string; - zoneName: string; - activeSides: Side[]; - panelOrder: Side[]; - lockedPanels: Side[]; - widgets: { - id: string; - type: string; - title: string; - panel: Side; - data: any; - }[]; - }; - setSelectedZone: React.Dispatch< - React.SetStateAction<{ - zoneId: string; - zoneName: string; - activeSides: Side[]; - panelOrder: Side[]; - lockedPanels: Side[]; - widgets: { - id: string; - type: string; - title: string; - panel: Side; - data: any; - }[]; - }> - >; -} - -const DisplayZone: React.FC = ({ - zonesData, - selectedZone, - setSelectedZone, -}) => { - // Ref for the container element - const containerRef = useRef(null); - - // Example state for selectedOption and options (adjust based on your actual use case) - const [selectedOption, setSelectedOption] = React.useState( - null - ); - console.log('setSelectedOption: ', setSelectedOption); - const [options, setOptions] = React.useState([]); - console.log('setOptions: ', setOptions); - - // Scroll to the selected option when it changes - useEffect(() => { - const container = containerRef.current; - - if (container && selectedOption) { - // Handle scrolling to the selected option - const index = options.findIndex((option) => { - const formattedOption = formatOptionName(option); - const selectedFormattedOption = - selectedOption?.split("_")[1] || selectedOption; - return formattedOption === selectedFormattedOption; - }); - - if (index !== -1) { - const optionElement = container.children[index] as HTMLElement; - if (optionElement) { - optionElement.scrollIntoView({ - behavior: "smooth", - block: "nearest", - inline: "center", - }); - } - } - } - }, [selectedOption, options]); - - useEffect(() => { - const container = containerRef.current; - - const handleWheel = (event: WheelEvent) => { - event.preventDefault(); - if (container) { - container.scrollBy({ - left: event.deltaY * 2, // Adjust the multiplier for faster scrolling - behavior: "smooth", - }); - } - }; - - let isDragging = false; - let startX: number; - let scrollLeft: number; - - const handleMouseDown = (event: MouseEvent) => { - isDragging = true; - startX = event.pageX - (container?.offsetLeft || 0); - scrollLeft = container?.scrollLeft || 0; - }; - - const handleMouseMove = (event: MouseEvent) => { - if (!isDragging || !container) return; - event.preventDefault(); - const x = event.pageX - (container.offsetLeft || 0); - const walk = (x - startX) * 2; // Adjust the multiplier for faster dragging - container.scrollLeft = scrollLeft - walk; - }; - - const handleMouseUp = () => { - isDragging = false; - }; - - const handleMouseLeave = () => { - isDragging = false; - }; - - if (container) { - container.addEventListener("wheel", handleWheel, { passive: false }); - container.addEventListener("mousedown", handleMouseDown); - container.addEventListener("mousemove", handleMouseMove); - container.addEventListener("mouseup", handleMouseUp); - container.addEventListener("mouseleave", handleMouseLeave); - } - - return () => { - if (container) { - container.removeEventListener("wheel", handleWheel); - container.removeEventListener("mousedown", handleMouseDown); - container.removeEventListener("mousemove", handleMouseMove); - container.removeEventListener("mouseup", handleMouseUp); - container.removeEventListener("mouseleave", handleMouseLeave); - } - }; - }, []); - - // Helper function to format option names (customize as needed) - const formatOptionName = (option: string): string => { - // Replace underscores with spaces and capitalize the first letter - return option.replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase()); - }; - - return ( -
- {Object.keys(zonesData).map((zoneName, index) => ( -
{ - setSelectedZone({ - zoneName, - ...zonesData[zoneName], - }); - }} - > - {zoneName} -
- ))} -
- ); -}; - -export default DisplayZone; - - - // import React, { useEffect, useRef } from "react"; // import { Widget } from "../../../store/useWidgetStore"; @@ -191,11 +6,13 @@ export default DisplayZone; // interface DisplayZoneProps { // zonesData: { -// _id: string; -// zoneName: string; -// zoneUUID: string; -// sceneID: string; -// }[]; +// [key: string]: { +// activeSides: Side[]; +// panelOrder: Side[]; +// lockedPanels: Side[]; +// widgets: Widget[]; +// }; +// }; // selectedZone: { // zoneName: string; // activeSides: Side[]; @@ -339,24 +156,237 @@ export default DisplayZone; // selectedZone.activeSides.includes("bottom") && "bottom" // }`} // > -// {zonesData && zonesData.length > 0 && zonesData?.map((zone, index) => ( +// {Object.keys(zonesData).map((zoneName, index) => ( //
{ -// // setSelectedZone({ -// // zoneName, -// // ...zonesData[zoneName], -// // }); -// // }} +// onClick={() => { +// setSelectedZone({ +// zoneName, +// ...zonesData[zoneName], +// }); +// }} // > -// {zone.zoneName} +// {zoneName} //
// ))} // // ); // }; -// export default DisplayZone; \ No newline at end of file +// export default DisplayZone; + + + +import React, { useEffect, useRef } from "react"; +import { Widget } from "../../../store/useWidgetStore"; +import axios from "axios"; + +// Define the type for `Side` +type Side = "top" | "bottom" | "left" | "right"; + +interface DisplayZoneProps { + zonesData: { + _id: string; + zoneName: string; + zoneUUID: string; + sceneID: string; + }[]; + selectedZone: { + zoneId: string; + zoneName: string; + activeSides: Side[]; + panelOrder: Side[]; + lockedPanels: Side[]; + widgets: { + id: string; + type: string; + title: string; + panel: Side; + data: any; + }[]; + }; + setSelectedZone: React.Dispatch< + React.SetStateAction<{ + zoneId: string; + zoneName: string; + activeSides: Side[]; + panelOrder: Side[]; + lockedPanels: Side[]; + widgets: { + id: string; + type: string; + title: string; + panel: Side; + data: any + }[]; + }> + >; +} + +const DisplayZone: React.FC = ({ + zonesData, + selectedZone, + setSelectedZone, +}) => { + // Ref for the container element + const containerRef = useRef(null); + + // Example state for selectedOption and options (adjust based on your actual use case) + const [selectedOption, setSelectedOption] = React.useState( + null + ); + console.log('setSelectedOption: ', setSelectedOption); + const [options, setOptions] = React.useState([]); + console.log('setOptions: ', setOptions); + + // Scroll to the selected option when it changes + useEffect(() => { + const container = containerRef.current; + + if (container && selectedOption) { + // Handle scrolling to the selected option + const index = options.findIndex((option) => { + const formattedOption = formatOptionName(option); + const selectedFormattedOption = + selectedOption?.split("_")[1] || selectedOption; + return formattedOption === selectedFormattedOption; + }); + + if (index !== -1) { + const optionElement = container.children[index] as HTMLElement; + if (optionElement) { + optionElement.scrollIntoView({ + behavior: "smooth", + block: "nearest", + inline: "center", + }); + } + } + } + }, [selectedOption, options]); + + useEffect(() => { + const container = containerRef.current; + + const handleWheel = (event: WheelEvent) => { + event.preventDefault(); + if (container) { + container.scrollBy({ + left: event.deltaY * 2, // Adjust the multiplier for faster scrolling + behavior: "smooth", + }); + } + }; + + + + let isDragging = false; + let startX: number; + let scrollLeft: number; + + const handleMouseDown = (event: MouseEvent) => { + isDragging = true; + startX = event.pageX - (container?.offsetLeft || 0); + scrollLeft = container?.scrollLeft || 0; + }; + + const handleMouseMove = (event: MouseEvent) => { + if (!isDragging || !container) return; + event.preventDefault(); + const x = event.pageX - (container.offsetLeft || 0); + const walk = (x - startX) * 2; // Adjust the multiplier for faster dragging + container.scrollLeft = scrollLeft - walk; + }; + + const handleMouseUp = () => { + isDragging = false; + }; + + const handleMouseLeave = () => { + isDragging = false; + }; + + if (container) { + container.addEventListener("wheel", handleWheel, { passive: false }); + container.addEventListener("mousedown", handleMouseDown); + container.addEventListener("mousemove", handleMouseMove); + container.addEventListener("mouseup", handleMouseUp); + container.addEventListener("mouseleave", handleMouseLeave); + } + + return () => { + if (container) { + container.removeEventListener("wheel", handleWheel); + container.removeEventListener("mousedown", handleMouseDown); + container.removeEventListener("mousemove", handleMouseMove); + container.removeEventListener("mouseup", handleMouseUp); + container.removeEventListener("mouseleave", handleMouseLeave); + } + }; + }, []); + + // Helper function to format option names (customize as needed) + const formatOptionName = (option: string): string => { + // Replace underscores with spaces and capitalize the first letter + return option.replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase()); + }; + + const fetchSelectedZone = async (selectedZoneId: string) => { + try { + // Send POST request to the server + const response = await axios.get('http://192.168.0.192:4000/fetchzonedetails', + { + params: { + zoneId: selectedZoneId + } + } + ); + + // Check the response and show a success message if needed + if (response.status === 200) { + console.log('broker details responce:', response.data); + setSelectedZone(response.data) + } else { + console.log('Unexpected response:', response); + } + + } catch (error) { + console.error('There was an error!', error); + // setZonesData([]) + } + }; + console.log(zonesData); + + return ( +
+ {zonesData && zonesData.length > 0 && zonesData?.map((zone, index) => ( +
{ + // setSelectedZone({ + // zoneName, + // ...zonesData[zoneName], + // }); + // }} + + onClick={() => { + fetchSelectedZone(zone._id) + }} + > + {zone.zoneName} +
+ ))} +
+ ); +}; + +export default DisplayZone; \ No newline at end of file diff --git a/app/src/components/ui/componets/Panel.tsx b/app/src/components/ui/componets/Panel.tsx index 2036ae8..86989fa 100644 --- a/app/src/components/ui/componets/Panel.tsx +++ b/app/src/components/ui/componets/Panel.tsx @@ -1,3 +1,209 @@ +// import React, { useEffect, useMemo, useRef, useState } from "react"; +// import { useWidgetStore } from "../../../store/useWidgetStore"; +// import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; +// import { DraggableWidget } from "./DraggableWidget"; + +// type Side = "top" | "bottom" | "left" | "right"; + +// interface Widget { +// id: string; +// type: string; +// title: string; +// panel: Side; +// data: any; +// } + +// interface PanelProps { +// selectedZone: { +// zoneName: string; +// activeSides: Side[]; +// panelOrder: Side[]; +// lockedPanels: Side[]; +// widgets: Widget[]; +// }; +// setSelectedZone: React.Dispatch< +// React.SetStateAction<{ +// zoneName: string; +// activeSides: Side[]; +// panelOrder: Side[]; +// lockedPanels: Side[]; +// widgets: Widget[]; +// }> +// >; +// } + +// const generateUniqueId = () => +// `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + +// const Panel: React.FC = ({ selectedZone, setSelectedZone }) => { +// const panelRefs = useRef<{ [side in Side]?: HTMLDivElement }>({}); +// const [panelDimensions, setPanelDimensions] = useState<{ +// [side in Side]?: { width: number; height: number }; +// }>({}); + +// const getPanelStyle = useMemo( +// () => (side: Side) => { +// const currentIndex = selectedZone.panelOrder.indexOf(side); +// const previousPanels = selectedZone.panelOrder.slice(0, currentIndex); +// const leftActive = previousPanels.includes("left"); +// const rightActive = previousPanels.includes("right"); +// const topActive = previousPanels.includes("top"); +// const bottomActive = previousPanels.includes("bottom"); + +// switch (side) { +// case "top": +// case "bottom": +// return { +// width: `calc(100% - ${ +// (leftActive ? 204 : 0) + (rightActive ? 204 : 0) +// }px)`, +// left: leftActive ? "204px" : "0", +// right: rightActive ? "204px" : "0", +// [side]: "0", +// height: "200px", +// }; +// case "left": +// case "right": +// return { +// height: `calc(100% - ${ +// (topActive ? 204 : 0) + (bottomActive ? 204 : 0) +// }px)`, +// top: topActive ? "204px" : "0", +// bottom: bottomActive ? "204px" : "0", +// [side]: "0", +// width: "200px", +// }; +// default: +// return {}; +// } +// }, +// [selectedZone.panelOrder] +// ); + +// const handleDrop = (e: React.DragEvent, panel: Side) => { +// e.preventDefault(); +// const { draggedAsset } = useWidgetStore.getState(); + +// if (!draggedAsset) return; +// if (isPanelLocked(panel)) return; + +// const currentWidgetsCount = getCurrentWidgetCount(panel); +// const maxCapacity = calculatePanelCapacity(panel); + +// if (currentWidgetsCount >= maxCapacity) return; + +// addWidgetToPanel(draggedAsset, panel); +// }; + +// // Helper functions +// const isPanelLocked = (panel: Side) => +// selectedZone.lockedPanels.includes(panel); + +// const getCurrentWidgetCount = (panel: Side) => +// selectedZone.widgets.filter(w => w.panel === panel).length; + +// const calculatePanelCapacity = (panel: Side) => { +// const CHART_WIDTH = 200; +// const CHART_HEIGHT = 200; +// const FALLBACK_HORIZONTAL_CAPACITY = 5; +// const FALLBACK_VERTICAL_CAPACITY = 3; + +// const dimensions = panelDimensions[panel]; +// if (!dimensions) { +// return panel === "top" || panel === "bottom" +// ? FALLBACK_HORIZONTAL_CAPACITY +// : FALLBACK_VERTICAL_CAPACITY; +// } + +// return panel === "top" || panel === "bottom" +// ? Math.floor(dimensions.width / CHART_WIDTH) +// : Math.floor(dimensions.height / CHART_HEIGHT); +// }; + +// const addWidgetToPanel = (asset: any, panel: Side) => { +// const newWidget = { +// ...asset, +// id: generateUniqueId(), +// panel, +// }; + +// setSelectedZone(prev => ({ +// ...prev, +// widgets: [...prev.widgets, newWidget] +// })); +// }; + +// useEffect(() => { +// const observers: ResizeObserver[] = []; +// const currentPanelRefs = panelRefs.current; + +// selectedZone.activeSides.forEach((side) => { +// const element = currentPanelRefs[side]; +// if (element) { +// const observer = new ResizeObserver((entries) => { +// for (const entry of entries) { +// const { width, height } = entry.contentRect; +// setPanelDimensions((prev) => ({ +// ...prev, +// [side]: { width, height }, +// })); +// } +// }); +// observer.observe(element); +// observers.push(observer); +// } +// }); + +// return () => { +// observers.forEach((observer) => observer.disconnect()); +// }; +// }, [selectedZone.activeSides]); + +// const { isPlaying } = usePlayButtonStore(); + +// return ( +// <> +// {selectedZone.activeSides.map((side) => ( +//
handleDrop(e, side)} +// onDragOver={(e) => e.preventDefault()} +// ref={(el) => { +// if (el) { +// panelRefs.current[side] = el; +// } else { +// delete panelRefs.current[side]; +// } +// }} +// > +//
+// <>{} +// {selectedZone.widgets +// .filter((w) => w.panel === side) +// .map((widget) => ( +// +// ))} +//
+//
+// ))} +// +// ); +// }; + +// export default Panel; + + + import React, { useEffect, useMemo, useRef, useState } from "react"; import { useWidgetStore } from "../../../store/useWidgetStore"; import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; @@ -203,3 +409,4 @@ const Panel: React.FC = ({ selectedZone, setSelectedZone }) => { }; export default Panel; + diff --git a/app/src/components/ui/componets/RealTimeVisulization.tsx b/app/src/components/ui/componets/RealTimeVisulization.tsx index 7f5b72d..f305419 100644 --- a/app/src/components/ui/componets/RealTimeVisulization.tsx +++ b/app/src/components/ui/componets/RealTimeVisulization.tsx @@ -1,123 +1,9 @@ -import React, { useEffect, useState, useRef } from "react"; -import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; -import Panel from "./Panel"; -import AddButtons from "./AddButtons"; -import { useSelectedZoneStore } from "../../../store/useZoneStore"; -import DisplayZone from "./DisplayZone"; - -type Side = "top" | "bottom" | "left" | "right"; - -interface Widget { - id: string; - type: string; - title: string; - panel: Side; - data: any; -} - -const RealTimeVisulization: React.FC = () => { - const [hiddenPanels, setHiddenPanels] = React.useState([]); - const containerRef = useRef(null); - const [zonesData, setZonesData] = useState<{ - [key: string]: { - zoneId: string; - activeSides: Side[]; - panelOrder: Side[]; - lockedPanels: Side[]; - widgets: Widget[]; - }; - }>({ - "Manufacturing unit": { - zoneId: "Manufacturing unit", - activeSides: [], - panelOrder: [], - lockedPanels: [], - widgets: [], - }, - "Assembly unit": { - zoneId: "Assembly unit", - activeSides: [], - panelOrder: [], - lockedPanels: [], - widgets: [], - }, - "Packing unit": { - zoneId: "Packing unit", - activeSides: [], - panelOrder: [], - lockedPanels: [], - widgets: [], - }, - Warehouse: { - zoneId: "Warehouse", - activeSides: [], - panelOrder: [], - lockedPanels: [], - widgets: [], - }, - Inventory: { - zoneId: "Inventory", - activeSides: [], - panelOrder: [], - lockedPanels: [], - widgets: [], - }, - }); - - const { isPlaying } = usePlayButtonStore(); - - const { selectedZone, setSelectedZone } = useSelectedZoneStore(); - useEffect(() => { - setZonesData((prev) => ({ - ...prev, - [selectedZone.zoneName]: selectedZone, - })); - }, [selectedZone]); - - return ( -
- - - {!isPlaying && ( - - )} - - -
- ); -}; - -export default RealTimeVisulization; - - - - - // import React, { useEffect, useState, useRef } from "react"; // import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; // import Panel from "./Panel"; // import AddButtons from "./AddButtons"; // import { useSelectedZoneStore } from "../../../store/useZoneStore"; // import DisplayZone from "./DisplayZone"; -// import axios from "axios"; // type Side = "top" | "bottom" | "left" | "right"; @@ -132,80 +18,45 @@ export default RealTimeVisulization; // const RealTimeVisulization: React.FC = () => { // const [hiddenPanels, setHiddenPanels] = React.useState([]); // const containerRef = useRef(null); -// // const [zonesData, setZonesData] = useState<{ -// // [key: string]: { -// // activeSides: Side[]; -// // panelOrder: Side[]; -// // lockedPanels: Side[]; -// // widgets: Widget[]; -// // }; -// // }>({ -// // "Manufacturing unit": { -// // activeSides: [], -// // panelOrder: [], -// // lockedPanels: [], -// // widgets: [], -// // }, -// // "Assembly unit": { -// // activeSides: [], -// // panelOrder: [], -// // lockedPanels: [], -// // widgets: [], -// // }, -// // "Packing unit": { -// // activeSides: [], -// // panelOrder: [], -// // lockedPanels: [], -// // widgets: [], -// // }, -// // Warehouse: { -// // activeSides: [], -// // panelOrder: [], -// // lockedPanels: [], -// // widgets: [], -// // }, -// // Inventory: { -// // activeSides: [], -// // panelOrder: [], -// // lockedPanels: [], -// // widgets: [], -// // }, -// // }); - // const [zonesData, setZonesData] = useState<{ -// _id: string; -// zoneName: string; -// zoneUUID: string; -// sceneID: string; -// }[]>([]); - -// useEffect(() => { -// const fetchZoneData = async () => { -// try { -// // Send POST request to the server -// const response = await axios.get('http://192.168.0.102:2000/zone_sets/6656cbf555be4ff11327fd7f?organization=organization', -// // { -// // params: { -// // sceneId:"123456789" -// // } -// // } -// ); - -// // Check the response and show a success message if needed -// if (response.status === 200) { -// console.log('broker details responce:', response.data); -// setZonesData(response.data) -// } else { -// console.log('Unexpected response:', response); -// } - -// } catch (error) { -// console.error('There was an error!', error); -// setZonesData([]) -// } +// [key: string]: { +// activeSides: Side[]; +// panelOrder: Side[]; +// lockedPanels: Side[]; +// widgets: Widget[]; // }; -// fetchZoneData(); -// }, []); +// }>({ +// "Manufacturing unit": { +// activeSides: [], +// panelOrder: [], +// lockedPanels: [], +// widgets: [], +// }, +// "Assembly unit": { +// activeSides: [], +// panelOrder: [], +// lockedPanels: [], +// widgets: [], +// }, +// "Packing unit": { +// activeSides: [], +// panelOrder: [], +// lockedPanels: [], +// widgets: [], +// }, +// Warehouse: { +// activeSides: [], +// panelOrder: [], +// lockedPanels: [], +// widgets: [], +// }, +// Inventory: { +// activeSides: [], +// panelOrder: [], +// lockedPanels: [], +// widgets: [], +// }, +// }); // const { isPlaying } = usePlayButtonStore(); @@ -250,3 +101,150 @@ export default RealTimeVisulization; // export default RealTimeVisulization; + + +import React, { useEffect, useState, useRef } from "react"; +import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; +import Panel from "./Panel"; +import AddButtons from "./AddButtons"; +import { useSelectedZoneStore } from "../../../store/useZoneStore"; +import DisplayZone from "./DisplayZone"; +import axios from "axios"; + +type Side = "top" | "bottom" | "left" | "right"; + +interface Widget { + id: string; + type: string; + title: string; + panel: Side; + data: any; +} + +const RealTimeVisulization: React.FC = () => { + const [hiddenPanels, setHiddenPanels] = React.useState([]); + const containerRef = useRef(null); + + const [zonesData, setZonesData] = useState<{ + _id: string; + zoneName: string; + zoneUUID: string; + sceneID: string; + }[]>([]); + // const [zonesData, setZonesData] = useState<{ + // [key: string]: { + // zoneId: string; + // activeSides: Side[]; + // panelOrder: Side[]; + // lockedPanels: Side[]; + // widgets: Widget[]; + // }; + // }>({ + // "Manufacturing unit": { + // zoneId: "Manufacturing unit", + // activeSides: [], + // panelOrder: [], + // lockedPanels: [], + // widgets: [], + // }, + // "Assembly unit": { + // zoneId: "Assembly unit", + // activeSides: [], + // panelOrder: [], + // lockedPanels: [], + // widgets: [], + // }, + // "Packing unit": { + // zoneId: "Packing unit", + // activeSides: [], + // panelOrder: [], + // lockedPanels: [], + // widgets: [], + // }, + // Warehouse: { + // zoneId: "Warehouse", + // activeSides: [], + // panelOrder: [], + // lockedPanels: [], + // widgets: [], + // }, + // Inventory: { + // zoneId: "Inventory", + // activeSides: [], + // panelOrder: [], + // lockedPanels: [], + // widgets: [], + // }, + // }); + + useEffect(() => { + const fetchZoneData = async () => { + try { + // Send POST request to the server + const response = await axios.get('http://192.168.0.192:4000/fetchzone', + // { + // params: { + // sceneId:"123456789" + // } + // } + ); + + // Check the response and show a success message if needed + if (response.status === 200) { + console.log('broker details responce:', response.data); + setZonesData(response.data) + } else { + console.log('Unexpected response:', response); + } + + } catch (error) { + console.error('There was an error!', error); + setZonesData([]) + } + }; + fetchZoneData(); + }, []); + + const { isPlaying } = usePlayButtonStore(); + + const { selectedZone, setSelectedZone } = useSelectedZoneStore(); + + // useEffect(() => { + // setZonesData((prev) => ({ + // ...prev, + // [selectedZone.zoneName]: selectedZone, + // })); + // }, [selectedZone]); + + return ( +
+ + + {!isPlaying && ( + + )} + + +
+ ); +}; + +export default RealTimeVisulization; \ No newline at end of file diff --git a/app/src/store/useZoneStore.ts b/app/src/store/useZoneStore.ts index 62996ae..cbf25b4 100644 --- a/app/src/store/useZoneStore.ts +++ b/app/src/store/useZoneStore.ts @@ -41,7 +41,60 @@ // })); +// import { create } from "zustand"; + +// type Side = "top" | "bottom" | "left" | "right"; + +// interface Widget { +// id: string; +// type: string; +// title: string; +// panel: Side; +// data: any; +// } + +// interface SelectedZoneState { +// zoneId: string; +// zoneName: string; +// activeSides: Side[]; +// panelOrder: Side[]; +// lockedPanels: Side[]; +// widgets: Widget[]; +// } + +// interface SelectedZoneStore { +// selectedZone: SelectedZoneState; +// setSelectedZone: (zone: Partial | ((prev: SelectedZoneState) => SelectedZoneState)) => void; +// } + +// export const useSelectedZoneStore = create((set) => ({ +// selectedZone: { +// zoneId:"", +// zoneName: "", +// activeSides: [], +// panelOrder: [], +// lockedPanels: [], +// widgets: [], +// }, +// setSelectedZone: (zone) => +// set((state) => { +// const newState = +// typeof zone === "function" +// ? zone(state.selectedZone) // Handle functional updates +// : { ...state.selectedZone, ...zone }; // Handle partial updates + +// console.log("Previous state:", state.selectedZone); +// console.log("Updated state:", newState); + +// return { selectedZone: newState }; +// }), +// })); + + import { create } from "zustand"; +import { io } from "socket.io-client"; + +const socket = io("http://192.168.0.192:4000"); type Side = "top" | "bottom" | "left" | "right"; @@ -69,7 +122,7 @@ interface SelectedZoneStore { export const useSelectedZoneStore = create((set) => ({ selectedZone: { - zoneId:"", + zoneId: "", zoneName: "", activeSides: [], panelOrder: [], @@ -80,12 +133,22 @@ export const useSelectedZoneStore = create((set) => ({ set((state) => { const newState = typeof zone === "function" - ? zone(state.selectedZone) // Handle functional updates - : { ...state.selectedZone, ...zone }; // Handle partial updates + ? zone(state.selectedZone) + : { ...state.selectedZone, ...zone }; console.log("Previous state:", state.selectedZone); console.log("Updated state:", newState); + // Send updates to the backend + socket.emit("updateZone", newState); + return { selectedZone: newState }; }), })); + +// Listen for backend updates +// socket.on("zoneUpdated", (updatedZone: SelectedZoneState) => { +// console.log("Received update from server:", updatedZone); +// useSelectedZoneStore.setState({ selectedZone: updatedZone }); +// }); +