diff --git a/app/src/assets/image/wallTextures/defaultTexture.jpg b/app/src/assets/image/wallTextures/defaultTexture.jpg new file mode 100644 index 0000000..97dfb91 Binary files /dev/null and b/app/src/assets/image/wallTextures/defaultTexture.jpg differ diff --git a/app/src/assets/image/wallTextures/wallTexture.png b/app/src/assets/image/wallTextures/wallTexture.png new file mode 100644 index 0000000..d3a7a0a Binary files /dev/null and b/app/src/assets/image/wallTextures/wallTexture.png differ diff --git a/app/src/components/layout/scenes/MainScene.tsx b/app/src/components/layout/scenes/MainScene.tsx index b15f28f..10894eb 100644 --- a/app/src/components/layout/scenes/MainScene.tsx +++ b/app/src/components/layout/scenes/MainScene.tsx @@ -1,44 +1,52 @@ -import React from 'react' -import { useLoadingProgress, useSaveVersion, useSocketStore, useWidgetSubOption } from '../../../store/builder/store'; -import useModuleStore, { useThreeDStore } from '../../../store/useModuleStore'; -import { usePlayButtonStore } from '../../../store/usePlayButtonStore'; -import { useSelectedZoneStore } from '../../../store/visualization/useZoneStore'; -import { useFloatingWidget } from '../../../store/visualization/useDroppedObjectsStore'; -import { useSelectedUserStore } from '../../../store/collaboration/useCollabStore'; -import KeyPressListener from '../../../utils/shortcutkeys/handleShortcutKeys'; -import LoadingPage from '../../templates/LoadingPage'; -import ModuleToggle from '../../ui/ModuleToggle'; -import SideBarLeft from '../sidebarLeft/SideBarLeft'; -import SideBarRight from '../sidebarRight/SideBarRight'; -import RealTimeVisulization from '../../../modules/visualization/RealTimeVisulization'; -import MarketPlace from '../../../modules/market/MarketPlace'; -import Tools from '../../ui/Tools'; -import SimulationPlayer from '../../ui/simulation/simulationPlayer'; -import ControlsPlayer from '../controls/ControlsPlayer'; -import SelectFloorPlan from '../../temporary/SelectFloorPlan'; -import { createHandleDrop } from '../../../modules/visualization/functions/handleUiDrop'; -import Scene from '../../../modules/scene/scene'; -import { useComparisonProduct, useMainProduct } from '../../../store/simulation/useSimulationStore'; -import { useProductContext } from '../../../modules/simulation/products/productContext'; -import { useProductStore } from '../../../store/simulation/useProductStore'; -import RegularDropDown from '../../ui/inputs/RegularDropDown'; +import React from "react"; +import { + useLoadingProgress, + useSaveVersion, + useSocketStore, + useWidgetSubOption, +} from "../../../store/builder/store"; +import useModuleStore, { useThreeDStore } from "../../../store/useModuleStore"; +import { usePlayButtonStore } from "../../../store/usePlayButtonStore"; +import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore"; +import { useFloatingWidget } from "../../../store/visualization/useDroppedObjectsStore"; +import { useSelectedUserStore } from "../../../store/collaboration/useCollabStore"; +import KeyPressListener from "../../../utils/shortcutkeys/handleShortcutKeys"; +import LoadingPage from "../../templates/LoadingPage"; +import ModuleToggle from "../../ui/ModuleToggle"; +import SideBarLeft from "../sidebarLeft/SideBarLeft"; +import SideBarRight from "../sidebarRight/SideBarRight"; +import RealTimeVisulization from "../../../modules/visualization/RealTimeVisulization"; +import MarketPlace from "../../../modules/market/MarketPlace"; +import Tools from "../../ui/Tools"; +import SimulationPlayer from "../../ui/simulation/simulationPlayer"; +import ControlsPlayer from "../controls/ControlsPlayer"; +import SelectFloorPlan from "../../temporary/SelectFloorPlan"; +import { createHandleDrop } from "../../../modules/visualization/functions/handleUiDrop"; +import Scene from "../../../modules/scene/scene"; +import { + useComparisonProduct, + useMainProduct, +} from "../../../store/simulation/useSimulationStore"; +import { useProductContext } from "../../../modules/simulation/products/productContext"; +import { useProductStore } from "../../../store/simulation/useProductStore"; +import RegularDropDown from "../../ui/inputs/RegularDropDown"; function MainScene() { - const { products } = useProductStore(); - const { setMainProduct } = useMainProduct(); - const { selectedProductStore } = useProductContext(); - const { selectedProduct } = selectedProductStore(); - const { isVersionSaved } = useSaveVersion(); - const { activeModule } = useModuleStore(); - const { selectedUser } = useSelectedUserStore(); - const { loadingProgress } = useLoadingProgress(); - const { toggleThreeD } = useThreeDStore(); - const { isPlaying } = usePlayButtonStore(); - const { widgetSubOption } = useWidgetSubOption(); - const { visualizationSocket } = useSocketStore(); - const { selectedZone } = useSelectedZoneStore(); - const { setFloatingWidget } = useFloatingWidget(); - const { comparisonProduct } = useComparisonProduct(); + const { products } = useProductStore(); + const { setMainProduct } = useMainProduct(); + const { selectedProductStore } = useProductContext(); + const { selectedProduct } = selectedProductStore(); + const { isVersionSaved } = useSaveVersion(); + const { activeModule } = useModuleStore(); + const { selectedUser } = useSelectedUserStore(); + const { loadingProgress } = useLoadingProgress(); + const { toggleThreeD } = useThreeDStore(); + const { isPlaying } = usePlayButtonStore(); + const { widgetSubOption } = useWidgetSubOption(); + const { visualizationSocket } = useSocketStore(); + const { selectedZone } = useSelectedZoneStore(); + const { setFloatingWidget } = useFloatingWidget(); + const { comparisonProduct } = useComparisonProduct(); const handleSelectLayout = (option: string) => { const product = products.find((product) => product.productName === option); @@ -47,68 +55,71 @@ function MainScene() { } }; - return ( + return ( + <> + {!selectedUser && ( <> - {!selectedUser && ( - <> - - {loadingProgress > 0 && } - {!isPlaying && ( - <> - {toggleThreeD && } - - - - )} - - {activeModule === "market" && } - {activeModule !== "market" && !isPlaying && !isVersionSaved && ( - - )} - {(isPlaying || comparisonProduct !== null) && activeModule === "simulation" && } - {(isPlaying || comparisonProduct !== null) && activeModule !== "simulation" && } + + {loadingProgress > 0 && } + {!isPlaying && ( + <> + {toggleThreeD && } + + + + )} + + {activeModule === "market" && } + {activeModule !== "market" && !isPlaying && !isVersionSaved && ( + + )} + {(isPlaying || comparisonProduct !== null) && + activeModule === "simulation" && + loadingProgress == 0 && } + {(isPlaying || comparisonProduct !== null) && + activeModule !== "simulation" && } - {/* remove this later */} - {activeModule === "builder" && !toggleThreeD && } - - )} -
- createHandleDrop({ - widgetSubOption, - visualizationSocket, - selectedZone, - setFloatingWidget, - event, - }) - } - onDragOver={(event) => event.preventDefault()} - > - -
- - {selectedProduct && isVersionSaved && !isPlaying && ( -
- l.productName)} // Pass layout names as options - onSelect={handleSelectLayout} - search={false} - /> -
- )} + {/* remove this later */} + {activeModule === "builder" && !toggleThreeD && } - ) + )} +
+ createHandleDrop({ + widgetSubOption, + visualizationSocket, + selectedZone, + setFloatingWidget, + event, + }) + } + onDragOver={(event) => event.preventDefault()} + > + +
+ + {selectedProduct && isVersionSaved && !isPlaying && ( +
+ l.productName)} // Pass layout names as options + onSelect={handleSelectLayout} + search={false} + /> +
+ )} + + ); } -export default MainScene \ No newline at end of file +export default MainScene; diff --git a/app/src/components/layout/sidebarRight/properties/eventProperties/WallProperties.tsx b/app/src/components/layout/sidebarRight/properties/eventProperties/WallProperties.tsx new file mode 100644 index 0000000..ee1d87b --- /dev/null +++ b/app/src/components/layout/sidebarRight/properties/eventProperties/WallProperties.tsx @@ -0,0 +1,213 @@ +import { useEffect, useState } from "react"; +import InputWithDropDown from "../../../../ui/inputs/InputWithDropDown"; +import { AddIcon, RemoveIcon } from "../../../../icons/ExportCommonIcons"; + +// Texture Imports +import wallTexture1 from "../../../../../assets/image/wallTextures/wallTexture.png"; +import defaultTexture from "../../../../../assets/image/wallTextures/defaultTexture.jpg"; + +// Define Material type +type Material = { + texture: string; + textureName: string; +}; + +// Initial and default material +const initialMaterial: Material = { + texture: wallTexture1, + textureName: "Grunge Concrete Wall", +}; + +const defaultMaterial: Material = { + texture: defaultTexture, + textureName: "Default Material", +}; + +const WallProperties = () => { + const [wallProperties, setWallProperties] = useState({ + height: "10", + thickness: "10", + length: "10", + }); + + const [activeSide, setActiveSide] = useState<"side1" | "side2">("side1"); + + const [materials, setMaterials] = useState([initialMaterial]); + + const [selectedMaterials, setSelectedMaterials] = useState<{ + side1: Material | null; + side2: Material | null; + }>({ + side1: null, + side2: null, + }); + + // Select initial material for both sides on mount + useEffect(() => { + setSelectedMaterials({ + side1: initialMaterial, + side2: initialMaterial, + }); + }, []); + + const handleInputChange = ( + key: keyof typeof wallProperties, + newValue: string + ) => { + setWallProperties((prev) => ({ + ...prev, + [key]: newValue, + })); + }; + + const handleAddMaterial = () => { + const newMaterial: Material = { + texture: defaultMaterial.texture, + textureName: `Material ${materials.length + 1}`, + }; + setMaterials([...materials, newMaterial]); + }; + + const handleSelectMaterial = (material: Material) => { + setSelectedMaterials((prev) => ({ + ...prev, + [activeSide]: material, + })); + }; + + const handleRemoveMaterial = (index: number) => { + const updatedMaterials = materials.filter((_, i) => i !== index); + + // Ensure there's always at least one material + const newMaterials = + updatedMaterials.length === 0 ? [defaultMaterial] : updatedMaterials; + setMaterials(newMaterials); + + // Deselect the material if it's the one removed + setSelectedMaterials((prev) => { + const updated = { ...prev }; + ["side1", "side2"].forEach((side) => { + if ( + updated[side as "side1" | "side2"]?.texture === + materials[index].texture + ) { + updated[side as "side1" | "side2"] = defaultMaterial; + } + }); + return updated; + }); + }; + + return ( +
+
Wall
+
+ handleInputChange("height", val)} + /> + handleInputChange("thickness", val)} + /> + handleInputChange("length", val)} + /> +
+ +
+
+
Materials
+ +
+ +
+
+
setActiveSide("side1")} + > +
Side 1
+
+ {selectedMaterials.side1 && ( + {selectedMaterials.side1.textureName} + )} +
+
+ +
setActiveSide("side2")} + > +
Side 2
+
+ {selectedMaterials.side2 && ( + {selectedMaterials.side2.textureName} + )} +
+
+
+ +
+ {selectedMaterials[activeSide] && ( + {selectedMaterials[activeSide]!.textureName} + )} +
+
+ +
+ {materials.length === 0 ? ( +
No materials added yet.
+ ) : ( +
+ {materials.map((material, index) => ( +
handleSelectMaterial(material)} + > +
+
+ {material.textureName} +
+
{material.textureName}
+
+
{ + e.stopPropagation(); + handleRemoveMaterial(index); + }} + > + +
+
+ ))} +
+ )} +
+
+
+ ); +}; + +export default WallProperties; diff --git a/app/src/components/templates/LoadingPage.tsx b/app/src/components/templates/LoadingPage.tsx index 329c19f..7e25c51 100644 --- a/app/src/components/templates/LoadingPage.tsx +++ b/app/src/components/templates/LoadingPage.tsx @@ -4,6 +4,7 @@ import { LogoIconLarge } from "../icons/Logo"; import { useParams } from "react-router-dom"; import { useProjectName } from "../../store/builder/store"; import { getAllProjects } from "../../services/dashboard/getAllProjects"; +import { useComparisonProduct } from "../../store/simulation/useSimulationStore"; interface LoadingPageProps { progress: number; // Expect progress as a percentage (0-100) @@ -12,6 +13,8 @@ interface LoadingPageProps { const LoadingPage: React.FC = ({ progress }) => { const { projectName, setProjectName } = useProjectName(); const { projectId } = useParams(); + const { comparisonProduct } = useComparisonProduct(); + const validatedProgress = Math.min(100, Math.max(0, progress)); const generateThumbnail = async () => { const email = localStorage.getItem("email"); @@ -30,25 +33,24 @@ const LoadingPage: React.FC = ({ progress }) => { const domainParts = emailParts[1].split("."); const Organization = domainParts[0]; - const projects = await getAllProjects( - userId, Organization + const projects = await getAllProjects(userId, Organization); + const filterProject = projects?.Projects.find( + (val: any) => val.projectUuid === projectId || val._id === projectId ); - const filterProject = projects?.Projects.find((val: any) => val.projectUuid === projectId || val._id - === projectId) - setProjectName(filterProject.projectName) - - } - catch { - - } - } + setProjectName(filterProject.projectName); + } catch {} + }; useEffect(() => { generateThumbnail(); }, []); return ( -
+
{projectName}
diff --git a/app/src/components/ui/compareVersion/CompareLayOut.tsx b/app/src/components/ui/compareVersion/CompareLayOut.tsx index 7cdba4b..6cce453 100644 --- a/app/src/components/ui/compareVersion/CompareLayOut.tsx +++ b/app/src/components/ui/compareVersion/CompareLayOut.tsx @@ -4,7 +4,10 @@ import { LayoutIcon, ResizerIcon, } from "../../icons/SimulationIcons"; -import { useLoadingProgress, useSaveVersion } from "../../../store/builder/store"; +import { + useLoadingProgress, + useSaveVersion, +} from "../../../store/builder/store"; import Search from "../inputs/Search"; import OuterClick from "../../../utils/outerClick"; import { useProductStore } from "../../../store/simulation/useProductStore"; @@ -13,7 +16,8 @@ import { useComparisonProduct } from "../../../store/simulation/useSimulationSto import { usePauseButtonStore, usePlayButtonStore } from "../../../store/usePlayButtonStore"; const CompareLayOut = () => { - const { comparisonProduct, setComparisonProduct, clearComparisonProduct } = useComparisonProduct(); + const { comparisonProduct, setComparisonProduct, clearComparisonProduct } = + useComparisonProduct(); const { products } = useProductStore(); const { setLoadingProgress } = useLoadingProgress(); const [width, setWidth] = useState("50vw"); @@ -23,6 +27,7 @@ const CompareLayOut = () => { const startWidthRef = useRef(0); const startXRef = useRef(0); const { setIsVersionSaved } = useSaveVersion(); + const { loadingProgress } = useLoadingProgress(); const { setIsPlaying } = usePlayButtonStore(); const { setIsPaused } = usePauseButtonStore(); @@ -124,14 +129,16 @@ const CompareLayOut = () => { ref={wrapperRef} style={{ width }} > - + {loadingProgress == 0 && ( + + )}
{comparisonProduct && (
@@ -158,7 +165,7 @@ const CompareLayOut = () => { {showLayoutDropdown && (
Layouts
- { }} /> + {}} />
{products.map((layout) => (