diff --git a/app/src/components/icons/SimulationIcons.tsx b/app/src/components/icons/SimulationIcons.tsx index 4d9657a..709e268 100644 --- a/app/src/components/icons/SimulationIcons.tsx +++ b/app/src/components/icons/SimulationIcons.tsx @@ -386,3 +386,452 @@ export function StorageCapacityIcon() { ); } + +export function CompareLayoutIcon() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export const ResizerIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + ); +}; + +export const LayoutIcon = () => { + return ( + + + + + + ); +}; diff --git a/app/src/components/layout/sidebarLeft/SideBarLeft.tsx b/app/src/components/layout/sidebarLeft/SideBarLeft.tsx index eb618ec..e50c76e 100644 --- a/app/src/components/layout/sidebarLeft/SideBarLeft.tsx +++ b/app/src/components/layout/sidebarLeft/SideBarLeft.tsx @@ -8,6 +8,7 @@ import useModuleStore from "../../../store/useModuleStore"; import Widgets from "./visualization/widgets/Widgets"; import Templates from "../../../modules/visualization/template/Templates"; import Search from "../../ui/inputs/Search"; +import { useSaveVersion } from "../../../store/builder/store"; const SideBarLeft: React.FC = () => { const [activeOption, setActiveOption] = useState("Widgets"); @@ -15,6 +16,8 @@ const SideBarLeft: React.FC = () => { const { toggleUILeft } = useToggleStore(); const { activeModule } = useModuleStore(); + const { isVersionSaved } = useSaveVersion(); + // Reset activeOption whenever activeModule changes useEffect(() => { setActiveOption("Outline"); @@ -31,7 +34,13 @@ const SideBarLeft: React.FC = () => { }; return ( -
+
{toggleUILeft && (
@@ -68,14 +77,18 @@ const SideBarLeft: React.FC = () => { } else { return ( <> - -
- {activeOption === "Outline" ? : } -
+ {!isVersionSaved && ( + <> + +
+ {activeOption === "Outline" ? : } +
+ + )} ); } diff --git a/app/src/components/layout/sidebarRight/SideBarRight.tsx b/app/src/components/layout/sidebarRight/SideBarRight.tsx index c027bdb..05774e2 100644 --- a/app/src/components/layout/sidebarRight/SideBarRight.tsx +++ b/app/src/components/layout/sidebarRight/SideBarRight.tsx @@ -14,6 +14,7 @@ import Visualization from "./visualization/Visualization"; import Analysis from "./analysis/Analysis"; import Simulations from "./simulation/Simulations"; import useVersionHistoryStore, { + useSaveVersion, useSelectedFloorItem, } from "../../../store/builder/store"; import { @@ -34,6 +35,7 @@ const SideBarRight: React.FC = () => { const { selectedEventData } = useSelectedEventData(); const { selectedEventSphere } = useSelectedEventSphere(); const { viewVersionHistory, setVersionHistory } = useVersionHistoryStore(); + const { isVersionSaved } = useSaveVersion(); // Reset activeList whenever activeModule changes useEffect(() => { @@ -60,10 +62,14 @@ const SideBarRight: React.FC = () => { return (
- {toggleUIRight && ( + {toggleUIRight && !isVersionSaved && (
{activeModule !== "simulation" && (
-
setComparePopUp(true)}> +
+
@@ -269,7 +284,7 @@ const Simulations: React.FC = () => { {comparePopUp && ( - + )}
diff --git a/app/src/components/ui/compare/CompareLayOut.tsx b/app/src/components/ui/compare/CompareLayOut.tsx new file mode 100644 index 0000000..5f85029 --- /dev/null +++ b/app/src/components/ui/compare/CompareLayOut.tsx @@ -0,0 +1,179 @@ +import React, { useState, useRef, useEffect } from "react"; +import { + CompareLayoutIcon, + LayoutIcon, + ResizerIcon, +} from "../../icons/SimulationIcons"; +import { useSaveVersion } from "../../../store/builder/store"; +import Search from "../inputs/Search"; +import OuterClick from "../../../utils/outerClick"; +import RegularDropDown from "../inputs/RegularDropDown"; + +interface Layout { + id: number; + name: string; +} +interface CompareLayoutProps { + dummyLayouts: Layout[]; +} + +const CompareLayOut: React.FC = ({ dummyLayouts }) => { + const [width, setWidth] = useState("50vw"); + const [isResizing, setIsResizing] = useState(false); + const [showLayoutDropdown, setShowLayoutDropdown] = useState(false); + const [selectedLayout, setSelectedLayout] = useState(null); // Track selected layout + const wrapperRef = useRef(null); + const startWidthRef = useRef(0); + const startXRef = useRef(0); + const { setIsVersionSaved } = useSaveVersion(); + + OuterClick({ + contextClassName: ["displayLayouts-container", "selectLayout"], + setMenuVisible: () => setShowLayoutDropdown(false), + }); + + const handleStartResizing = (e: React.MouseEvent) => { + e.preventDefault(); + setIsResizing(true); + startXRef.current = e.clientX; + if (wrapperRef.current) { + startWidthRef.current = wrapperRef.current.getBoundingClientRect().width; + } + }; + + const handleMouseMove = (e: MouseEvent) => { + if (!isResizing || !wrapperRef.current) return; + + const dx = startXRef.current - e.clientX; + const newWidthPx = startWidthRef.current + dx; + const viewportWidth = window.innerWidth; + const newWidthVw = (newWidthPx / viewportWidth) * 100; + + if (newWidthVw <= 10) { + setWidth("0px"); + } else if (newWidthVw <= 90) { + setWidth(`${newWidthPx}px`); + } + }; + + const handleMouseUp = () => { + if (!isResizing) return; + + if (wrapperRef.current) { + const finalWidthPx = wrapperRef.current.getBoundingClientRect().width; + const viewportWidth = window.innerWidth; + const finalWidthVw = (finalWidthPx / viewportWidth) * 100; + + if (finalWidthVw <= 10) { + setWidth("0px"); + setIsVersionSaved(false); + } else { + setWidth(`${finalWidthVw}vw`); + } + } + + setIsResizing(false); + }; + + useEffect(() => { + if (isResizing) { + window.addEventListener("mousemove", handleMouseMove); + window.addEventListener("mouseup", handleMouseUp); + document.body.classList.add("resizing-active"); + } + + return () => { + window.removeEventListener("mousemove", handleMouseMove); + window.removeEventListener("mouseup", handleMouseUp); + document.body.classList.remove("resizing-active"); + }; + }, [isResizing]); + + // Maintain proportional width on window resize + useEffect(() => { + const handleResize = () => { + if (!wrapperRef.current || isResizing) return; + + const currentWidth = wrapperRef.current.style.width; + if (currentWidth === "0px" || currentWidth.endsWith("vw")) return; + + const pxWidth = parseFloat(currentWidth); + const vwWidth = (pxWidth / window.innerWidth) * 100; + setWidth(`${vwWidth}vw`); + }; + + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); + }, [isResizing]); + + const handleSelectLayout = (option: string) => { + setSelectedLayout(option); // Set selected layout + console.log("Selected layout:", option); + }; + + return ( +
+
+
+ +
+ + {width !== "0px" && + !selectedLayout && ( // Show only if no layout selected +
+
+ +
+
Choose Layout to compare
+ + + {showLayoutDropdown && ( +
+
Layouts
+ {}} /> +
+ {dummyLayouts.map((layout) => ( + + ))} +
+
+ )} +
+ )} + + {/* Always show after layout is selected */} + {width !== "0px" && selectedLayout && ( +
+ l.name)} // Pass layout names as options + onSelect={handleSelectLayout} + search={false} + /> +
+ )} +
+
+ ); +}; + +export default CompareLayOut; diff --git a/app/src/modules/simulation/compare/compare.tsx b/app/src/components/ui/compare/compare.tsx similarity index 80% rename from app/src/modules/simulation/compare/compare.tsx rename to app/src/components/ui/compare/compare.tsx index 4582b30..4c7e724 100644 --- a/app/src/modules/simulation/compare/compare.tsx +++ b/app/src/components/ui/compare/compare.tsx @@ -1,10 +1,15 @@ -import React from "react"; -import { InfoIcon } from "../../../components/icons/ShortcutIcons"; -import { SaveDiskIcon } from "../../../components/icons/ExportCommonIcons"; +import React, { useState } from "react"; +import { InfoIcon } from "../../icons/ShortcutIcons"; +import { SaveDiskIcon } from "../../icons/ExportCommonIcons"; import { useCompareStore } from "../../../store/builder/store"; import OuterClick from "../../../utils/outerClick"; +import useToggleStore from "../../../store/useUIToggleStore"; -const ComparePopUp = () => { +interface ComparePopUpProps { + onClose: () => void; +} + +const ComparePopUp: React.FC = ({ onClose }) => { const { setComparePopUp } = useCompareStore(); OuterClick({ @@ -47,7 +52,9 @@ const ComparePopUp = () => {
-
Save & Continue
+
Replace Existing Version