Merge branch 'v2-ui' of http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev into v2-ui
This commit is contained in:
BIN
app/src/assets/textures/floor/black.png
Normal file
BIN
app/src/assets/textures/floor/black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
app/src/assets/textures/floor/factory wall texture.jpg
Normal file
BIN
app/src/assets/textures/floor/factory wall texture.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
app/src/assets/textures/floor/wall-tex.png
Normal file
BIN
app/src/assets/textures/floor/wall-tex.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 312 KiB |
BIN
app/src/assets/textures/floor/white.png
Normal file
BIN
app/src/assets/textures/floor/white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -1,9 +1,6 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Search from "../../ui/inputs/Search";
|
import Search from "../../ui/inputs/Search";
|
||||||
import { getCategoryAsset } from "../../../services/factoryBuilder/assest/assets/getCategoryAsset";
|
import { getCategoryAsset } from "../../../services/factoryBuilder/assest/assets/getCategoryAsset";
|
||||||
import arch from "../../../assets/gltf-glb/arch.glb";
|
|
||||||
import door from "../../../assets/gltf-glb/door.glb";
|
|
||||||
import window from "../../../assets/gltf-glb/window.glb";
|
|
||||||
import { fetchAssets } from "../../../services/marketplace/fetchAssets";
|
import { fetchAssets } from "../../../services/marketplace/fetchAssets";
|
||||||
import { useSelectedItem } from "../../../store/store";
|
import { useSelectedItem } from "../../../store/store";
|
||||||
|
|
||||||
@@ -16,8 +13,6 @@ import storage from "../../../assets/image/categories/storage.png";
|
|||||||
import office from "../../../assets/image/categories/office.png";
|
import office from "../../../assets/image/categories/office.png";
|
||||||
import safety from "../../../assets/image/categories/safety.png";
|
import safety from "../../../assets/image/categories/safety.png";
|
||||||
import feneration from "../../../assets/image/categories/feneration.png";
|
import feneration from "../../../assets/image/categories/feneration.png";
|
||||||
import archThumbnail from "../../../assets/image/localAssets/arch.png";
|
|
||||||
import windowThumbnail from "../../../assets/image/localAssets/window.png";
|
|
||||||
import SkeletonUI from "../../templates/SkeletonUI";
|
import SkeletonUI from "../../templates/SkeletonUI";
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
||||||
@@ -90,24 +85,7 @@ const Assets: React.FC = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setCategoryList([
|
setCategoryList([
|
||||||
{
|
{ category: "Fenestration", categoryImage: feneration },
|
||||||
assetName: "Doors",
|
|
||||||
assetImage: "",
|
|
||||||
category: "Feneration",
|
|
||||||
categoryImage: feneration,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
assetName: "Windows",
|
|
||||||
assetImage: "",
|
|
||||||
category: "Feneration",
|
|
||||||
categoryImage: feneration,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
assetName: "Pillars",
|
|
||||||
assetImage: "",
|
|
||||||
category: "Feneration",
|
|
||||||
categoryImage: feneration,
|
|
||||||
},
|
|
||||||
{ category: "Vehicles", categoryImage: vehicle },
|
{ category: "Vehicles", categoryImage: vehicle },
|
||||||
{ category: "Workstation", categoryImage: workStation },
|
{ category: "Workstation", categoryImage: workStation },
|
||||||
{ category: "Machines", categoryImage: machines },
|
{ category: "Machines", categoryImage: machines },
|
||||||
@@ -121,44 +99,15 @@ const Assets: React.FC = () => {
|
|||||||
const fetchCategoryAssets = async (asset: any) => {
|
const fetchCategoryAssets = async (asset: any) => {
|
||||||
setisLoading(true);
|
setisLoading(true);
|
||||||
setSelectedCategory(asset);
|
setSelectedCategory(asset);
|
||||||
if (asset === "Feneration") {
|
try {
|
||||||
const localAssets: AssetProp[] = [
|
const res = await getCategoryAsset(asset);
|
||||||
{
|
setCategoryAssets(res);
|
||||||
filename: "arch",
|
setFiltereredAssets(res);
|
||||||
category: "Feneration",
|
setisLoading(false); // End loading
|
||||||
url: arch,
|
// eslint-disable-next-line
|
||||||
thumbnail: archThumbnail,
|
} catch (error) {
|
||||||
tags: "arch",
|
echo.error("failed to fetch assets");
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "door",
|
|
||||||
category: "Feneration",
|
|
||||||
url: door,
|
|
||||||
thumbnail: feneration,
|
|
||||||
tags: "door",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
filename: "window",
|
|
||||||
category: "Feneration",
|
|
||||||
url: window,
|
|
||||||
thumbnail: windowThumbnail,
|
|
||||||
tags: "window",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
setCategoryAssets(localAssets);
|
|
||||||
setFiltereredAssets(localAssets);
|
|
||||||
setisLoading(false);
|
setisLoading(false);
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
const res = await getCategoryAsset(asset);
|
|
||||||
setCategoryAssets(res);
|
|
||||||
setFiltereredAssets(res);
|
|
||||||
setisLoading(false); // End loading
|
|
||||||
// eslint-disable-next-line
|
|
||||||
} catch (error) {
|
|
||||||
echo.error("failed to fetch assets");
|
|
||||||
setisLoading(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,64 +116,21 @@ const Assets: React.FC = () => {
|
|||||||
<Search onChange={handleSearchChange} />
|
<Search onChange={handleSearchChange} />
|
||||||
<div className="assets-list-section">
|
<div className="assets-list-section">
|
||||||
<section>
|
<section>
|
||||||
{isLoading ? (
|
{(() => {
|
||||||
<SkeletonUI type="asset" /> // Show skeleton when loading
|
if (isLoading) {
|
||||||
) : searchValue ? (
|
return <SkeletonUI type="asset" />; // Show skeleton when loading
|
||||||
<div className="assets-result">
|
}
|
||||||
<div className="assets-wrapper">
|
if (searchValue) {
|
||||||
<div className="searched-content">
|
return (
|
||||||
<p>Results for {searchValue}</p>
|
<div className="assets-result">
|
||||||
</div>
|
<div className="assets-wrapper">
|
||||||
<div className="assets-container">
|
<div className="searched-content">
|
||||||
{categoryAssets?.map((asset: any, index: number) => (
|
<p>Results for {searchValue}</p>
|
||||||
<div
|
|
||||||
key={index}
|
|
||||||
className="assets"
|
|
||||||
id={asset.filename}
|
|
||||||
title={asset.filename}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={asset?.thumbnail}
|
|
||||||
alt={asset.filename}
|
|
||||||
className="asset-image"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="asset-name">
|
|
||||||
{asset.filename
|
|
||||||
.split("_")
|
|
||||||
.map(
|
|
||||||
(word: any) =>
|
|
||||||
word.charAt(0).toUpperCase() + word.slice(1)
|
|
||||||
)
|
|
||||||
.join(" ")}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
<div className="assets-container">
|
||||||
</div>
|
{categoryAssets?.map((asset: any, index: number) => (
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
{selectedCategory ? (
|
|
||||||
<div className="assets-wrapper">
|
|
||||||
<h2>
|
|
||||||
{selectedCategory}{" "}
|
|
||||||
<div
|
|
||||||
className="back-button"
|
|
||||||
id="asset-backButtom"
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedCategory(null);
|
|
||||||
setCategoryAssets([]);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
← Back
|
|
||||||
</div>
|
|
||||||
</h2>
|
|
||||||
<div className="assets-container">
|
|
||||||
{categoryAssets &&
|
|
||||||
categoryAssets?.map((asset: any, index: number) => (
|
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={`${index}-${asset.filename}`}
|
||||||
className="assets"
|
className="assets"
|
||||||
id={asset.filename}
|
id={asset.filename}
|
||||||
title={asset.filename}
|
title={asset.filename}
|
||||||
@@ -233,17 +139,8 @@ const Assets: React.FC = () => {
|
|||||||
src={asset?.thumbnail}
|
src={asset?.thumbnail}
|
||||||
alt={asset.filename}
|
alt={asset.filename}
|
||||||
className="asset-image"
|
className="asset-image"
|
||||||
onPointerDown={() => {
|
|
||||||
setSelectedItem({
|
|
||||||
name: asset.filename,
|
|
||||||
id: asset.AssetID,
|
|
||||||
type:
|
|
||||||
asset.type === "undefined"
|
|
||||||
? undefined
|
|
||||||
: asset.type,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="asset-name">
|
<div className="asset-name">
|
||||||
{asset.filename
|
{asset.filename
|
||||||
.split("_")
|
.split("_")
|
||||||
@@ -255,40 +152,104 @@ const Assets: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedCategory) {
|
||||||
|
return (
|
||||||
<div className="assets-wrapper">
|
<div className="assets-wrapper">
|
||||||
<h2>Categories</h2>
|
<h2>
|
||||||
<div className="categories-container">
|
{selectedCategory}
|
||||||
{Array.from(
|
<button
|
||||||
new Set(categoryList.map((asset) => asset.category))
|
className="back-button"
|
||||||
).map((category, index) => {
|
id="asset-backButtom"
|
||||||
const categoryInfo = categoryList.find(
|
onClick={() => {
|
||||||
(asset) => asset.category === category
|
setSelectedCategory(null);
|
||||||
);
|
setCategoryAssets([]);
|
||||||
return (
|
}}
|
||||||
<div
|
>
|
||||||
key={index}
|
← Back
|
||||||
className="category"
|
</button>
|
||||||
id={category}
|
</h2>
|
||||||
onClick={() => fetchCategoryAssets(category)}
|
<div className="assets-container">
|
||||||
>
|
{categoryAssets?.map((asset: any, index: number) => (
|
||||||
<img
|
<div
|
||||||
src={categoryInfo?.categoryImage || ""}
|
key={`${index}-${asset}`}
|
||||||
alt={category}
|
className="assets"
|
||||||
className="category-image"
|
id={asset.filename}
|
||||||
draggable={false}
|
title={asset.filename}
|
||||||
/>
|
>
|
||||||
<div className="category-name">{category}</div>
|
<img
|
||||||
|
src={asset?.thumbnail}
|
||||||
|
alt={asset.filename}
|
||||||
|
className="asset-image"
|
||||||
|
onPointerDown={() => {
|
||||||
|
setSelectedItem({
|
||||||
|
name: asset.filename,
|
||||||
|
id: asset.AssetID,
|
||||||
|
type:
|
||||||
|
asset.type === "undefined"
|
||||||
|
? undefined
|
||||||
|
: asset.type,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="asset-name">
|
||||||
|
{asset.filename
|
||||||
|
.split("_")
|
||||||
|
.map(
|
||||||
|
(word: any) =>
|
||||||
|
word.charAt(0).toUpperCase() + word.slice(1)
|
||||||
|
)
|
||||||
|
.join(" ")}
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
})}
|
))}
|
||||||
|
{categoryAssets.length === 0 && (
|
||||||
|
<div className="no-asset">
|
||||||
|
🚧 The asset shelf is empty. We're working on filling it
|
||||||
|
up!
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
);
|
||||||
</>
|
}
|
||||||
)}
|
|
||||||
|
return (
|
||||||
|
<div className="assets-wrapper">
|
||||||
|
<h2>Categories</h2>
|
||||||
|
<div className="categories-container">
|
||||||
|
{Array.from(
|
||||||
|
new Set(categoryList.map((asset) => asset.category))
|
||||||
|
).map((category, index) => {
|
||||||
|
const categoryInfo = categoryList.find(
|
||||||
|
(asset) => asset.category === category
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={`${index}-${category}`}
|
||||||
|
className="category"
|
||||||
|
id={category}
|
||||||
|
onClick={() => fetchCategoryAssets(category)}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={categoryInfo?.categoryImage ?? ""}
|
||||||
|
alt={category}
|
||||||
|
className="category-image"
|
||||||
|
draggable={false}
|
||||||
|
/>
|
||||||
|
<div className="category-name">{category}</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import useToggleStore from "../../../store/useUIToggleStore";
|
|||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
|
|
||||||
const Header: React.FC = () => {
|
const Header: React.FC = () => {
|
||||||
const { toggleUI, setToggleUI } = useToggleStore();
|
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -20,15 +20,17 @@ const Header: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className={`toggle-sidebar-ui-button ${!toggleUI ? "active" : ""}`}
|
className={`toggle-sidebar-ui-button ${!toggleUILeft ? "active" : ""}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (activeModule !== "market") {
|
if (activeModule !== "market") {
|
||||||
setToggleUI(!toggleUI);
|
setToggleUI(!toggleUILeft, toggleUIRight);
|
||||||
localStorage.setItem("navBarUi", JSON.stringify(!toggleUI));
|
localStorage.setItem("navBarUiLeft", JSON.stringify(!toggleUILeft));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="tooltip">{toggleUI ? "Hide" : "Show"} sidebar (ctrl + \)</div>
|
<div className="tooltip">
|
||||||
|
{toggleUILeft ? "Hide" : "Show"} sidebar (ctrl + [)
|
||||||
|
</div>
|
||||||
<ToggleSidebarIcon />
|
<ToggleSidebarIcon />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import Search from "../../ui/inputs/Search";
|
|||||||
const SideBarLeft: React.FC = () => {
|
const SideBarLeft: React.FC = () => {
|
||||||
const [activeOption, setActiveOption] = useState("Widgets");
|
const [activeOption, setActiveOption] = useState("Widgets");
|
||||||
|
|
||||||
const { toggleUI } = useToggleStore();
|
const { toggleUILeft } = useToggleStore();
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
|
|
||||||
// Reset activeOption whenever activeModule changes
|
// Reset activeOption whenever activeModule changes
|
||||||
@@ -31,47 +31,55 @@ const SideBarLeft: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`sidebar-left-wrapper ${toggleUI ? "open" : "closed"}`}>
|
<div className={`sidebar-left-wrapper ${toggleUILeft ? "open" : "closed"}`}>
|
||||||
<Header />
|
<Header />
|
||||||
{toggleUI && (
|
{toggleUILeft && (
|
||||||
<div className={`sidebar-left-container `}>
|
<div className={`sidebar-left-container `}>
|
||||||
{activeModule === "visualization" ? (
|
{(() => {
|
||||||
<>
|
if (activeModule === "visualization") {
|
||||||
<ToggleHeader
|
return (
|
||||||
options={["Widgets", "Templates"]}
|
<>
|
||||||
activeOption={activeOption}
|
<ToggleHeader
|
||||||
handleClick={handleToggleClick}
|
options={["Widgets", "Templates"]}
|
||||||
/>
|
activeOption={activeOption}
|
||||||
<Search onChange={handleSearchChange} />
|
handleClick={handleToggleClick}
|
||||||
<div className="sidebar-left-content-container">
|
/>
|
||||||
{activeOption === "Widgets" ? <Widgets /> : <Templates />}
|
<Search onChange={handleSearchChange} />
|
||||||
</div>
|
<div className="sidebar-left-content-container">
|
||||||
</>
|
{activeOption === "Widgets" ? <Widgets /> : <Templates />}
|
||||||
) : activeModule === "market" ? (
|
</div>
|
||||||
<></>
|
</>
|
||||||
) : activeModule === "builder" ? (
|
);
|
||||||
<>
|
} else if (activeModule === "market") {
|
||||||
<ToggleHeader
|
return <></>;
|
||||||
options={["Outline", "Assets"]}
|
} else if (activeModule === "builder") {
|
||||||
activeOption={activeOption}
|
return (
|
||||||
handleClick={handleToggleClick}
|
<>
|
||||||
/>
|
<ToggleHeader
|
||||||
<div className="sidebar-left-content-container">
|
options={["Outline", "Assets"]}
|
||||||
{activeOption === "Outline" ? <Outline /> : <Assets />}
|
activeOption={activeOption}
|
||||||
</div>
|
handleClick={handleToggleClick}
|
||||||
</>
|
/>
|
||||||
) : (
|
<div className="sidebar-left-content-container">
|
||||||
<>
|
{activeOption === "Outline" ? <Outline /> : <Assets />}
|
||||||
<ToggleHeader
|
</div>
|
||||||
options={["Outline"]}
|
</>
|
||||||
activeOption={activeOption}
|
);
|
||||||
handleClick={handleToggleClick}
|
} else {
|
||||||
/>
|
return (
|
||||||
<div className="sidebar-left-content-container">
|
<>
|
||||||
{activeOption === "Outline" ? <Outline /> : <Assets />}
|
<ToggleHeader
|
||||||
</div>
|
options={["Outline"]}
|
||||||
</>
|
activeOption={activeOption}
|
||||||
)}
|
handleClick={handleToggleClick}
|
||||||
|
/>
|
||||||
|
<div className="sidebar-left-content-container">
|
||||||
|
{activeOption === "Outline" ? <Outline /> : <Assets />}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,10 +5,15 @@ import { ActiveUser } from "../../../types/users";
|
|||||||
import CollaborationPopup from "../../templates/CollaborationPopup";
|
import CollaborationPopup from "../../templates/CollaborationPopup";
|
||||||
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
|
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
|
||||||
import { useSelectedUserStore } from "../../../store/useCollabStore";
|
import { useSelectedUserStore } from "../../../store/useCollabStore";
|
||||||
|
import useToggleStore from "../../../store/useUIToggleStore";
|
||||||
|
import { ToggleSidebarIcon } from "../../icons/HeaderIcons";
|
||||||
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
|
|
||||||
const Header: React.FC = () => {
|
const Header: React.FC = () => {
|
||||||
const { activeUsers } = useActiveUsers();
|
const { activeUsers } = useActiveUsers();
|
||||||
const userName = localStorage.getItem("userName") ?? "Anonymous";
|
const userName = localStorage.getItem("userName") ?? "Anonymous";
|
||||||
|
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
|
||||||
|
const { activeModule } = useModuleStore();
|
||||||
|
|
||||||
const guestUsers: ActiveUser[] = activeUsers.filter(
|
const guestUsers: ActiveUser[] = activeUsers.filter(
|
||||||
(user: ActiveUser) => user.userName !== userName
|
(user: ActiveUser) => user.userName !== userName
|
||||||
@@ -55,6 +60,25 @@ const Header: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
<div className="header-container">
|
<div className="header-container">
|
||||||
<div className="options-container">
|
<div className="options-container">
|
||||||
|
<button
|
||||||
|
className={`toggle-sidebar-ui-button ${
|
||||||
|
!toggleUIRight ? "active" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
if (activeModule !== "market") {
|
||||||
|
setToggleUI(toggleUILeft, !toggleUIRight);
|
||||||
|
localStorage.setItem(
|
||||||
|
"navBarUiRight",
|
||||||
|
JSON.stringify(!toggleUIRight)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="tooltip">
|
||||||
|
{toggleUIRight ? "Hide" : "Show"} sidebar (ctrl + ])
|
||||||
|
</div>
|
||||||
|
<ToggleSidebarIcon />
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className="share-button"
|
className="share-button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import VersionHistory from "./versionHisory/VersionHistory";
|
|||||||
|
|
||||||
const SideBarRight: React.FC = () => {
|
const SideBarRight: React.FC = () => {
|
||||||
const { activeModule } = useModuleStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { toggleUI } = useToggleStore();
|
const { toggleUIRight } = useToggleStore();
|
||||||
const { subModule, setSubModule } = useSubModuleStore();
|
const { subModule, setSubModule } = useSubModuleStore();
|
||||||
const { selectedFloorItem } = useSelectedFloorItem();
|
const { selectedFloorItem } = useSelectedFloorItem();
|
||||||
const { selectedEventData } = useSelectedEventData();
|
const { selectedEventData } = useSelectedEventData();
|
||||||
@@ -59,9 +59,9 @@ const SideBarRight: React.FC = () => {
|
|||||||
}, [activeModule, selectedEventData, selectedEventSphere, setSubModule]);
|
}, [activeModule, selectedEventData, selectedEventSphere, setSubModule]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`sidebar-right-wrapper ${toggleUI ? "open" : "closed"}`}>
|
<div className={`sidebar-right-wrapper ${toggleUIRight ? "open" : "closed"}`}>
|
||||||
<Header />
|
<Header />
|
||||||
{toggleUI && (
|
{toggleUIRight && (
|
||||||
<div className="sidebar-actions-container">
|
<div className="sidebar-actions-container">
|
||||||
{activeModule !== "simulation" && (
|
{activeModule !== "simulation" && (
|
||||||
<button
|
<button
|
||||||
@@ -120,7 +120,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{toggleUI && viewVersionHistory && (
|
{toggleUIRight && viewVersionHistory && (
|
||||||
<div className="sidebar-right-container">
|
<div className="sidebar-right-container">
|
||||||
<div className="sidebar-right-content-container">
|
<div className="sidebar-right-content-container">
|
||||||
<VersionHistory />
|
<VersionHistory />
|
||||||
@@ -129,7 +129,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* process builder */}
|
{/* process builder */}
|
||||||
{toggleUI &&
|
{toggleUIRight &&
|
||||||
!viewVersionHistory &&
|
!viewVersionHistory &&
|
||||||
subModule === "properties" &&
|
subModule === "properties" &&
|
||||||
activeModule !== "visualization" &&
|
activeModule !== "visualization" &&
|
||||||
@@ -140,7 +140,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{toggleUI &&
|
{toggleUIRight &&
|
||||||
!viewVersionHistory &&
|
!viewVersionHistory &&
|
||||||
subModule === "properties" &&
|
subModule === "properties" &&
|
||||||
activeModule !== "visualization" &&
|
activeModule !== "visualization" &&
|
||||||
@@ -152,7 +152,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{toggleUI &&
|
{toggleUIRight &&
|
||||||
!viewVersionHistory &&
|
!viewVersionHistory &&
|
||||||
subModule === "zoneProperties" &&
|
subModule === "zoneProperties" &&
|
||||||
(activeModule === "builder" || activeModule === "simulation") && (
|
(activeModule === "builder" || activeModule === "simulation") && (
|
||||||
@@ -163,7 +163,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* simulation */}
|
{/* simulation */}
|
||||||
{toggleUI && !viewVersionHistory && activeModule === "simulation" && (
|
{toggleUIRight && !viewVersionHistory && activeModule === "simulation" && (
|
||||||
<>
|
<>
|
||||||
{subModule === "simulations" && (
|
{subModule === "simulations" && (
|
||||||
<div className="sidebar-right-container">
|
<div className="sidebar-right-container">
|
||||||
@@ -189,7 +189,7 @@ const SideBarRight: React.FC = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{/* realtime visualization */}
|
{/* realtime visualization */}
|
||||||
{toggleUI && activeModule === "visualization" && <Visualization />}
|
{toggleUIRight && activeModule === "visualization" && <Visualization />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ interface SkeletonUIProps {
|
|||||||
|
|
||||||
// Define the SkeletonUI component
|
// Define the SkeletonUI component
|
||||||
const SkeletonUI: React.FC<SkeletonUIProps> = ({ type }) => {
|
const SkeletonUI: React.FC<SkeletonUIProps> = ({ type }) => {
|
||||||
|
|
||||||
// Function to render skeleton content based on 'type'
|
// Function to render skeleton content based on 'type'
|
||||||
const renderSkeleton = () => {
|
const renderSkeleton = () => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -38,17 +37,28 @@ const SkeletonUI: React.FC<SkeletonUIProps> = ({ type }) => {
|
|||||||
case "asset":
|
case "asset":
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="skeleton-content">
|
<div className="skeleton asset-category-title"></div>
|
||||||
<div className="skeleton asset-name"></div>
|
<div className="skeleton-content-asset">
|
||||||
<div className="skeleton asset"></div>
|
<div className="skeleton-content">
|
||||||
</div>
|
<div className="skeleton asset-name"></div>
|
||||||
<div className="skeleton-content">
|
<div className="skeleton asset"></div>
|
||||||
<div className="skeleton asset-name"></div>
|
</div>
|
||||||
<div className="skeleton asset"></div>
|
<div className="skeleton-content">
|
||||||
|
<div className="skeleton asset-name"></div>
|
||||||
|
<div className="skeleton asset"></div>
|
||||||
|
</div>
|
||||||
|
<div className="skeleton-content">
|
||||||
|
<div className="skeleton asset-name"></div>
|
||||||
|
<div className="skeleton asset"></div>
|
||||||
|
</div>
|
||||||
|
<div className="skeleton-content">
|
||||||
|
<div className="skeleton asset-name"></div>
|
||||||
|
<div className="skeleton asset"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<div className="skeleton-content">
|
<div className="skeleton-content">
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const FileMenu: React.FC = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// project
|
// project
|
||||||
const [projectName, setProjectName] = useState("project 1");
|
const [projectName, setProjectName] = useState("Demo Project");
|
||||||
|
|
||||||
// Load project name from localStorage on mount
|
// Load project name from localStorage on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -22,8 +22,11 @@ const ModuleToggle: React.FC = () => {
|
|||||||
setActiveModule("builder");
|
setActiveModule("builder");
|
||||||
setVersionHistory(false);
|
setVersionHistory(false);
|
||||||
setToggleUI(
|
setToggleUI(
|
||||||
localStorage.getItem("navBarUi")
|
localStorage.getItem("navBarUiLeft")
|
||||||
? localStorage.getItem("navBarUi") === "true"
|
? localStorage.getItem("navBarUiLeft") === "true"
|
||||||
|
: true,
|
||||||
|
localStorage.getItem("navBarUiRight")
|
||||||
|
? localStorage.getItem("navBarUiRight") === "true"
|
||||||
: true
|
: true
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -41,8 +44,11 @@ const ModuleToggle: React.FC = () => {
|
|||||||
setActiveModule("simulation");
|
setActiveModule("simulation");
|
||||||
setVersionHistory(false);
|
setVersionHistory(false);
|
||||||
setToggleUI(
|
setToggleUI(
|
||||||
localStorage.getItem("navBarUi")
|
localStorage.getItem("navBarUiLeft")
|
||||||
? localStorage.getItem("navBarUi") === "true"
|
? localStorage.getItem("navBarUiLeft") === "true"
|
||||||
|
: true,
|
||||||
|
localStorage.getItem("navBarUiRight")
|
||||||
|
? localStorage.getItem("navBarUiRight") === "true"
|
||||||
: true
|
: true
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -60,8 +66,11 @@ const ModuleToggle: React.FC = () => {
|
|||||||
setActiveModule("visualization");
|
setActiveModule("visualization");
|
||||||
setVersionHistory(false);
|
setVersionHistory(false);
|
||||||
setToggleUI(
|
setToggleUI(
|
||||||
localStorage.getItem("navBarUi")
|
localStorage.getItem("navBarUiLeft")
|
||||||
? localStorage.getItem("navBarUi") === "true"
|
? localStorage.getItem("navBarUiLeft") === "true"
|
||||||
|
: true,
|
||||||
|
localStorage.getItem("navBarUiRight")
|
||||||
|
? localStorage.getItem("navBarUiRight") === "true"
|
||||||
: true
|
: true
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
@@ -76,7 +85,7 @@ const ModuleToggle: React.FC = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActiveModule("market");
|
setActiveModule("market");
|
||||||
setVersionHistory(false);
|
setVersionHistory(false);
|
||||||
setToggleUI(false);
|
setToggleUI(false, false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="icon">
|
<div className="icon">
|
||||||
|
|||||||
@@ -71,8 +71,11 @@ const Tools: React.FC = () => {
|
|||||||
// Reset activeTool whenever activeModule changes
|
// Reset activeTool whenever activeModule changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setToggleUI(
|
setToggleUI(
|
||||||
localStorage.getItem("navBarUi")
|
localStorage.getItem("navBarUiLeft")
|
||||||
? localStorage.getItem("navBarUi") === "true"
|
? localStorage.getItem("navBarUiLeft") === "true"
|
||||||
|
: true,
|
||||||
|
localStorage.getItem("navBarUiRight")
|
||||||
|
? localStorage.getItem("navBarUiRight") === "true"
|
||||||
: true
|
: true
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
@@ -93,8 +96,11 @@ const Tools: React.FC = () => {
|
|||||||
setToggleView(false);
|
setToggleView(false);
|
||||||
}
|
}
|
||||||
setToggleUI(
|
setToggleUI(
|
||||||
localStorage.getItem("navBarUi")
|
localStorage.getItem("navBarUiLeft")
|
||||||
? localStorage.getItem("navBarUi") === "true"
|
? localStorage.getItem("navBarUiLeft") === "true"
|
||||||
|
: true,
|
||||||
|
localStorage.getItem("navBarUiRight")
|
||||||
|
? localStorage.getItem("navBarUiRight") === "true"
|
||||||
: true
|
: true
|
||||||
);
|
);
|
||||||
setToggleThreeD(!toggleThreeD);
|
setToggleThreeD(!toggleThreeD);
|
||||||
@@ -119,7 +125,7 @@ const Tools: React.FC = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!toggleThreeD) {
|
if (!toggleThreeD) {
|
||||||
setToggleUI(false);
|
setToggleUI(false, false);
|
||||||
}
|
}
|
||||||
}, [toggleThreeD]);
|
}, [toggleThreeD]);
|
||||||
|
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ const ROISummary = ({
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="tips-section">
|
{/* <div className="tips-section">
|
||||||
<div className="tip-header">
|
<div className="tip-header">
|
||||||
<span className="lightbulb-icon">
|
<span className="lightbulb-icon">
|
||||||
<LightBulpIcon />
|
<LightBulpIcon />
|
||||||
@@ -224,7 +224,7 @@ const ROISummary = ({
|
|||||||
<button className="get-tips-button">
|
<button className="get-tips-button">
|
||||||
<div className="btn">Get ROI Boost Tips</div>
|
<div className="btn">Get ROI Boost Tips</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div> */}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<SkeletonUI type={"default"} />
|
<SkeletonUI type={"default"} />
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import SkeletonUI from "../../templates/SkeletonUI";
|
|||||||
|
|
||||||
const ProductionCapacity = ({
|
const ProductionCapacity = ({
|
||||||
progressPercent = 50,
|
progressPercent = 50,
|
||||||
avgProcessTime = "28.4 Secs/unit",
|
avgProcessTime = "28.4",
|
||||||
machineUtilization = "78%",
|
machineUtilization = "78%",
|
||||||
throughputValue = 128,
|
throughputValue = 128,
|
||||||
timeRange = { startTime: "08:00 AM", endTime: "09:00 AM" },
|
timeRange = { startTime: "08:00 AM", endTime: "09:00 AM" },
|
||||||
@@ -34,7 +34,7 @@ const ProductionCapacity = ({
|
|||||||
<>
|
<>
|
||||||
<div className="process-container">
|
<div className="process-container">
|
||||||
<div className="throughput-value">
|
<div className="throughput-value">
|
||||||
<span className="value">{throughputValue}</span> Units/hour
|
<span className="value">{avgProcessTime}</span> secs/unit
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Dynamic Progress Bar */}
|
{/* Dynamic Progress Bar */}
|
||||||
@@ -56,8 +56,8 @@ const ProductionCapacity = ({
|
|||||||
|
|
||||||
<div className="metrics-section">
|
<div className="metrics-section">
|
||||||
<div className="metric">
|
<div className="metric">
|
||||||
<span className="label">Avg. Process Time</span>
|
<span className="label">Units/hour</span>
|
||||||
<span className="value">{avgProcessTime}</span>
|
<span className="value">{throughputValue} avg.</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="metric">
|
<div className="metric">
|
||||||
<span className="label">Machine Utilization</span>
|
<span className="label">Machine Utilization</span>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useState } from "react";
|
|||||||
import { ArrowIcon } from "../../icons/ExportCommonIcons";
|
import { ArrowIcon } from "../../icons/ExportCommonIcons";
|
||||||
import { toggleTheme } from "../../../utils/theme";
|
import { toggleTheme } from "../../../utils/theme";
|
||||||
import useVersionHistoryStore, { useShortcutStore } from "../../../store/store";
|
import useVersionHistoryStore, { useShortcutStore } from "../../../store/store";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useSubModuleStore } from "../../../store/useModuleStore";
|
import { useSubModuleStore } from "../../../store/useModuleStore";
|
||||||
|
|
||||||
interface MenuBarProps {
|
interface MenuBarProps {
|
||||||
@@ -9,6 +10,7 @@ interface MenuBarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
|
const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const [activeMenu, setActiveMenu] = useState<string | null>(null);
|
const [activeMenu, setActiveMenu] = useState<string | null>(null);
|
||||||
const [activeSubMenu, setActiveSubMenu] = useState<string | null>(null);
|
const [activeSubMenu, setActiveSubMenu] = useState<string | null>(null);
|
||||||
|
|
||||||
@@ -36,6 +38,12 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
|
|||||||
|
|
||||||
const savedTheme: string | null = localStorage.getItem("theme") ?? "light";
|
const savedTheme: string | null = localStorage.getItem("theme") ?? "light";
|
||||||
|
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
localStorage.clear(); // 1. Clear all localStorage
|
||||||
|
navigate('/'); // 2. Redirect to homepage
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="menu-bar"
|
className="menu-bar"
|
||||||
@@ -552,6 +560,9 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="menu-button-container" onClick={handleLogout}>
|
||||||
|
<div className="menu-button">Log out</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import * as THREE from 'three';
|
|||||||
import * as Types from "../../../../types/world/worldTypes";
|
import * as Types from "../../../../types/world/worldTypes";
|
||||||
import * as CONSTANTS from "../../../../types/world/worldConstants";
|
import * as CONSTANTS from "../../../../types/world/worldConstants";
|
||||||
|
|
||||||
import texturePath from "../../../../assets/textures/floor/concreteFloorWorn001Diff2k.jpg";
|
import texturePath from "../../../../assets/textures/floor/white.png";
|
||||||
import normalPath from "../../../../assets/textures/floor/concreteFloorWorn001NorGl2k.jpg";
|
import texturePathDark from "../../../../assets/textures/floor/black.png";
|
||||||
|
|
||||||
// Cache for materials
|
// Cache for materials
|
||||||
const materialCache = new Map<string, THREE.Material>();
|
const materialCache = new Map<string, THREE.Material>();
|
||||||
@@ -14,6 +14,8 @@ export default function addFloorToScene(
|
|||||||
floorGroup: Types.RefGroup,
|
floorGroup: Types.RefGroup,
|
||||||
userData: any,
|
userData: any,
|
||||||
) {
|
) {
|
||||||
|
const savedTheme: string | null = localStorage.getItem('theme');
|
||||||
|
|
||||||
const textureLoader = new THREE.TextureLoader();
|
const textureLoader = new THREE.TextureLoader();
|
||||||
|
|
||||||
const textureScale = CONSTANTS.floorConfig.textureScale;
|
const textureScale = CONSTANTS.floorConfig.textureScale;
|
||||||
@@ -24,20 +26,17 @@ export default function addFloorToScene(
|
|||||||
|
|
||||||
if (materialCache.has(materialKey)) {
|
if (materialCache.has(materialKey)) {
|
||||||
material = materialCache.get(materialKey) as THREE.Material;
|
material = materialCache.get(materialKey) as THREE.Material;
|
||||||
|
// } else {
|
||||||
} else {
|
} else {
|
||||||
const floorTexture = textureLoader.load(texturePath);
|
const floorTexture = textureLoader.load(savedTheme === "dark" ? texturePathDark : texturePath);
|
||||||
const normalMap = textureLoader.load(normalPath);
|
// const floorTexture = textureLoader.load(texturePath);
|
||||||
|
|
||||||
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
|
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
|
||||||
floorTexture.repeat.set(textureScale, textureScale);
|
floorTexture.repeat.set(textureScale, textureScale);
|
||||||
floorTexture.colorSpace = THREE.SRGBColorSpace;
|
floorTexture.colorSpace = THREE.SRGBColorSpace;
|
||||||
|
|
||||||
normalMap.wrapS = normalMap.wrapT = THREE.RepeatWrapping;
|
|
||||||
normalMap.repeat.set(textureScale, textureScale);
|
|
||||||
|
|
||||||
material = new THREE.MeshStandardMaterial({
|
material = new THREE.MeshStandardMaterial({
|
||||||
map: floorTexture,
|
map: floorTexture,
|
||||||
normalMap: normalMap,
|
|
||||||
side: THREE.DoubleSide,
|
side: THREE.DoubleSide,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useFrame, useThree } from "@react-three/fiber";
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
import {
|
import {
|
||||||
useActiveTool,
|
useActiveTool,
|
||||||
useAsset3dWidget,
|
|
||||||
useCamMode,
|
useCamMode,
|
||||||
useDeletableFloorItem,
|
useDeletableFloorItem,
|
||||||
useDeleteTool,
|
useDeleteTool,
|
||||||
@@ -14,7 +13,6 @@ import {
|
|||||||
useToggleView,
|
useToggleView,
|
||||||
useTransformMode,
|
useTransformMode,
|
||||||
} from "../../../store/store";
|
} from "../../../store/store";
|
||||||
import assetVisibility from "../geomentries/assets/assetVisibility";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import * as Types from "../../../types/world/worldTypes";
|
import * as Types from "../../../types/world/worldTypes";
|
||||||
@@ -29,7 +27,6 @@ import loadInitialFloorItems from "../IntialLoad/loadInitialFloorItems";
|
|||||||
import addAssetModel from "../geomentries/assets/addAssetModel";
|
import addAssetModel from "../geomentries/assets/addAssetModel";
|
||||||
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
import { getFloorAssets } from "../../../services/factoryBuilder/assest/floorAsset/getFloorItemsApi";
|
||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
// import { retrieveGLTF } from "../../../utils/indexDB/idbUtils";
|
|
||||||
import { useEventsStore } from "../../../store/simulation/useEventsStore";
|
import { useEventsStore } from "../../../store/simulation/useEventsStore";
|
||||||
|
|
||||||
const assetManagerWorker = new Worker(
|
const assetManagerWorker = new Worker(
|
||||||
@@ -198,9 +195,7 @@ const FloorItemsGroup = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const startInterval = () => {
|
const startInterval = () => {
|
||||||
if (!intervalId) {
|
intervalId ??= setInterval(handleChange, 50);
|
||||||
intervalId = setInterval(handleChange, 50);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const stopInterval = () => {
|
const stopInterval = () => {
|
||||||
|
|||||||
@@ -1,56 +1,92 @@
|
|||||||
import { Geometry } from "@react-three/csg";
|
import { Geometry } from "@react-three/csg";
|
||||||
import { useDeleteTool, useSelectedWallItem, useToggleView, useTransformMode, useWallItems, useWalls } from "../../../store/store";
|
import {
|
||||||
|
useDeleteTool,
|
||||||
|
useSelectedWallItem,
|
||||||
|
useToggleView,
|
||||||
|
useTransformMode,
|
||||||
|
useWallItems,
|
||||||
|
useWalls,
|
||||||
|
} from "../../../store/store";
|
||||||
import handleMeshDown from "../eventFunctions/handleMeshDown";
|
import handleMeshDown from "../eventFunctions/handleMeshDown";
|
||||||
import handleMeshMissed from "../eventFunctions/handleMeshMissed";
|
import handleMeshMissed from "../eventFunctions/handleMeshMissed";
|
||||||
import WallsMesh from "./wallsMesh";
|
import WallsMesh from "./wallsMesh";
|
||||||
import WallItemsGroup from "./wallItemsGroup";
|
import WallItemsGroup from "./wallItemsGroup";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
const WallsAndWallItems = ({
|
||||||
|
CSGGroup,
|
||||||
|
AssetConfigurations,
|
||||||
|
setSelectedItemsIndex,
|
||||||
|
selectedItemsIndex,
|
||||||
|
currentWallItem,
|
||||||
|
csg,
|
||||||
|
lines,
|
||||||
|
hoveredDeletableWallItem,
|
||||||
|
}: any) => {
|
||||||
|
const { walls } = useWalls();
|
||||||
|
const { wallItems } = useWallItems();
|
||||||
|
const { toggleView } = useToggleView();
|
||||||
|
const { deleteTool } = useDeleteTool();
|
||||||
|
const { transformMode } = useTransformMode();
|
||||||
|
const { setSelectedWallItem } = useSelectedWallItem();
|
||||||
|
|
||||||
const WallsAndWallItems = ({ CSGGroup, AssetConfigurations, setSelectedItemsIndex, selectedItemsIndex, currentWallItem, csg, lines, hoveredDeletableWallItem }: any) => {
|
useEffect(() => {
|
||||||
const { walls, setWalls } = useWalls();
|
if (transformMode === null) {
|
||||||
const { wallItems, setWallItems } = useWallItems();
|
if (!deleteTool) {
|
||||||
const { toggleView, setToggleView } = useToggleView();
|
handleMeshMissed(
|
||||||
const { deleteTool, setDeleteTool } = useDeleteTool();
|
currentWallItem,
|
||||||
const { transformMode, setTransformMode } = useTransformMode();
|
setSelectedWallItem,
|
||||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
setSelectedItemsIndex
|
||||||
|
);
|
||||||
useEffect(() => {
|
setSelectedWallItem(null);
|
||||||
if (transformMode === null) {
|
setSelectedItemsIndex(null);
|
||||||
if (!deleteTool) {
|
}
|
||||||
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
}
|
||||||
setSelectedWallItem(null);
|
}, [transformMode]);
|
||||||
setSelectedItemsIndex(null);
|
return (
|
||||||
}
|
<mesh
|
||||||
|
ref={CSGGroup as any}
|
||||||
|
name="Walls"
|
||||||
|
key={walls.length}
|
||||||
|
receiveShadow
|
||||||
|
visible={!toggleView}
|
||||||
|
onClick={(event) => {
|
||||||
|
if (!deleteTool && transformMode !== null) {
|
||||||
|
handleMeshDown(
|
||||||
|
event,
|
||||||
|
currentWallItem,
|
||||||
|
setSelectedWallItem,
|
||||||
|
setSelectedItemsIndex,
|
||||||
|
wallItems,
|
||||||
|
toggleView
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [transformMode])
|
}}
|
||||||
|
onPointerMissed={() => {
|
||||||
|
if (!deleteTool) {
|
||||||
|
handleMeshMissed(
|
||||||
|
currentWallItem,
|
||||||
|
setSelectedWallItem,
|
||||||
|
setSelectedItemsIndex
|
||||||
|
);
|
||||||
|
setSelectedWallItem(null);
|
||||||
|
setSelectedItemsIndex(null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Geometry ref={csg as any} computeVertexNormals useGroups>
|
||||||
|
<WallsMesh lines={lines} />
|
||||||
|
<WallItemsGroup
|
||||||
|
currentWallItem={currentWallItem}
|
||||||
|
AssetConfigurations={AssetConfigurations}
|
||||||
|
hoveredDeletableWallItem={hoveredDeletableWallItem}
|
||||||
|
selectedItemsIndex={selectedItemsIndex}
|
||||||
|
setSelectedItemsIndex={setSelectedItemsIndex}
|
||||||
|
CSGGroup={CSGGroup}
|
||||||
|
/>
|
||||||
|
</Geometry>
|
||||||
|
</mesh>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
export default WallsAndWallItems;
|
||||||
<mesh
|
|
||||||
ref={CSGGroup as any}
|
|
||||||
name="Walls"
|
|
||||||
key={walls.length}
|
|
||||||
receiveShadow
|
|
||||||
visible={!toggleView}
|
|
||||||
onClick={(event) => {
|
|
||||||
if (!deleteTool && transformMode !== null) {
|
|
||||||
handleMeshDown(event, currentWallItem, setSelectedWallItem, setSelectedItemsIndex, wallItems, toggleView);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onPointerMissed={() => {
|
|
||||||
if (!deleteTool) {
|
|
||||||
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
|
||||||
setSelectedWallItem(null);
|
|
||||||
setSelectedItemsIndex(null);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Geometry ref={csg as any} computeVertexNormals useGroups>
|
|
||||||
<WallsMesh lines={lines} />
|
|
||||||
<WallItemsGroup currentWallItem={currentWallItem} AssetConfigurations={AssetConfigurations} hoveredDeletableWallItem={hoveredDeletableWallItem} selectedItemsIndex={selectedItemsIndex} setSelectedItemsIndex={setSelectedItemsIndex} CSGGroup={CSGGroup} />
|
|
||||||
</Geometry>
|
|
||||||
</mesh>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WallsAndWallItems;
|
|
||||||
|
|||||||
@@ -1,65 +1,78 @@
|
|||||||
import * as THREE from 'three';
|
import * as THREE from "three";
|
||||||
import * as Types from '../../../types/world/worldTypes';
|
import * as Types from "../../../types/world/worldTypes";
|
||||||
import * as CONSTANTS from '../../../types/world/worldConstants';
|
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||||
import { Base } from '@react-three/csg';
|
import { Base } from "@react-three/csg";
|
||||||
import { MeshDiscardMaterial } from '@react-three/drei';
|
import { MeshDiscardMaterial } from "@react-three/drei";
|
||||||
import { useUpdateScene, useWalls } from '../../../store/store';
|
import { useUpdateScene, useWalls } from "../../../store/store";
|
||||||
import { useEffect } from 'react';
|
import React, { useEffect } from "react";
|
||||||
import { getLines } from '../../../services/factoryBuilder/lines/getLinesApi';
|
import { getLines } from "../../../services/factoryBuilder/lines/getLinesApi";
|
||||||
import objectLinesToArray from '../geomentries/lines/lineConvertions/objectLinesToArray';
|
import objectLinesToArray from "../geomentries/lines/lineConvertions/objectLinesToArray";
|
||||||
import loadWalls from '../geomentries/walls/loadWalls';
|
import loadWalls from "../geomentries/walls/loadWalls";
|
||||||
|
// texture
|
||||||
|
import texturePath from "../../../assets/textures/floor/wall-tex.png";
|
||||||
|
|
||||||
const WallsMesh = ({ lines }: any) => {
|
// Cache for materials
|
||||||
const { walls, setWalls } = useWalls();
|
const materialCache = new Map<string, THREE.Material>();
|
||||||
const { updateScene, setUpdateScene } = useUpdateScene();
|
|
||||||
|
|
||||||
useEffect(() => {
|
const WallsMeshComponent = ({ lines }: any) => {
|
||||||
if (updateScene) {
|
const { walls, setWalls } = useWalls();
|
||||||
|
const { updateScene, setUpdateScene } = useUpdateScene();
|
||||||
|
|
||||||
const email = localStorage.getItem('email')
|
useEffect(() => {
|
||||||
const organization = (email!.split("@")[1]).split(".")[0];
|
if (updateScene) {
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const organization = email!.split("@")[1].split(".")[0];
|
||||||
|
|
||||||
getLines(organization).then((data) => {
|
getLines(organization).then((data) => {
|
||||||
const Lines: Types.Lines = objectLinesToArray(data);
|
const Lines: Types.Lines = objectLinesToArray(data);
|
||||||
localStorage.setItem("Lines", JSON.stringify(Lines));
|
localStorage.setItem("Lines", JSON.stringify(Lines));
|
||||||
|
|
||||||
if (Lines) {
|
if (Lines) {
|
||||||
loadWalls(lines, setWalls);
|
loadWalls(lines, setWalls);
|
||||||
}
|
|
||||||
})
|
|
||||||
setUpdateScene(false);
|
|
||||||
}
|
}
|
||||||
}, [updateScene])
|
});
|
||||||
|
setUpdateScene(false);
|
||||||
|
}
|
||||||
|
}, [updateScene]);
|
||||||
|
|
||||||
return (
|
const textureLoader = new THREE.TextureLoader();
|
||||||
<>
|
const wallTexture = textureLoader.load(texturePath);
|
||||||
{walls.map((wall: Types.Wall, index: number) => (
|
|
||||||
<mesh key={index}>
|
|
||||||
<Base
|
|
||||||
name={`Wall${index + 1}`}
|
|
||||||
geometry={wall[0]}
|
|
||||||
rotation={wall[1]}
|
|
||||||
position={wall[2]}
|
|
||||||
userData={{ WallType: wall[3], Layer: wall[4] }}
|
|
||||||
>
|
|
||||||
<meshStandardMaterial
|
|
||||||
side={THREE.DoubleSide}
|
|
||||||
color={CONSTANTS.wallConfig.defaultColor}
|
|
||||||
/>
|
|
||||||
</Base>
|
|
||||||
<mesh
|
|
||||||
castShadow
|
|
||||||
geometry={wall[0]}
|
|
||||||
rotation={wall[1]}
|
|
||||||
position={wall[2]}
|
|
||||||
name={`WallRaycastReference_${index + 1}`}
|
|
||||||
>
|
|
||||||
<MeshDiscardMaterial />
|
|
||||||
</mesh>
|
|
||||||
</mesh>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WallsMesh;
|
wallTexture.wrapS = wallTexture.wrapT = THREE.RepeatWrapping;
|
||||||
|
wallTexture.repeat.set(0.1, 0.1);
|
||||||
|
wallTexture.colorSpace = THREE.SRGBColorSpace;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{walls.map((wall: Types.Wall, index: number) => (
|
||||||
|
<mesh key={index} renderOrder={1}>
|
||||||
|
<Base
|
||||||
|
name={`Wall${index + 1}`}
|
||||||
|
geometry={wall[0]}
|
||||||
|
rotation={wall[1]}
|
||||||
|
position={wall[2]}
|
||||||
|
userData={{ WallType: wall[3], Layer: wall[4] }}
|
||||||
|
>
|
||||||
|
<meshStandardMaterial
|
||||||
|
side={THREE.DoubleSide}
|
||||||
|
color={CONSTANTS.wallConfig.defaultColor}
|
||||||
|
map={wallTexture}
|
||||||
|
/>
|
||||||
|
</Base>
|
||||||
|
<mesh
|
||||||
|
castShadow
|
||||||
|
geometry={wall[0]}
|
||||||
|
rotation={wall[1]}
|
||||||
|
position={wall[2]}
|
||||||
|
name={`WallRaycastReference_${index + 1}`}
|
||||||
|
>
|
||||||
|
<MeshDiscardMaterial />
|
||||||
|
</mesh>
|
||||||
|
</mesh>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const WallsMesh = React.memo(WallsMeshComponent);
|
||||||
|
export default WallsMesh;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ function MoveControls({
|
|||||||
"Ctrl" | "Shift" | "Ctrl+Shift" | ""
|
"Ctrl" | "Shift" | "Ctrl+Shift" | ""
|
||||||
>("");
|
>("");
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
const organization = email!.split("@")[1].split(".")[0];
|
const organization = email?.split("@")[1].split(".")[0] ?? null;
|
||||||
|
|
||||||
const updateBackend = (
|
const updateBackend = (
|
||||||
productName: string,
|
productName: string,
|
||||||
@@ -308,7 +308,7 @@ function MoveControls({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (event) {
|
if (event && organization) {
|
||||||
updateBackend(
|
updateBackend(
|
||||||
selectedProduct.productName,
|
selectedProduct.productName,
|
||||||
selectedProduct.productId,
|
selectedProduct.productId,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
|||||||
const itemsData = useRef<Types.FloorItems>([]);
|
const itemsData = useRef<Types.FloorItems>([]);
|
||||||
|
|
||||||
const email = localStorage.getItem('email')
|
const email = localStorage.getItem('email')
|
||||||
const organization = (email!.split("@")[1]).split(".")[0];
|
const organization = (email?.split("@")[1])?.split(".")[0] ?? null;
|
||||||
|
|
||||||
const updateBackend = (
|
const updateBackend = (
|
||||||
productName: string,
|
productName: string,
|
||||||
@@ -214,7 +214,7 @@ function RotateControls({ rotatedObjects, setRotatedObjects, movedObjects, setMo
|
|||||||
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z],
|
||||||
})
|
})
|
||||||
|
|
||||||
if (event) {
|
if (event && organization) {
|
||||||
updateBackend(
|
updateBackend(
|
||||||
selectedProduct.productName,
|
selectedProduct.productName,
|
||||||
selectedProduct.productId,
|
selectedProduct.productId,
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ const RealTimeVisulization: React.FC = () => {
|
|||||||
<div
|
<div
|
||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
className="realTime-viz"
|
className="realTime-viz"
|
||||||
|
id="real-time-vis-canvas"
|
||||||
style={{
|
style={{
|
||||||
height: isPlaying || activeModule !== "visualization" ? "100vh" : "",
|
height: isPlaying || activeModule !== "visualization" ? "100vh" : "",
|
||||||
width: isPlaying || activeModule !== "visualization" ? "100vw" : "",
|
width: isPlaying || activeModule !== "visualization" ? "100vw" : "",
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
|
|
||||||
interface ToggleState {
|
interface ToggleState {
|
||||||
toggleUI: boolean; // State to track UI toggle
|
toggleUILeft: boolean;
|
||||||
setToggleUI: (value: boolean) => void; // Action to update toggleUI
|
toggleUIRight: boolean;
|
||||||
|
setToggleUI: (value1: boolean, value2: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useToggleStore = create<ToggleState>((set) => ({
|
const useToggleStore = create<ToggleState>((set) => ({
|
||||||
toggleUI: true, // Initial state
|
toggleUILeft: true,
|
||||||
setToggleUI: (value: boolean) => set({ toggleUI: value }), // Update the state
|
toggleUIRight: false,
|
||||||
|
setToggleUI: (value1: boolean, value2: boolean) => {
|
||||||
|
set({ toggleUILeft: value1, toggleUIRight: value2 });
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default useToggleStore;
|
export default useToggleStore;
|
||||||
|
|||||||
@@ -1,6 +1,55 @@
|
|||||||
@use "../abstracts/variables" as *;
|
@use "../abstracts/variables" as *;
|
||||||
@use "../abstracts/mixins" as *;
|
@use "../abstracts/mixins" as *;
|
||||||
|
|
||||||
|
.toggle-sidebar-ui-button {
|
||||||
|
@include flex-center;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
min-height: 32px;
|
||||||
|
min-width: 32px;
|
||||||
|
border-radius: #{$border-radius-large};
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
top: 6px;
|
||||||
|
right: -168px;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
left: 0px;
|
||||||
|
bottom: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
outline: 1px solid var(--border-color);
|
||||||
|
outline-offset: -1px;
|
||||||
|
background: var(--background-color-solid);
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(2px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-sidebar-ui-button.active {
|
||||||
|
background: var(--background-color-accent);
|
||||||
|
|
||||||
|
rect {
|
||||||
|
stroke: var(--icon-default-color-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
circle {
|
||||||
|
fill: var(--icon-default-color-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: saturate(0.8);
|
||||||
|
background: var(--background-color-accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-left-wrapper {
|
.sidebar-left-wrapper {
|
||||||
width: 270px;
|
width: 270px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -34,15 +83,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.toggle-sidebar-ui-button {
|
.toggle-sidebar-ui-button {
|
||||||
@include flex-center;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 32px;
|
|
||||||
width: 32px;
|
|
||||||
min-height: 32px;
|
|
||||||
min-width: 32px;
|
|
||||||
border-radius: #{$border-radius-large};
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.tooltip {
|
.tooltip {
|
||||||
top: 6px;
|
top: 6px;
|
||||||
right: -168px;
|
right: -168px;
|
||||||
@@ -52,34 +92,6 @@
|
|||||||
bottom: 50%;
|
bottom: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
|
||||||
outline: 1px solid var(--border-color);
|
|
||||||
outline-offset: -1px;
|
|
||||||
background: var(--background-color-solid);
|
|
||||||
|
|
||||||
.tooltip {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateX(2px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
background: var(--background-color-accent);
|
|
||||||
|
|
||||||
rect {
|
|
||||||
stroke: var(--icon-default-color-active);
|
|
||||||
}
|
|
||||||
|
|
||||||
circle {
|
|
||||||
fill: var(--icon-default-color-active);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
filter: saturate(0.8);
|
|
||||||
background: var(--background-color-accent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +307,7 @@
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 12px;
|
gap: 8px;
|
||||||
height: 52px;
|
height: 52px;
|
||||||
|
|
||||||
.options-container {
|
.options-container {
|
||||||
@@ -318,7 +330,7 @@
|
|||||||
|
|
||||||
.split {
|
.split {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
width: 2px;
|
min-width: 1px;
|
||||||
background: var(--text-disabled);
|
background: var(--text-disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1166,8 +1178,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
color: var(--text-color);
|
color: var(--accent-color);
|
||||||
opacity: 0.4;
|
|
||||||
font-size: var(--font-size-regular);
|
font-size: var(--font-size-regular);
|
||||||
outline-offset: -1px;
|
outline-offset: -1px;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -1431,6 +1442,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.toggle-sidebar-ui-button {
|
||||||
|
svg {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
.tooltip {
|
||||||
|
right: 56px;
|
||||||
|
&::after {
|
||||||
|
left: 100%;
|
||||||
|
bottom: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.assets-container-main {
|
.assets-container-main {
|
||||||
@@ -1598,7 +1621,11 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
.no-asset {
|
||||||
|
text-align: center;
|
||||||
|
margin: 12px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
.assets {
|
.assets {
|
||||||
width: 122px;
|
width: 122px;
|
||||||
height: 95px;
|
height: 95px;
|
||||||
@@ -1655,20 +1682,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.skeleton-wrapper {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.asset-name {
|
|
||||||
width: 40%;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asset {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-left-wrapper,
|
.sidebar-left-wrapper,
|
||||||
.sidebar-right-wrapper {
|
.sidebar-right-wrapper {
|
||||||
transition: height 0.2s ease-in-out;
|
transition: height 0.2s ease-in-out;
|
||||||
|
|||||||
125
app/src/styles/layout/skeleton.scss
vendored
125
app/src/styles/layout/skeleton.scss
vendored
@@ -1,61 +1,90 @@
|
|||||||
.skeleton-wrapper {
|
.skeleton-wrapper {
|
||||||
// max-width: 600px;
|
margin: 0 auto;
|
||||||
margin: 0 auto;
|
width: 100%;
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.skeleton {
|
.skeleton {
|
||||||
background: var(--background-color-gray);
|
background: var(--background-color-gray);
|
||||||
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background-image: linear-gradient(90deg,
|
background-image: linear-gradient(
|
||||||
rgba(255, 255, 255, 0) 0%,
|
90deg,
|
||||||
rgba(255, 255, 255, 0.2) 20%,
|
rgba(255, 255, 255, 0) 0%,
|
||||||
rgba(255, 255, 255, 0.5) 60%,
|
rgba(255, 255, 255, 0.2) 20%,
|
||||||
rgba(255, 255, 255, 0) 100%);
|
rgba(255, 255, 255, 0.39) 60%,
|
||||||
transform: translateX(-100%);
|
rgba(255, 255, 255, 0) 100%
|
||||||
animation: shimmer 1.5s infinite;
|
);
|
||||||
}
|
transform: translateX(-100%);
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-header {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.skeleton-title {
|
||||||
|
width: 100%;
|
||||||
|
height: 25px;
|
||||||
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skeleton-header {
|
.skeleton-subtitle {
|
||||||
margin-bottom: 20px;
|
width: 100%;
|
||||||
|
height: 4px;
|
||||||
.skeleton-title {
|
|
||||||
width: 100%;
|
|
||||||
height: 25px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skeleton-subtitle {
|
|
||||||
width: 100%;
|
|
||||||
height: 4px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.skeleton-content {
|
.skeleton-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
.skeleton-card {
|
.skeleton-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.asset-category-title{
|
||||||
|
width: 60%;
|
||||||
|
height: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.skeleton-content-asset{
|
||||||
|
display: flex;
|
||||||
|
height: calc(95px * 2 + 10px);
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.skeleton-content {
|
||||||
|
gap: 8px;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 122px;
|
||||||
|
min-height: 95px;
|
||||||
|
.asset-name {
|
||||||
|
width: 40%;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
.asset {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes shimmer {
|
@keyframes shimmer {
|
||||||
100% {
|
100% {
|
||||||
transform: translateX(100%);
|
transform: translateX(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ export const lineConfig: LineConfig = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const wallConfig: WallConfig = {
|
export const wallConfig: WallConfig = {
|
||||||
defaultColor: "white", // Default color of the walls
|
defaultColor: "#f2f2f2", // Default color of the walls
|
||||||
height: 7, // Height of the walls
|
height: 7, // Height of the walls
|
||||||
width: 0.05, // Width of the walls
|
width: 0.05, // Width of the walls
|
||||||
};
|
};
|
||||||
@@ -334,7 +334,7 @@ export const wallConfig: WallConfig = {
|
|||||||
export const floorConfig: FloorConfig = {
|
export const floorConfig: FloorConfig = {
|
||||||
defaultColor: "grey", // Default color of the floors
|
defaultColor: "grey", // Default color of the floors
|
||||||
height: 0.1, // Height of the floors
|
height: 0.1, // Height of the floors
|
||||||
textureScale: 0.1, // Scale of the floor texture
|
textureScale: 1, // Scale of the floor texture
|
||||||
};
|
};
|
||||||
|
|
||||||
export const roofConfig: RoofConfig = {
|
export const roofConfig: RoofConfig = {
|
||||||
@@ -345,7 +345,7 @@ export const roofConfig: RoofConfig = {
|
|||||||
export const aisleConfig: AisleConfig = {
|
export const aisleConfig: AisleConfig = {
|
||||||
width: 0.1, // Width of the aisles
|
width: 0.1, // Width of the aisles
|
||||||
height: 0.01, // Height of the aisles
|
height: 0.01, // Height of the aisles
|
||||||
defaultColor: 0xffff00, // Default color of the aisles
|
defaultColor: 0xE2AC09, // Default color of the aisles
|
||||||
};
|
};
|
||||||
|
|
||||||
export const zoneConfig: ZoneConfig = {
|
export const zoneConfig: ZoneConfig = {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
|
|||||||
const KeyPressListener: React.FC = () => {
|
const KeyPressListener: React.FC = () => {
|
||||||
const { activeModule, setActiveModule } = useModuleStore();
|
const { activeModule, setActiveModule } = useModuleStore();
|
||||||
const { setActiveSubTool } = useActiveSubTool();
|
const { setActiveSubTool } = useActiveSubTool();
|
||||||
const { toggleUI, setToggleUI } = useToggleStore();
|
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
|
||||||
const { setToggleThreeD } = useThreeDStore();
|
const { setToggleThreeD } = useThreeDStore();
|
||||||
const { setToolMode } = useToolMode();
|
const { setToolMode } = useToolMode();
|
||||||
const { setIsPlaying } = usePlayButtonStore();
|
const { setIsPlaying } = usePlayButtonStore();
|
||||||
@@ -26,7 +26,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
const { setAddAction } = useAddAction();
|
const { setAddAction } = useAddAction();
|
||||||
const { setSelectedWallItem } = useSelectedWallItem();
|
const { setSelectedWallItem } = useSelectedWallItem();
|
||||||
const { setActiveTool } = useActiveTool();
|
const { setActiveTool } = useActiveTool();
|
||||||
const { clearSelectedZone} = useSelectedZoneStore();
|
const { clearSelectedZone } = useSelectedZoneStore();
|
||||||
|
|
||||||
const isTextInput = (element: Element | null): boolean =>
|
const isTextInput = (element: Element | null): boolean =>
|
||||||
element instanceof HTMLInputElement ||
|
element instanceof HTMLInputElement ||
|
||||||
@@ -42,9 +42,10 @@ const KeyPressListener: React.FC = () => {
|
|||||||
};
|
};
|
||||||
const module = modules[keyCombination];
|
const module = modules[keyCombination];
|
||||||
if (module && !toggleView) {
|
if (module && !toggleView) {
|
||||||
|
console.log("hi");
|
||||||
setActiveTool("cursor");
|
setActiveTool("cursor");
|
||||||
setActiveSubTool("cursor");
|
setActiveSubTool("cursor");
|
||||||
if (module === "market") setToggleUI(false);
|
if (module === "market") setToggleUI(false, false);
|
||||||
setActiveModule(module);
|
setActiveModule(module);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -69,6 +70,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
const toggleTo2D = toggleView;
|
const toggleTo2D = toggleView;
|
||||||
setToggleView(!toggleTo2D);
|
setToggleView(!toggleTo2D);
|
||||||
setToggleThreeD(toggleTo2D);
|
setToggleThreeD(toggleTo2D);
|
||||||
|
setToggleUI(toggleTo2D, toggleTo2D);
|
||||||
if (toggleTo2D) {
|
if (toggleTo2D) {
|
||||||
setSelectedWallItem(null);
|
setSelectedWallItem(null);
|
||||||
setDeleteTool(false);
|
setDeleteTool(false);
|
||||||
@@ -105,6 +107,29 @@ const KeyPressListener: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const handleSidebarShortcuts = (key: string) => {
|
||||||
|
if (activeModule !== "market") {
|
||||||
|
if (key === "Ctrl+\\") {
|
||||||
|
if (toggleUILeft === toggleUIRight) {
|
||||||
|
setToggleUI(!toggleUILeft, !toggleUIRight);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setToggleUI(true, true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (key === "Ctrl+]") {
|
||||||
|
setToggleUI(toggleUILeft, !toggleUIRight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (key === "Ctrl+[") {
|
||||||
|
setToggleUI(!toggleUILeft, toggleUIRight);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const handleKeyPress = (event: KeyboardEvent) => {
|
const handleKeyPress = (event: KeyboardEvent) => {
|
||||||
if (isTextInput(document.activeElement)) return;
|
if (isTextInput(document.activeElement)) return;
|
||||||
|
|
||||||
@@ -113,11 +138,8 @@ const KeyPressListener: React.FC = () => {
|
|||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (keyCombination === "Ctrl+\\") {
|
// Shortcuts specific for sidebar visibility toggle and others specific to sidebar if added
|
||||||
if (activeModule !== "market") setToggleUI(!toggleUI);
|
handleSidebarShortcuts(keyCombination);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active module selection (builder, simulation, etc.)
|
// Active module selection (builder, simulation, etc.)
|
||||||
handleModuleSwitch(keyCombination);
|
handleModuleSwitch(keyCombination);
|
||||||
// Common editing tools: cursor | delete | free-hand
|
// Common editing tools: cursor | delete | free-hand
|
||||||
@@ -132,6 +154,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
|
|
||||||
if (keyCombination === "ESCAPE") {
|
if (keyCombination === "ESCAPE") {
|
||||||
setActiveTool("cursor");
|
setActiveTool("cursor");
|
||||||
|
setActiveSubTool("cursor");
|
||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
clearSelectedZone();
|
clearSelectedZone();
|
||||||
}
|
}
|
||||||
@@ -146,7 +169,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
window.addEventListener("keydown", handleKeyPress);
|
window.addEventListener("keydown", handleKeyPress);
|
||||||
return () => window.removeEventListener("keydown", handleKeyPress);
|
return () => window.removeEventListener("keydown", handleKeyPress);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [activeModule, toggleUI, toggleView]);
|
}, [activeModule, toggleUIRight, toggleUILeft, toggleView]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export { };
|
|||||||
function setTheme() {
|
function setTheme() {
|
||||||
const savedTheme: string | null = localStorage.getItem('theme');
|
const savedTheme: string | null = localStorage.getItem('theme');
|
||||||
const systemPrefersDark: boolean = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
const systemPrefersDark: boolean = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
const defaultTheme: string = savedTheme || (systemPrefersDark ? 'dark' : 'light');
|
const defaultTheme: string = savedTheme ?? (systemPrefersDark ? 'dark' : 'light');
|
||||||
document.documentElement.setAttribute('data-theme', defaultTheme);
|
document.documentElement.setAttribute('data-theme', defaultTheme);
|
||||||
localStorage.setItem('theme', defaultTheme);
|
localStorage.setItem('theme', defaultTheme);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user