v3-ui #98

Merged
Vishnu merged 51 commits from v3-ui into main 2025-06-10 06:46:08 +00:00
16 changed files with 546 additions and 194 deletions
Showing only changes of commit 3575f2bf73 - Show all commits

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,27 +1,35 @@
import React from 'react' import React from "react";
import { useLoadingProgress, useSaveVersion, useSocketStore, useWidgetSubOption } from '../../../store/builder/store'; import {
import useModuleStore, { useThreeDStore } from '../../../store/useModuleStore'; useLoadingProgress,
import { usePlayButtonStore } from '../../../store/usePlayButtonStore'; useSaveVersion,
import { useSelectedZoneStore } from '../../../store/visualization/useZoneStore'; useSocketStore,
import { useFloatingWidget } from '../../../store/visualization/useDroppedObjectsStore'; useWidgetSubOption,
import { useSelectedUserStore } from '../../../store/collaboration/useCollabStore'; } from "../../../store/builder/store";
import KeyPressListener from '../../../utils/shortcutkeys/handleShortcutKeys'; import useModuleStore, { useThreeDStore } from "../../../store/useModuleStore";
import LoadingPage from '../../templates/LoadingPage'; import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
import ModuleToggle from '../../ui/ModuleToggle'; import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
import SideBarLeft from '../sidebarLeft/SideBarLeft'; import { useFloatingWidget } from "../../../store/visualization/useDroppedObjectsStore";
import SideBarRight from '../sidebarRight/SideBarRight'; import { useSelectedUserStore } from "../../../store/collaboration/useCollabStore";
import RealTimeVisulization from '../../../modules/visualization/RealTimeVisulization'; import KeyPressListener from "../../../utils/shortcutkeys/handleShortcutKeys";
import MarketPlace from '../../../modules/market/MarketPlace'; import LoadingPage from "../../templates/LoadingPage";
import Tools from '../../ui/Tools'; import ModuleToggle from "../../ui/ModuleToggle";
import SimulationPlayer from '../../ui/simulation/simulationPlayer'; import SideBarLeft from "../sidebarLeft/SideBarLeft";
import ControlsPlayer from '../controls/ControlsPlayer'; import SideBarRight from "../sidebarRight/SideBarRight";
import SelectFloorPlan from '../../temporary/SelectFloorPlan'; import RealTimeVisulization from "../../../modules/visualization/RealTimeVisulization";
import { createHandleDrop } from '../../../modules/visualization/functions/handleUiDrop'; import MarketPlace from "../../../modules/market/MarketPlace";
import Scene from '../../../modules/scene/scene'; import Tools from "../../ui/Tools";
import { useComparisonProduct, useMainProduct } from '../../../store/simulation/useSimulationStore'; import SimulationPlayer from "../../ui/simulation/simulationPlayer";
import { useProductContext } from '../../../modules/simulation/products/productContext'; import ControlsPlayer from "../controls/ControlsPlayer";
import { useProductStore } from '../../../store/simulation/useProductStore'; import SelectFloorPlan from "../../temporary/SelectFloorPlan";
import RegularDropDown from '../../ui/inputs/RegularDropDown'; 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() { function MainScene() {
const { products } = useProductStore(); const { products } = useProductStore();
@ -65,8 +73,11 @@ function MainScene() {
{activeModule !== "market" && !isPlaying && !isVersionSaved && ( {activeModule !== "market" && !isPlaying && !isVersionSaved && (
<Tools /> <Tools />
)} )}
{(isPlaying || comparisonProduct !== null) && activeModule === "simulation" && <SimulationPlayer />} {(isPlaying || comparisonProduct !== null) &&
{(isPlaying || comparisonProduct !== null) && activeModule !== "simulation" && <ControlsPlayer />} activeModule === "simulation" &&
loadingProgress == 0 && <SimulationPlayer />}
{(isPlaying || comparisonProduct !== null) &&
activeModule !== "simulation" && <ControlsPlayer />}
{/* remove this later */} {/* remove this later */}
{activeModule === "builder" && !toggleThreeD && <SelectFloorPlan />} {activeModule === "builder" && !toggleThreeD && <SelectFloorPlan />}
@ -108,7 +119,7 @@ function MainScene() {
</div> </div>
)} )}
</> </>
) );
} }
export default MainScene export default MainScene;

View File

@ -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<Material[]>([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 (
<div className="wall-properties-container">
<div className="header">Wall</div>
<div className="wall-properties">
<InputWithDropDown
label="Height"
value={wallProperties.height}
onChange={(val) => handleInputChange("height", val)}
/>
<InputWithDropDown
label="Thickness"
value={wallProperties.thickness}
onChange={(val) => handleInputChange("thickness", val)}
/>
<InputWithDropDown
label="Length"
value={wallProperties.length}
onChange={(val) => handleInputChange("length", val)}
/>
</div>
<section>
<div className="header-wrapper">
<div className="header">Materials</div>
<button className="addMaterial" onClick={handleAddMaterial}>
<AddIcon />
</button>
</div>
<div className="material-preview">
<div className="sides-wrapper">
<div
className={`side-wrapper ${
activeSide === "side1" ? "active" : ""
}`}
onClick={() => setActiveSide("side1")}
>
<div className="label">Side 1</div>
<div className="texture-image">
{selectedMaterials.side1 && (
<img
src={selectedMaterials.side1.texture}
alt={selectedMaterials.side1.textureName}
/>
)}
</div>
</div>
<div
className={`side-wrapper ${
activeSide === "side2" ? "active" : ""
}`}
onClick={() => setActiveSide("side2")}
>
<div className="label">Side 2</div>
<div className="texture-image">
{selectedMaterials.side2 && (
<img
src={selectedMaterials.side2.texture}
alt={selectedMaterials.side2.textureName}
/>
)}
</div>
</div>
</div>
<div className="preview">
{selectedMaterials[activeSide] && (
<img
src={selectedMaterials[activeSide]!.texture}
alt={selectedMaterials[activeSide]!.textureName}
/>
)}
</div>
</div>
<div className="materials">
{materials.length === 0 ? (
<div className="no-materials">No materials added yet.</div>
) : (
<div className="material-container">
{materials.map((material, index) => (
<div
className="material-wrapper"
key={`${material.textureName}_${index}`}
onClick={() => handleSelectMaterial(material)}
>
<div className="material-property">
<div className="material-image">
<img src={material.texture} alt={material.textureName} />
</div>
<div className="material-name">{material.textureName}</div>
</div>
<div
className="delete-material"
onClick={(e) => {
e.stopPropagation();
handleRemoveMaterial(index);
}}
>
<RemoveIcon />
</div>
</div>
))}
</div>
)}
</div>
</section>
</div>
);
};
export default WallProperties;

View File

@ -4,6 +4,7 @@ import { LogoIconLarge } from "../icons/Logo";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { useProjectName } from "../../store/builder/store"; import { useProjectName } from "../../store/builder/store";
import { getAllProjects } from "../../services/dashboard/getAllProjects"; import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { useComparisonProduct } from "../../store/simulation/useSimulationStore";
interface LoadingPageProps { interface LoadingPageProps {
progress: number; // Expect progress as a percentage (0-100) progress: number; // Expect progress as a percentage (0-100)
@ -12,6 +13,8 @@ interface LoadingPageProps {
const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => { const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
const { projectName, setProjectName } = useProjectName(); const { projectName, setProjectName } = useProjectName();
const { projectId } = useParams(); const { projectId } = useParams();
const { comparisonProduct } = useComparisonProduct();
const validatedProgress = Math.min(100, Math.max(0, progress)); const validatedProgress = Math.min(100, Math.max(0, progress));
const generateThumbnail = async () => { const generateThumbnail = async () => {
const email = localStorage.getItem("email"); const email = localStorage.getItem("email");
@ -30,25 +33,24 @@ const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
const domainParts = emailParts[1].split("."); const domainParts = emailParts[1].split(".");
const Organization = domainParts[0]; const Organization = domainParts[0];
const projects = await getAllProjects( const projects = await getAllProjects(userId, Organization);
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) setProjectName(filterProject.projectName);
} catch {}
} };
catch {
}
}
useEffect(() => { useEffect(() => {
generateThumbnail(); generateThumbnail();
}, []); }, []);
return ( return (
<RenderOverlay> <RenderOverlay>
<div className="loading-wrapper"> <div
className={`loading-wrapper ${
comparisonProduct != null ? "comparisionLoading" : ""
}`}
>
<div className="loading-container"> <div className="loading-container">
<div className="project-name">{projectName}</div> <div className="project-name">{projectName}</div>
<div className="loading-hero-container"> <div className="loading-hero-container">

View File

@ -4,7 +4,10 @@ import {
LayoutIcon, LayoutIcon,
ResizerIcon, ResizerIcon,
} from "../../icons/SimulationIcons"; } from "../../icons/SimulationIcons";
import { useLoadingProgress, useSaveVersion } from "../../../store/builder/store"; import {
useLoadingProgress,
useSaveVersion,
} from "../../../store/builder/store";
import Search from "../inputs/Search"; import Search from "../inputs/Search";
import OuterClick from "../../../utils/outerClick"; import OuterClick from "../../../utils/outerClick";
import { useProductStore } from "../../../store/simulation/useProductStore"; import { useProductStore } from "../../../store/simulation/useProductStore";
@ -13,7 +16,8 @@ import { useComparisonProduct } from "../../../store/simulation/useSimulationSto
import { usePauseButtonStore, usePlayButtonStore } from "../../../store/usePlayButtonStore"; import { usePauseButtonStore, usePlayButtonStore } from "../../../store/usePlayButtonStore";
const CompareLayOut = () => { const CompareLayOut = () => {
const { comparisonProduct, setComparisonProduct, clearComparisonProduct } = useComparisonProduct(); const { comparisonProduct, setComparisonProduct, clearComparisonProduct } =
useComparisonProduct();
const { products } = useProductStore(); const { products } = useProductStore();
const { setLoadingProgress } = useLoadingProgress(); const { setLoadingProgress } = useLoadingProgress();
const [width, setWidth] = useState("50vw"); const [width, setWidth] = useState("50vw");
@ -23,6 +27,7 @@ const CompareLayOut = () => {
const startWidthRef = useRef<number>(0); const startWidthRef = useRef<number>(0);
const startXRef = useRef<number>(0); const startXRef = useRef<number>(0);
const { setIsVersionSaved } = useSaveVersion(); const { setIsVersionSaved } = useSaveVersion();
const { loadingProgress } = useLoadingProgress();
const { setIsPlaying } = usePlayButtonStore(); const { setIsPlaying } = usePlayButtonStore();
const { setIsPaused } = usePauseButtonStore(); const { setIsPaused } = usePauseButtonStore();
@ -124,6 +129,7 @@ const CompareLayOut = () => {
ref={wrapperRef} ref={wrapperRef}
style={{ width }} style={{ width }}
> >
{loadingProgress == 0 && (
<button <button
title="resize-canvas" title="resize-canvas"
id="compare-resize-slider-btn" id="compare-resize-slider-btn"
@ -132,6 +138,7 @@ const CompareLayOut = () => {
> >
<ResizerIcon /> <ResizerIcon />
</button> </button>
)}
<div className="chooseLayout-container"> <div className="chooseLayout-container">
{comparisonProduct && ( {comparisonProduct && (
<div className="compare-layout-canvas-container"> <div className="compare-layout-canvas-container">
@ -158,7 +165,7 @@ const CompareLayOut = () => {
{showLayoutDropdown && ( {showLayoutDropdown && (
<div className="displayLayouts-container"> <div className="displayLayouts-container">
<div className="header">Layouts</div> <div className="header">Layouts</div>
<Search onChange={() => { }} /> <Search onChange={() => {}} />
<div className="layouts-container"> <div className="layouts-container">
{products.map((layout) => ( {products.map((layout) => (
<button <button

View File

@ -2,16 +2,19 @@ import React from "react";
import MachineInstance from "./machineInstance/machineInstance"; import MachineInstance from "./machineInstance/machineInstance";
import MachineContentUi from "../../ui3d/MachineContentUi"; import MachineContentUi from "../../ui3d/MachineContentUi";
import { useSceneContext } from "../../../scene/sceneContext"; import { useSceneContext } from "../../../scene/sceneContext";
import { useViewSceneStore } from "../../../../store/builder/store";
function MachineInstances() { function MachineInstances() {
const { machineStore } = useSceneContext(); const { machineStore } = useSceneContext();
const { machines } = machineStore(); const { machines } = machineStore();
const { viewSceneLabels } = useViewSceneStore();
return ( return (
<> <>
{machines.map((machine: MachineStatus) => ( {machines.map((machine: MachineStatus) => (
<React.Fragment key={machine.modelUuid}> <React.Fragment key={machine.modelUuid}>
<MachineInstance machineDetail={machine} /> <MachineInstance machineDetail={machine} />
<MachineContentUi machine={machine} /> {viewSceneLabels && <MachineContentUi machine={machine} />}
</React.Fragment> </React.Fragment>
))} ))}
</> </>

View File

@ -1,22 +1,24 @@
import React from 'react' import React from "react";
import StorageUnitInstance from './storageUnitInstance/storageUnitInstance' import StorageUnitInstance from "./storageUnitInstance/storageUnitInstance";
import StorageContentUi from '../../ui3d/StorageContentUi'; import StorageContentUi from "../../ui3d/StorageContentUi";
import { useSceneContext } from '../../../scene/sceneContext'; import { useSceneContext } from "../../../scene/sceneContext";
import { useViewSceneStore } from "../../../../store/builder/store";
function StorageUnitInstances() { function StorageUnitInstances() {
const { storageUnitStore } = useSceneContext(); const { storageUnitStore } = useSceneContext();
const { storageUnits } = storageUnitStore(); const { storageUnits } = storageUnitStore();
const { viewSceneLabels } = useViewSceneStore();
return ( return (
<> <>
{storageUnits.map((storageUnit: StorageUnitStatus) => ( {storageUnits.map((storageUnit: StorageUnitStatus) => (
<React.Fragment key={storageUnit.modelUuid}> <React.Fragment key={storageUnit.modelUuid}>
<StorageUnitInstance storageUnit={storageUnit} /> <StorageUnitInstance storageUnit={storageUnit} />
<StorageContentUi storageUnit={storageUnit} /> {viewSceneLabels && <StorageContentUi storageUnit={storageUnit} />}
</React.Fragment> </React.Fragment>
))} ))}
</> </>
) );
} }
export default StorageUnitInstances export default StorageUnitInstances;

View File

@ -2,17 +2,19 @@ import React from "react";
import VehicleInstance from "./instance/vehicleInstance"; import VehicleInstance from "./instance/vehicleInstance";
import VehicleContentUi from "../../ui3d/VehicleContentUi"; import VehicleContentUi from "../../ui3d/VehicleContentUi";
import { useSceneContext } from "../../../scene/sceneContext"; import { useSceneContext } from "../../../scene/sceneContext";
import { useViewSceneStore } from "../../../../store/builder/store";
function VehicleInstances() { function VehicleInstances() {
const { vehicleStore } = useSceneContext(); const { vehicleStore } = useSceneContext();
const { vehicles } = vehicleStore(); const { vehicles } = vehicleStore();
const { viewSceneLabels } = useViewSceneStore();
return ( return (
<> <>
{vehicles.map((vehicle: VehicleStatus) => ( {vehicles.map((vehicle: VehicleStatus) => (
<React.Fragment key={vehicle.modelUuid}> <React.Fragment key={vehicle.modelUuid}>
<VehicleInstance agvDetail={vehicle} /> <VehicleInstance agvDetail={vehicle} />
<VehicleContentUi vehicle={vehicle} /> {viewSceneLabels && <VehicleContentUi vehicle={vehicle} />}
</React.Fragment> </React.Fragment>
))} ))}
</> </>

View File

@ -6,6 +6,7 @@ import {
useUserName, useUserName,
useWallItems, useWallItems,
useSaveVersion, useSaveVersion,
useViewSceneStore,
useProjectName, useProjectName,
useRenameModeStore, useRenameModeStore,
useSelectedFloorItem, useSelectedFloorItem,

View File

@ -680,3 +680,31 @@ export const useVersionStore = create<VersionListStore>((set) => ({
), ),
})), })),
})); }));
interface ViewSceneState {
viewSceneLabels: boolean;
setViewSceneLabels: (value: boolean | ((prev: boolean) => boolean)) => void;
}
export const useViewSceneStore = create<ViewSceneState>((set) => ({
viewSceneLabels: getInitialViewSceneLabels(),
setViewSceneLabels: (value) => {
set((state) => {
const newValue =
typeof value === 'function' ? value(state.viewSceneLabels) : value;
// Store in localStorage manually
localStorage.setItem('viewSceneLabels', JSON.stringify(newValue));
return { viewSceneLabels: newValue };
});
},
}));
function getInitialViewSceneLabels(): boolean {
if (typeof window === 'undefined') return false; // SSR safety
const saved = localStorage.getItem('viewSceneLabels');
return saved ? JSON.parse(saved) : false;
}

View File

@ -46,6 +46,7 @@ textarea {
} }
input[type="number"] { input[type="number"] {
// Chrome, Safari, Edge, Opera // Chrome, Safari, Edge, Opera
&::-webkit-outer-spin-button, &::-webkit-outer-spin-button,
&::-webkit-inner-spin-button { &::-webkit-inner-spin-button {
@ -146,6 +147,7 @@ input[type="number"] {
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
cursor: pointer; cursor: pointer;
background: transparent; background: transparent;
&:hover { &:hover {
background: var(--background-color-secondary); background: var(--background-color-secondary);
} }
@ -337,6 +339,7 @@ input[type="number"] {
max-width: 80%; max-width: 80%;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
&:hover { &:hover {
background: #333333; background: #333333;
} }
@ -413,6 +416,7 @@ input[type="number"] {
cursor: pointer; cursor: pointer;
transition: background-color 0.3s ease; transition: background-color 0.3s ease;
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
&:hover { &:hover {
color: var(--accent-color); color: var(--accent-color);
background: var(--highlight-accent-color); background: var(--highlight-accent-color);
@ -483,6 +487,7 @@ input[type="number"] {
position: relative; position: relative;
cursor: pointer; cursor: pointer;
.check-box-style { .check-box-style {
position: absolute; position: absolute;
height: 20px; height: 20px;
@ -714,21 +719,26 @@ input[type="number"] {
.input-header-container { .input-header-container {
padding: 6px 12px; padding: 6px 12px;
@include flex-space-between; @include flex-space-between;
.arrow-container { .arrow-container {
transition: all 0.2s; transition: all 0.2s;
@include flex-center; @include flex-center;
} }
} }
.upload-custom-asset-button { .upload-custom-asset-button {
padding: 6px 12px; padding: 6px 12px;
@include flex-space-between; @include flex-space-between;
.title { .title {
white-space: nowrap; white-space: nowrap;
width: 40%; width: 40%;
} }
input { input {
display: none; display: none;
} }
.upload-button { .upload-button {
width: 60%; width: 60%;
background: var(--highlight-accent-color); background: var(--highlight-accent-color);
@ -738,6 +748,7 @@ input[type="number"] {
text-align: center; text-align: center;
} }
} }
.canvas-wrapper { .canvas-wrapper {
height: 150px; height: 150px;
width: 100%; width: 100%;
@ -745,6 +756,7 @@ input[type="number"] {
padding-right: 4px; padding-right: 4px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
.canvas-container { .canvas-container {
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@ -52,7 +52,7 @@
border-radius: 50%; border-radius: 50%;
cursor: ew-resize; cursor: ew-resize;
transition: transform 0.1s ease; transition: transform 0.1s ease;
z-index: 10; z-index: 100;
} }
.chooseLayout-container { .chooseLayout-container {
@ -161,9 +161,7 @@
width: 100%; width: 100%;
&:hover { &:hover {
background-color: var( background-color: var(--highlight-text-color) !important;
--highlight-text-color
) !important;
border-radius: 4px; border-radius: 4px;
.layout { .layout {
@ -254,6 +252,7 @@
display: flex; display: flex;
} }
} }
.metric-value { .metric-value {
padding-top: 6px; padding-top: 6px;
font-size: var(--font-size-xlarge); font-size: var(--font-size-xlarge);
@ -289,6 +288,7 @@
top: -57%; top: -57%;
left: 220%; left: 220%;
} }
&::after { &::after {
content: ""; content: "";
position: absolute; position: absolute;
@ -300,21 +300,19 @@
background-color: #b7b7c6; background-color: #b7b7c6;
// Custom polygon shape (adjust if needed) // Custom polygon shape (adjust if needed)
clip-path: polygon( clip-path: polygon(96% 52%,
96% 52%,
96% 54%, 96% 54%,
45% 53%, 45% 53%,
3% 100%, 3% 100%,
0 100%, 0 100%,
42% 52% 42% 52%);
);
z-index: 0; // Behind any inner content z-index: 0; // Behind any inner content
} }
} }
// Optional: content above the shape // Optional: content above the shape
> * { >* {
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
@ -322,12 +320,14 @@
&:nth-child(2) { &:nth-child(2) {
grid-column-start: 1; grid-column-start: 1;
grid-row-start: 2; grid-row-start: 2;
.metric-label { .metric-label {
white-space: normal; white-space: normal;
width: 50px; width: 50px;
left: 230%; left: 230%;
} }
} }
&:nth-child(3) { &:nth-child(3) {
grid-row: span 2 / span 2; grid-row: span 2 / span 2;
grid-column-start: 2; grid-column-start: 2;
@ -367,21 +367,19 @@
height: 100%; height: 100%;
background: var(--background-color, wheat); background: var(--background-color, wheat);
clip-path: polygon( clip-path: polygon(25% 0%,
25% 0%,
75% 0%, 75% 0%,
100% 50%, 100% 50%,
75% 100%, 75% 100%,
25% 100%, 25% 100%,
0% 50% 0% 50%);
);
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.25)); filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.25));
z-index: 0; z-index: 0;
} }
// Content stays above the shape // Content stays above the shape
> * { >* {
position: relative; position: relative;
z-index: 1; z-index: 1;
} }

View File

@ -6,6 +6,16 @@
width: 100vw; width: 100vw;
background: var(--background-color-solid); background: var(--background-color-solid);
&.comparisionLoading {
position: fixed;
top: 0;
right: 0;
height: 100vh;
width: 50vw;
}
.loading-container { .loading-container {
position: relative; position: relative;
height: 100%; height: 100%;
@ -59,6 +69,12 @@
} }
.progress-container { .progress-container {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.progress-value { .progress-value {
font-family: #{$font-josefin-sans}; font-family: #{$font-josefin-sans};
font-weight: #{$thin-weight}; font-weight: #{$thin-weight};
@ -69,7 +85,7 @@
.progress-indicator-container { .progress-indicator-container {
height: 6px; height: 6px;
width: 60vw; width: 60%;
background: var(--highlight-accent-color); background: var(--highlight-accent-color);
border-radius: #{$border-radius-small}; border-radius: #{$border-radius-small};
position: relative; position: relative;

View File

@ -4,11 +4,21 @@
.distance-text-wrapper, .distance-text-wrapper,
.zone-name-wrapper, .zone-name-wrapper,
.pointer-none { .pointer-none {
pointer-events: none !important; pointer-events: auto !important;
background-color: gray;
}
.zone-name-wrapper {
background: var(--background-color-accent);
color: var(--text-button-color);
outline: 1px solid var(--border-color);
border-radius: #{$border-radius-medium};
backdrop-filter: blur(12px);
} }
.distance-text { .distance-text {
pointer-events: none !important; pointer-events: none !important;
div { div {
position: absolute; position: absolute;
transform: translate(-50%, -50%) scale(0.8); transform: translate(-50%, -50%) scale(0.8);
@ -22,18 +32,16 @@
border-radius: #{$border-radius-medium}; border-radius: #{$border-radius-medium};
box-shadow: var(--box-shadow-light); box-shadow: var(--box-shadow-light);
} }
.area { .area {
background: #008cff; background: #008cff;
} }
} }
.zone-name{ .zone-name {
background: var(--background-color); padding: 2px 10px;
padding: 2px 8px;
text-wrap: nowrap; text-wrap: nowrap;
backdrop-filter: blur(12px); color: var(--text-button-color);
border-radius: #{$border-radius-medium};
outline: 1px solid var(--border-color);
} }
// //
@ -54,19 +62,55 @@
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
outline: 1px solid var(--border-color); outline: 1px solid var(--border-color);
transform: translate(-50%, 12px); transform: translate(-50%, 12px);
z-index: 100; z-index: 2;
.presets-container { .presets-container {
@include flex-center; @include flex-center;
gap: 4px; gap: 4px;
.preset { .preset {
background: var(--background-color); background: var(--background-color);
padding: 2px 8px; padding: 2px 8px;
border-radius: #{$border-radius-large}; border-radius: #{$border-radius-large};
outline: 1px solid var(--border-color); outline: 1px solid var(--border-color);
} }
.active { .active {
background: var(--background-color-accent); background: var(--background-color-accent);
color: var(--text-button-color); color: var(--text-button-color);
} }
} }
} }
.label-toogler {
position: fixed;
bottom: 4%;
right: 1.5%;
z-index: 10;
// background: var(--background-color);
// backdrop-filter: blur(10px);
// outline: 1px solid var(--border-color);
border-radius: 8px;
.input-toggle-container {
padding: 0;
display: flex;
flex-direction: column;
align-items: end;
gap: 12px;
.check-box {
width: 35px;
height: 20px;
.check-box-style {
width: 16px;
height: 16px;
background: var(--text-button-color) !important;
}
}
}
}

View File

@ -13,6 +13,7 @@ import {
useShortcutStore, useShortcutStore,
useToggleView, useToggleView,
useToolMode, useToolMode,
useViewSceneStore,
} from "../../store/builder/store"; } from "../../store/builder/store";
import useCameraModeStore, { import useCameraModeStore, {
usePlayButtonStore, usePlayButtonStore,
@ -41,6 +42,7 @@ const KeyPressListener: React.FC = () => {
const { setIsVersionSaved } = useSaveVersion(); const { setIsVersionSaved } = useSaveVersion();
const { isLogListVisible, setIsLogListVisible } = useLogger(); const { isLogListVisible, setIsLogListVisible } = useLogger();
const { hidePlayer, setHidePlayer } = usePlayerStore(); const { hidePlayer, setHidePlayer } = usePlayerStore();
const { viewSceneLabels, setViewSceneLabels } = useViewSceneStore();
const { isRenameMode, setIsRenameMode } = useRenameModeStore(); const { isRenameMode, setIsRenameMode } = useRenameModeStore();
const { selectedFloorItem } = useSelectedFloorItem(); const { selectedFloorItem } = useSelectedFloorItem();
@ -158,6 +160,12 @@ const KeyPressListener: React.FC = () => {
}; };
const handleKeyPress = (event: KeyboardEvent) => { const handleKeyPress = (event: KeyboardEvent) => {
console.log(
"isTextInput(document.activeElement): ",
isTextInput(document.activeElement)
);
if (isTextInput(document.activeElement)) return;
const keyCombination = detectModifierKeys(event); const keyCombination = detectModifierKeys(event);
if (isTextInput(document.activeElement) && keyCombination !== "ESCAPE") if (isTextInput(document.activeElement) && keyCombination !== "ESCAPE")
@ -183,6 +191,7 @@ const KeyPressListener: React.FC = () => {
keyCombination === "Ctrl+R" keyCombination === "Ctrl+R"
) )
return; return;
console.log("keyCombination: ", keyCombination);
event.preventDefault(); event.preventDefault();
@ -211,6 +220,10 @@ const KeyPressListener: React.FC = () => {
if (keyCombination === "Ctrl+Shift+?") { if (keyCombination === "Ctrl+Shift+?") {
setShowShortcuts(!showShortcuts); setShowShortcuts(!showShortcuts);
} }
if (keyCombination === "U") {
console.log("viewSceneLabels: ", viewSceneLabels);
setViewSceneLabels((prev) => !prev);
}
if (selectedFloorItem && keyCombination === "F2") { if (selectedFloorItem && keyCombination === "F2") {
setIsRenameMode(true); setIsRenameMode(true);