Refactor SideBarRight component for improved readability and functionality; add DecalProperties component; remove DecalTransformation; update AssetProperties animations rendering; enhance InputRange and RegularDropDown components; adjust styles for better layout; fix state management in decal store.

This commit is contained in:
2025-08-23 15:43:19 +05:30
parent d7295ebacf
commit e2c5b43c2e
15 changed files with 741 additions and 739 deletions

View File

@@ -15,270 +15,293 @@ import safety from "../../../assets/image/categories/safety.png";
import feneration from "../../../assets/image/categories/feneration.png";
import decal from "../../../assets/image/categories/decal.png";
import SkeletonUI from "../../templates/SkeletonUI";
import { AlertIcon, DecalInfoIcon, HangTagIcon, NavigationIcon } from "../../icons/ExportCommonIcons";
import {
AlertIcon,
DecalInfoIcon,
HangTagIcon,
NavigationIcon,
} from "../../icons/ExportCommonIcons";
// -------------------------------------
interface AssetProp {
filename: string;
thumbnail?: string;
category: string;
description?: string;
tags: string;
url?: string;
uploadDate?: number;
isArchieve?: boolean;
animated?: boolean;
price?: number;
CreatedBy?: string;
filename: string;
thumbnail?: string;
category: string;
description?: string;
tags: string;
url?: string;
uploadDate?: number;
isArchieve?: boolean;
animated?: boolean;
price?: number;
CreatedBy?: string;
}
interface CategoryListProp {
assetImage?: string;
assetName?: string;
categoryImage: string;
category: string;
assetImage?: string;
assetName?: string;
categoryImage: string;
category: string;
}
const Assets: React.FC = () => {
const { setSelectedItem } = useSelectedItem();
const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const [isLoading, setisLoading] = useState<boolean>(false); // Loading state for assets
const { setSelectedItem } = useSelectedItem();
const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const [isLoading, setisLoading] = useState<boolean>(false); // Loading state for assets
const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase();
setSearchValue(value);
if (searchTerm.trim() === "" && !selectedCategory) {
setCategoryAssets([]);
return;
}
const filteredModels = filtereredAssets?.filter((model) => {
if (!model?.tags || !model?.filename || !model?.category) return false;
if (searchTerm.startsWith(":") && searchTerm.length > 1) {
const tagSearchTerm = searchTerm.slice(1);
return model.tags.toLowerCase().includes(tagSearchTerm);
} else if (selectedCategory) {
return (
model.category
.toLowerCase()
.includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm);
}
});
const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase();
setSearchValue(value);
if (searchTerm.trim() === "" && !selectedCategory) {
setCategoryAssets([]);
return;
}
const filteredModels = filtereredAssets?.filter((model) => {
if (!model?.tags || !model?.filename || !model?.category) return false;
if (searchTerm.startsWith(":") && searchTerm.length > 1) {
const tagSearchTerm = searchTerm.slice(1);
return model.tags.toLowerCase().includes(tagSearchTerm);
} else if (selectedCategory) {
return (
model.category
.toLowerCase()
.includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm);
}
});
setCategoryAssets(filteredModels);
setCategoryAssets(filteredModels);
};
useEffect(() => {
const filteredAssets = async () => {
try {
const filt = await fetchAssets();
setFiltereredAssets(filt);
} catch {
echo.error("Filter asset not found");
}
};
filteredAssets();
}, [categoryAssets]);
useEffect(() => {
const filteredAssets = async () => {
try {
const filt = await fetchAssets();
setFiltereredAssets(filt);
} catch {
echo.error("Filter asset not found");
useEffect(() => {
setCategoryList([
{ category: "Fenestration", categoryImage: feneration },
{ category: "Decals", categoryImage: decal },
{ category: "Vehicles", categoryImage: vehicle },
{ category: "Workstation", categoryImage: workStation },
{ category: "Machines", categoryImage: machines },
{ category: "Workers", categoryImage: worker },
{ category: "Storage", categoryImage: storage },
{ category: "Safety", categoryImage: safety },
{ category: "Office", categoryImage: office },
]);
}, []);
const fetchCategoryAssets = async (asset: any) => {
setisLoading(true);
setSelectedCategory(asset);
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);
}
};
const activeSubcategories = [
{ name: "Safety", icon: <AlertIcon /> },
{ name: "Navigation", icon: <NavigationIcon /> },
{ name: "Branding", icon: <HangTagIcon /> },
{ name: "Informational", icon: <DecalInfoIcon /> },
];
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
return (
<div className="assets-container-main">
<Search onChange={handleSearchChange} />
<div className="assets-list-section">
<section>
{(() => {
if (isLoading) {
return <SkeletonUI type="asset" />; // Show skeleton when loading
}
};
filteredAssets();
}, [categoryAssets]);
if (searchValue) {
return (
<div className="assets-result">
<div className="assets-wrapper">
<div className="searched-content">
<p>Results for {searchValue}</p>
</div>
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset.filename}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<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,
});
}}
/>
useEffect(() => {
setCategoryList([
{ category: "Fenestration", categoryImage: feneration },
{ category: "Decals", categoryImage: decal },
{ category: "Vehicles", categoryImage: vehicle },
{ category: "Workstation", categoryImage: workStation },
{ category: "Machines", categoryImage: machines },
{ category: "Workers", categoryImage: worker },
{ category: "Storage", categoryImage: storage },
{ category: "Safety", categoryImage: safety },
{ category: "Office", categoryImage: office },
]);
}, []);
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div>
</div>
))}
</div>
</div>
</div>
);
}
const fetchCategoryAssets = async (asset: any) => {
setisLoading(true);
setSelectedCategory(asset);
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);
}
};
if (selectedCategory) {
return (
<div className="assets-wrapper">
<h2>
{selectedCategory}
<button
className="back-button"
id="asset-backButtom"
onClick={() => {
setSelectedCategory(null);
setSelectedSubCategory(null);
setCategoryAssets([]);
}}
>
Back
</button>
</h2>
{selectedCategory === "Decals" && (
<>
<div className="catogory-asset-filter">
{activeSubcategories.map((cat, index) => (
<div
key={index}
className={`catogory-asset-filter-wrapper ${
selectedSubCategory === cat.name ? "active" : ""
}`}
onClick={() => setSelectedSubCategory(cat.name)}
>
<div className="sub-catagory">{cat.icon}</div>
<div className="sub-catagory">{cat.name}</div>
</div>
))}
</div>
</>
)}
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<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,
category: asset.category,
subType: asset.subType,
});
}}
/>
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div>
</div>
))}
{categoryAssets.length === 0 && (
<div className="no-asset">
🚧 The asset shelf is empty. We're working on filling it
up!
</div>
)}
</div>
</div>
);
}
const activeSubcategories = [
{ name: "Safety", icon: <AlertIcon /> },
{ name: "Navigation", icon: <NavigationIcon /> },
{ name: "Branding", icon: <HangTagIcon /> },
{ name: "Informational", icon: <DecalInfoIcon /> }
]
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
return (
<div className="assets-container-main">
<Search onChange={handleSearchChange} />
<div className="assets-list-section">
<section>
{(() => {
if (isLoading) {
return <SkeletonUI type="asset" />; // Show skeleton when loading
}
if (searchValue) {
return (
<div className="assets-result">
<div className="assets-wrapper">
<div className="searched-content">
<p>Results for {searchValue}</p>
</div>
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset.filename}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<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>
</div>
</div>
);
}
if (selectedCategory) {
return (
<div className="assets-wrapper">
<h2>
{selectedCategory}
<button
className="back-button"
id="asset-backButtom"
onClick={() => {
setSelectedCategory(null);
setCategoryAssets([]);
}}
>
Back
</button>
</h2>
{selectedCategory === "Decals" &&
<>
<div className="catogory-asset-filter">
{activeSubcategories.map((cat, index) => (
<div className={`catogory-asset-filter-wrapper ${selectedSubCategory === cat.name ? "active" : ""}`} onClick={() => setSelectedSubCategory(cat.name)}>
<div className="sub-catagory">{cat.icon}</div>
<div className="sub-catagory">{cat.name}</div>
</div>
))}
</div>
</>
}
<div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<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,
category: asset.category,
subType: asset.subType
});
}}
/>
<div className="asset-name">
{asset.filename.split("_").map((word: any) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ")}
</div>
</div>
))}
{categoryAssets.length === 0 && (
<div className="no-asset">
🚧 The asset shelf is empty. We're working on filling it up!
</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 (
<div
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>
</div>
);
})}
</div>
</div>
);
})()}
</section>
</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 (
<div
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>
</div>
);
})}
</div>
</div>
);
})()}
</section>
</div>
</div>
);
};
export default Assets;

View File

@@ -1,26 +1,28 @@
import React, { useEffect, useState } from "react";
import Header from "./Header";
import useModuleStore, { useSubModuleStore } from "../../../store/useModuleStore";
import useModuleStore, {
useSubModuleStore,
} from "../../../store/useModuleStore";
import {
AnalysisIcon,
FilePackageIcon,
MechanicsIcon,
PropertiesIcon,
SimulationIcon,
AnalysisIcon,
FilePackageIcon,
MechanicsIcon,
PropertiesIcon,
SimulationIcon,
} from "../../icons/SimulationIcons";
import { useToggleStore } from "../../../store/useUIToggleStore";
import Visualization from "./visualization/Visualization";
import Analysis from "./analysis/Analysis";
import Simulations from "./simulation/Simulations";
import useVersionHistoryVisibleStore, {
useDecalStore,
useSaveVersion,
useSelectedFloorItem,
useToolMode,
useDecalStore,
useSaveVersion,
useSelectedFloorItem,
useToolMode,
} from "../../../store/builder/store";
import {
useSelectedEventData,
useSelectedEventSphere,
useSelectedEventData,
useSelectedEventSphere,
} from "../../../store/simulation/useSimulationStore";
import { useBuilderStore } from "../../../store/builder/useBuilderStore";
import GlobalProperties from "./properties/GlobalProperties";
@@ -33,277 +35,319 @@ import WallProperties from "./properties/WallProperties";
import FloorProperties from "./properties/FloorProperties";
import SelectedWallProperties from "./properties/SelectedWallProperties";
import SelectedFloorProperties from "./properties/SelectedFloorProperties";
import DecalTransformation from "./decals/DecalTransformation";
import ResourceManagement from "./resourceManagement/ResourceManagement";
import DecalProperties from "./properties/DecalProperties";
type DisplayComponent =
| "versionHistory"
| "globalProperties"
| "aisleProperties"
| "wallProperties"
| "floorProperties"
| "assetProperties"
| "selectedWallProperties"
| "selectedFloorProperties"
| "zoneProperties"
| "simulations"
| "mechanics"
| "analysis"
| "visualization"
| "decals"
| "resourceManagement"
| "none";
| "versionHistory"
| "globalProperties"
| "aisleProperties"
| "wallProperties"
| "floorProperties"
| "assetProperties"
| "selectedWallProperties"
| "selectedFloorProperties"
| "zoneProperties"
| "simulations"
| "mechanics"
| "analysis"
| "visualization"
| "selectedDecalProperties"
| "resourceManagement"
| "none";
const SideBarRight: React.FC = () => {
const { activeModule } = useModuleStore();
const { toggleUIRight } = useToggleStore();
const { toolMode } = useToolMode();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedWall, selectedFloor, selectedAisle } = useBuilderStore();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
const { viewVersionHistory, setVersionHistoryVisible } = useVersionHistoryVisibleStore();
const { isVersionSaved } = useSaveVersion();
const { selectedSubCategory } = useDecalStore();
const { activeModule } = useModuleStore();
const { toggleUIRight } = useToggleStore();
const { toolMode } = useToolMode();
const { subModule, setSubModule } = useSubModuleStore();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedWall, selectedFloor, selectedAisle } = useBuilderStore();
const { selectedEventData } = useSelectedEventData();
const { selectedEventSphere } = useSelectedEventSphere();
const { viewVersionHistory, setVersionHistoryVisible } =
useVersionHistoryVisibleStore();
const { isVersionSaved } = useSaveVersion();
const { selectedSubCategory } = useDecalStore();
const [displayComponent, setDisplayComponent] = useState<DisplayComponent>("none");
const [displayComponent, setDisplayComponent] =
useState<DisplayComponent>("none");
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
if (activeModule === "simulation") setSubModule("simulations");
}, [activeModule, setSubModule]);
useEffect(() => {
if (activeModule !== "simulation") setSubModule("properties");
if (activeModule === "simulation") setSubModule("simulations");
}, [activeModule, setSubModule]);
useEffect(() => {
if (activeModule !== "mechanics" && selectedEventData && selectedEventSphere) {
setSubModule("mechanics");
} else if (!selectedEventData && !selectedEventSphere) {
if (activeModule === "simulation") {
setSubModule("simulations");
}
useEffect(() => {
if (
activeModule !== "mechanics" &&
selectedEventData &&
selectedEventSphere
) {
setSubModule("mechanics");
} else if (!selectedEventData && !selectedEventSphere) {
if (activeModule === "simulation") {
setSubModule("simulations");
}
}
if (activeModule !== "simulation") {
setSubModule("properties");
}
}, [activeModule, selectedEventData, selectedEventSphere, setSubModule]);
useEffect(() => {
if (activeModule === "visualization") {
setDisplayComponent("visualization");
return;
}
if (!isVersionSaved && activeModule === "simulation") {
if (subModule === "simulations") {
setDisplayComponent("simulations");
return;
}
if (subModule === "mechanics") {
setDisplayComponent("mechanics");
return;
}
if (subModule === "analysis") {
setDisplayComponent("analysis");
return;
}
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (activeModule === "simulation" || activeModule === "builder") {
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (subModule === "properties" && activeModule !== "visualization") {
if (selectedFloorItem) {
setDisplayComponent("assetProperties");
return;
}
if (
!selectedFloorItem &&
!selectedFloor &&
!selectedAisle &&
selectedWall
) {
setDisplayComponent("selectedWallProperties");
return;
}
if (
!selectedFloorItem &&
!selectedWall &&
!selectedAisle &&
selectedFloor
) {
setDisplayComponent("selectedFloorProperties");
return;
}
if (viewVersionHistory) {
setDisplayComponent("versionHistory");
return;
}
if (selectedSubCategory) {
setDisplayComponent("selectedDecalProperties");
return;
}
if (
!selectedFloorItem &&
!selectedFloor &&
!selectedWall &&
!selectedSubCategory
) {
if (toolMode === "Aisle") {
setDisplayComponent("aisleProperties");
return;
}
if (activeModule !== "simulation") {
setSubModule("properties");
if (toolMode === "Wall") {
setDisplayComponent("wallProperties");
return;
}
}, [activeModule, selectedEventData, selectedEventSphere, setSubModule]);
useEffect(() => {
if (activeModule === "visualization") {
setDisplayComponent("visualization");
return;
if (toolMode === "Floor") {
setDisplayComponent("floorProperties");
return;
}
setDisplayComponent("globalProperties");
return;
}
}
if (!isVersionSaved && activeModule === "simulation") {
if (subModule === "simulations") {
setDisplayComponent("simulations");
return;
}
if (subModule === "mechanics") {
setDisplayComponent("mechanics");
return;
}
if (subModule === "analysis") {
setDisplayComponent("analysis");
return;
}
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (
subModule === "zoneProperties" &&
(activeModule === "builder" || activeModule === "simulation")
) {
setDisplayComponent("zoneProperties");
return;
}
setDisplayComponent("none");
}, [
viewVersionHistory,
activeModule,
subModule,
isVersionSaved,
selectedFloorItem,
selectedWall,
selectedFloor,
selectedAisle,
toolMode,
selectedSubCategory,
]);
const renderComponent = () => {
switch (displayComponent) {
case "versionHistory":
return <VersionHistory />;
case "globalProperties":
return <GlobalProperties />;
case "aisleProperties":
return <AisleProperties />;
case "wallProperties":
return <WallProperties />;
case "floorProperties":
return <FloorProperties />;
case "assetProperties":
return <AssetProperties />;
case "selectedWallProperties":
return <SelectedWallProperties />;
case "selectedFloorProperties":
return <SelectedFloorProperties />;
case "zoneProperties":
return <ZoneProperties />;
case "simulations":
return <Simulations />;
case "mechanics":
return <EventProperties />;
case "analysis":
return <Analysis />;
case "visualization":
return <Visualization />;
case "selectedDecalProperties":
return <DecalProperties />;
case "resourceManagement":
return <ResourceManagement />;
default:
return null;
}
};
if (activeModule === "simulation" || activeModule === "builder") {
if (subModule === "resourceManagement") {
setDisplayComponent("resourceManagement");
return;
}
}
if (subModule === "properties" && activeModule !== "visualization") {
if (selectedFloorItem) {
setDisplayComponent("assetProperties");
return;
}
if (!selectedFloorItem && !selectedFloor && !selectedAisle && selectedWall) {
setDisplayComponent("selectedWallProperties");
return;
}
if (!selectedFloorItem && !selectedWall && !selectedAisle && selectedFloor) {
setDisplayComponent("selectedFloorProperties");
return;
}
if (viewVersionHistory) {
setDisplayComponent("versionHistory");
return;
}
if (selectedSubCategory) {
setDisplayComponent("decals");
return;
}
if (!selectedFloorItem && !selectedFloor && !selectedWall && !selectedSubCategory) {
if (toolMode === "Aisle") {
setDisplayComponent("aisleProperties");
return;
}
if (toolMode === "Wall") {
setDisplayComponent("wallProperties");
return;
}
if (toolMode === "Floor") {
setDisplayComponent("floorProperties");
return;
}
setDisplayComponent("globalProperties");
return;
}
}
if (subModule === "zoneProperties" && (activeModule === "builder" || activeModule === "simulation")) {
setDisplayComponent("zoneProperties");
return;
}
setDisplayComponent("none");
}, [viewVersionHistory, activeModule, subModule, isVersionSaved, selectedFloorItem, selectedWall, selectedFloor, selectedAisle, toolMode, selectedSubCategory]);
const renderComponent = () => {
switch (displayComponent) {
case "versionHistory":
return <VersionHistory />;
case "globalProperties":
return <GlobalProperties />;
case "aisleProperties":
return <AisleProperties />;
case "wallProperties":
return <WallProperties />;
case "floorProperties":
return <FloorProperties />;
case "assetProperties":
return <AssetProperties />;
case "selectedWallProperties":
return <SelectedWallProperties />;
case "selectedFloorProperties":
return <SelectedFloorProperties />;
case "zoneProperties":
return <ZoneProperties />;
case "simulations":
return <Simulations />;
case "mechanics":
return <EventProperties />;
case "analysis":
return <Analysis />;
case "visualization":
return <Visualization />;
case "decals":
return <DecalTransformation />;
case "resourceManagement":
return <ResourceManagement />;
default:
return null;
}
};
return (
<div
className={`sidebar-right-wrapper ${toggleUIRight && (!isVersionSaved || activeModule !== "simulation") ? "open" : "closed"
}`}
>
<Header />
{toggleUIRight && (
return (
<div
className={`sidebar-right-wrapper ${
toggleUIRight && (!isVersionSaved || activeModule !== "simulation")
? "open"
: "closed"
}`}
>
<Header />
{toggleUIRight && (
<>
{(!isVersionSaved || activeModule !== "simulation") && (
<div className="sidebar-actions-container">
{activeModule !== "simulation" && (
<>
{(!isVersionSaved || activeModule !== "simulation") && (
<div className="sidebar-actions-container">
{activeModule !== "simulation" && (
<>
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""}`}
onClick={() => {
setSubModule("properties");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">properties</div>
<PropertiesIcon isActive={subModule === "properties"} />
</button>
</>
)}
{activeModule === "simulation" && (
<>
<button
id="sidebar-action-list-simulation"
className={`sidebar-action-list ${subModule === "simulations" ? "active" : ""}`}
onClick={() => {
setSubModule("simulations");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">simulations</div>
<SimulationIcon isActive={subModule === "simulations"} />
</button>
<button
id="sidebar-action-list-mechanics"
className={`sidebar-action-list ${subModule === "mechanics" ? "active" : ""}`}
onClick={() => {
setSubModule("mechanics");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">mechanics</div>
<MechanicsIcon isActive={subModule === "mechanics"} />
</button>
<button
id="sidebar-action-list-analysis"
className={`sidebar-action-list ${subModule === "analysis" ? "active" : ""}`}
onClick={() => {
setSubModule("analysis");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">analysis</div>
<AnalysisIcon isActive={subModule === "analysis"} />
</button>
</>
)}
{(activeModule === "builder" || activeModule === "simulation") && (
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${subModule === "resourceManagement" ? "active" : ""}`}
onClick={() => {
setSubModule("resourceManagement");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">Resource Management</div>
<FilePackageIcon isActive={subModule === "resourceManagement"} />
</button>
)}
</div>
)}
{displayComponent !== "none" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
{renderComponent()}
{/* <ResourceManagement /> */}
</div>
</div>
)}
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${
subModule === "properties" ? "active" : ""
}`}
onClick={() => {
setSubModule("properties");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">properties</div>
<PropertiesIcon isActive={subModule === "properties"} />
</button>
</>
)}
</div>
);
)}
{activeModule === "simulation" && (
<>
<button
id="sidebar-action-list-simulation"
className={`sidebar-action-list ${
subModule === "simulations" ? "active" : ""
}`}
onClick={() => {
setSubModule("simulations");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">simulations</div>
<SimulationIcon isActive={subModule === "simulations"} />
</button>
<button
id="sidebar-action-list-mechanics"
className={`sidebar-action-list ${
subModule === "mechanics" ? "active" : ""
}`}
onClick={() => {
setSubModule("mechanics");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">mechanics</div>
<MechanicsIcon isActive={subModule === "mechanics"} />
</button>
<button
id="sidebar-action-list-analysis"
className={`sidebar-action-list ${
subModule === "analysis" ? "active" : ""
}`}
onClick={() => {
setSubModule("analysis");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">analysis</div>
<AnalysisIcon isActive={subModule === "analysis"} />
</button>
</>
)}
{(activeModule === "builder" ||
activeModule === "simulation") && (
<button
id="sidebar-action-list-properties"
className={`sidebar-action-list ${
subModule === "resourceManagement" ? "active" : ""
}`}
onClick={() => {
setSubModule("resourceManagement");
setVersionHistoryVisible(false);
}}
>
<div className="tooltip">Resource Management</div>
<FilePackageIcon
isActive={subModule === "resourceManagement"}
/>
</button>
)}
</div>
)}
{displayComponent !== "none" && (
<div className="sidebar-right-container">
<div className="sidebar-right-content-container">
{renderComponent()}
{/* <ResourceManagement /> */}
</div>
</div>
)}
</>
)}
</div>
);
};
export default SideBarRight;
export default SideBarRight;

View File

@@ -1,6 +1,4 @@
import React from "react";
import { EyeDroperIcon } from "../../../icons/ExportCommonIcons";
// import { useThree } from "@react-three/fiber";
interface PositionInputProps {
onChange: (value: [number, number, number]) => void; // Callback for value change
@@ -24,7 +22,7 @@ const Vector3Input: React.FC<PositionInputProps> = ({
if (!value) return;
const updatedValue = [...value] as [number, number, number];
updatedValue[index] = parseFloat(newValue) || 0;
// console.log('updatedValue: ', updatedValue);
console.log('updatedValue: ', updatedValue);
onChange(updatedValue);
};
@@ -42,8 +40,8 @@ const Vector3Input: React.FC<PositionInputProps> = ({
<input
className="custom-input-field"
type={type}
value={value?.[i] !== undefined ? value[i].toFixed(2) : ""}
// onChange={(e) => handleChange(i, e.target.value)}
value={value?.[i] !== undefined ? value[i].toFixed(1) : ""}
onChange={(e) => handleChange(i, e.target.value)}
placeholder={placeholder}
disabled={disabled}
/>

View File

@@ -1,59 +0,0 @@
import React, { useState } from 'react';
import RotationInput from '../customInput/RotationInput';
import PositionInput from '../customInput/PositionInputs';
import { LockIcon } from '../../../icons/RealTimeVisulationIcons';
import { LayeringBottomIcon, LayeringTopIcon, ValueUpdateIcon } from '../../../icons/ExportCommonIcons';
import decalImage from "../../../../assets/image/sampleDecal.png"
const DecalTransformation = () => {
return (
<div className='decal-transformation-container'>
{["position", "rotation", "scale"].map((transformation) => (
<div className="transformation-wrapper">
<div className="header">{transformation}</div>
<div className="input-wrapppers">
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
<div className="icon"><LockIcon /></div>
</div>
</div>
))}
<div className="transformation-wrapper opacity">
<div className="header">opacity</div>
<div className="input-wrapppers">
<input type="number" name="" id="" />
<div className="icon"><ValueUpdateIcon /></div>
</div>
</div>
<div className="transformation-wrapper opacity">
<div className="header">Layering</div>
<div className="layers">
<div className="icon">
<LayeringBottomIcon />
</div>
<div className="icon">
<LayeringTopIcon />
</div>
</div>
</div>
<div className="preview">
<img src={decalImage} alt="" />
<div className="replace-btn">replace</div>
</div>
</div>
);
};
export default DecalTransformation;

View File

@@ -103,32 +103,32 @@ const AssetProperties: React.FC = () => {
</section>
<div className="header">Animations</div>
<section className="animations-lists">
{assets.map((asset) => (
<>
{asset.modelUuid === selectedFloorItem.uuid &&
asset.animations &&
asset.animations.length > 0 &&
asset.animations.map((animation, index) => (
<div key={index} className="animations-list-wrapper">
<div
onClick={() => handleAnimationClick(animation)}
onMouseEnter={() => setHoveredIndex(index)}
onMouseLeave={() => setHoveredIndex(null)}
className="animations-list"
style={{
background:
hoveredIndex === index
? "#7b4cd3"
: "var(--background-color)",
}}
>
{animation.charAt(0).toUpperCase() +
animation.slice(1).toLowerCase()}
</div>
</div>
))}
</>
))}
{assets.map((asset) => {
if (asset.modelUuid !== selectedFloorItem.uuid || !asset.animations)
return null;
return asset.animations.map((animation, index) => (
<div key={index} className="animations-list-wrapper">
<div
onClick={() => handleAnimationClick(animation)}
onMouseEnter={() => setHoveredIndex(index)}
onMouseLeave={() => setHoveredIndex(null)}
className="animations-list"
style={{
background:
hoveredIndex === index
? "var(--background-color-button)"
: "var(--background-color)",
color:
hoveredIndex === index ? "var(--text-button-color)" : "",
}}
>
{animation.charAt(0).toUpperCase() +
animation.slice(1).toLowerCase()}
</div>
</div>
));
})}
</section>
</div>
);

View File

@@ -0,0 +1,53 @@
import {
LayeringBottomIcon,
LayeringTopIcon,
} from "../../../icons/ExportCommonIcons";
import InputRange from "../../../ui/inputs/InputRange";
import RotationInput from "../customInput/RotationInput";
import Vector3Input from "../customInput/Vector3Input";
const DecalProperties = () => {
return (
<div className="decal-transformation-container">
<div className="header">Decal Propertis</div>
<section>
<RotationInput
onChange={() => {}}
value={10}
/>
<Vector3Input
onChange={(value) => console.log(value)}
header="Scale"
value={[0, 0, 0] as [number, number, number]}
/>
</section>
<section>
<InputRange
label="Opacity"
value={1}
min={0}
step={0.1}
max={1}
onChange={(value: number) => console.log(value)}
key={"6"}
/>
<div className="transformation-wrapper opacity">
<div className="transformation-header">Layering</div>
<div className="layers-list">
<button className="layer-move-btn">
<LayeringBottomIcon />
</button>
<button className="layer-move-btn">
<LayeringTopIcon />
</button>
</div>
</div>
</section>
</div>
);
};
export default DecalProperties;