added usecase to all the builder and simulation fetched

This commit is contained in:
2025-09-22 10:44:58 +05:30
parent 47d8f8adb1
commit 2b74d00740
11 changed files with 167 additions and 122 deletions

View File

@@ -2,12 +2,12 @@ import React, { useState, useRef, useCallback, useEffect } from "react";
import { createPortal } from "react-dom";
import { useNavigate } from "react-router-dom";
import img from "../../assets/image/image.png";
import { getUserData } from "../../functions/getUserData";
import { useLoadingProgress, useProjectName } from "../../store/builder/store";
import OuterClick from "../../utils/outerClick";
import { KebabIcon } from "../icons/ExportCommonIcons";
import { getAllProjectsApi } from "../../services/dashboard/getAllProjectsApi";
import { useSocketStore } from "../../store/socket/useSocketStore";
import { getUserData } from "../../functions/getUserData";
import OuterClick from "../../utils/outerClick";
import { Modal } from "../templates/PreviewModal";
// import { viewProject } from "../../services/dashboard/viewProject";
// import { updateProject } from "../../services/dashboard/updateProject";

View File

@@ -83,6 +83,7 @@ function MainScene() {
getVersionHistoryApi(projectId)
.then((data) => {
if (!data.versions) return;
const versions: VersionHistory = [];
data.versions.forEach((version: any) => {
versions.push({

View File

@@ -1,52 +1,53 @@
import React from "react";
import { useNavigate } from "react-router-dom";
import { ToggleSidebarIcon } from "../../icons/HeaderIcons";
import { LogoIcon } from "../../icons/Logo";
import FileMenu from "../../ui/FileMenu";
import { useToggleStore } from "../../../store/ui/useUIToggleStore";
import { useSceneStore } from "../../../store/scene/useSceneStore";
import useModuleStore from "../../../store/ui/useModuleStore";
import { useNavigate } from "react-router-dom";
import useRestStates from "../../../hooks/useResetStates";
import FileMenu from "../../ui/FileMenu";
const Header: React.FC = () => {
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
const { activeModule } = useModuleStore();
const navigate = useNavigate();
const { resetStates } = useRestStates();
const navigate = useNavigate();
const { setLayoutType } = useSceneStore();
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
const { activeModule } = useModuleStore();
const { resetStates } = useRestStates();
return (
<div className="header-container">
<div className="header-content">
<button
className="logo-container"
onClick={() => {
resetStates();
navigate("/Dashboard")
}}
title="Back to Dashboard"
>
<LogoIcon />
</button>
<div className="header-title">
<FileMenu />
return (
<div className="header-container">
<div className="header-content">
<button
className="logo-container"
onClick={() => {
resetStates();
navigate("/Dashboard");
setLayoutType(null);
}}
title="Back to Dashboard"
>
<LogoIcon />
</button>
<div className="header-title">
<FileMenu />
</div>
</div>
<button
id="toggle-leftSidebar-ui-button"
className={`toggle-sidebar-ui-button ${!toggleUILeft ? "active" : ""}`}
onClick={() => {
if (activeModule !== "market") {
setToggleUI(!toggleUILeft, toggleUIRight);
localStorage.setItem("navBarUiLeft", JSON.stringify(!toggleUILeft));
}
}}
>
<div className="tooltip">{toggleUILeft ? "Hide" : "Show"} sidebar (ctrl + [)</div>
<ToggleSidebarIcon />
</button>
</div>
</div>
<button
id="toggle-leftSidebar-ui-button"
className={`toggle-sidebar-ui-button ${!toggleUILeft ? "active" : ""}`}
onClick={() => {
if (activeModule !== "market") {
setToggleUI(!toggleUILeft, toggleUIRight);
localStorage.setItem("navBarUiLeft", JSON.stringify(!toggleUILeft));
}
}}
>
<div className="tooltip">
{toggleUILeft ? "Hide" : "Show"} sidebar (ctrl + [)
</div>
<ToggleSidebarIcon />
</button>
</div >
);
);
};
export default Header;

View File

@@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom";
import { ArrowIcon } from "../../icons/ExportCommonIcons";
import { toggleTheme } from "../../../utils/theme";
import { useShortcutStore } from "../../../store/builder/store";
import { useSceneStore } from "../../../store/scene/useSceneStore";
import useModuleStore, { useSubModuleStore } from "../../../store/ui/useModuleStore";
import { useSceneContext } from "../../../modules/scene/sceneContext";
@@ -20,6 +21,7 @@ interface MenuItem {
const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
const navigate = useNavigate();
const { setLayoutType } = useSceneStore();
const [activeMenu, setActiveMenu] = useState<string | null>(null);
const [activeSubMenu, setActiveSubMenu] = useState<string | null>(null);
const [selectedItems, setSelectedItems] = useState<Record<string, boolean>>({});
@@ -50,6 +52,7 @@ const MenuBar: React.FC<MenuBarProps> = ({ setOpenMenu }) => {
localStorage.clear();
localStorage.setItem("theme", theme);
navigate("/");
setLayoutType(null);
};
function handleShotcutsHelper() {

View File

@@ -63,11 +63,21 @@ type SceneContextValue = {
clearStores: () => void;
layout: "Main Layout" | "Comparison Layout";
layoutType: "project" | "usecase" | "tutorial" | null;
};
const SceneContext = createContext<SceneContextValue | null>(null);
export function SceneProvider({ children, layout }: { readonly children: React.ReactNode; readonly layout: "Main Layout" | "Comparison Layout" }) {
export function SceneProvider({
children,
layout,
layoutType,
}: {
readonly children: React.ReactNode;
readonly layout: "Main Layout" | "Comparison Layout";
readonly layoutType: "project" | "usecase" | "tutorial" | null;
}) {
const versionStore = useMemo(() => createVersionStore(), []);
const assetStore = useMemo(() => createAssetStore(), []);
@@ -177,6 +187,7 @@ export function SceneProvider({ children, layout }: { readonly children: React.R
craneEventManagerRef,
clearStores,
layout,
layoutType,
}),
[
versionStore,
@@ -202,6 +213,7 @@ export function SceneProvider({ children, layout }: { readonly children: React.R
collabUsersStore,
clearStores,
layout,
layoutType,
]
);

View File

@@ -75,13 +75,7 @@ const RealTimeVisulization: React.FC = () => {
useEffect(() => {
if (!projectId || !selectedVersion) return;
getZone2dData(organization, projectId, selectedVersion?.versionId || "").then((response) => {
// console.log('response: ', response);
if (!response) return;
// if (response.status === 401) {
// console.log("force logout");
// navigate("/");
// return;
// }
if (!Array.isArray(response)) {
return;
}

View File

@@ -1,17 +1,19 @@
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useSocketStore } from "../store/socket/useSocketStore";
import { getUserData } from "../functions/getUserData";
import { useSceneStore } from "../store/scene/useSceneStore";
import SidePannel from "../components/Dashboard/SidePannel";
import DashboardTutorial from "../components/Dashboard/DashboardTutorial";
import DashboardMain from "../components/Dashboard/DashboardMain";
import DashboardUseCases from "../components/Dashboard/DasboardUseCases";
import ProjectSocketRes from "../components/Dashboard/socket/projectSocketRes";
import { useNavigate } from "react-router-dom";
import { getUserData } from "../functions/getUserData";
export const ALPHA_ORG = "hexrfactory";
const Dashboard: React.FC = () => {
const navigate = useNavigate();
const { setLayoutType } = useSceneStore();
const [activeTab, setActiveTab] = useState<string>("Home");
const [projectsData, setProjectsData] = useState<DashboardProjectCollection>({});
const [projectsCache, setProjectsCache] = useState<Record<string, DashboardProjectCollection>>({});
@@ -21,6 +23,7 @@ const Dashboard: React.FC = () => {
useEffect(() => {
if (email === "" || organization === "") {
navigate("/");
setLayoutType(null);
}
const token = localStorage.getItem("token");
const refreshToken = localStorage.getItem("refreshToken");

View File

@@ -1,57 +1,55 @@
import { useLocation, useNavigate } from "react-router-dom";
import { useSceneStore } from "../store/scene/useSceneStore";
import text404 from "../assets/image/404/404.svg";
import hero from "../assets/image/404/404_bk.png";
const PageNotFound = () => {
const savedTheme = localStorage.getItem("theme");
const isLogedIn = localStorage.getItem("userId");
const navigate = useNavigate();
const { hash } = useLocation();
const navigate = useNavigate();
const { hash } = useLocation();
const { setLayoutType } = useSceneStore();
const savedTheme = localStorage.getItem("theme");
const isLogedIn = localStorage.getItem("userId");
function getErrorContext() {
const contexts = hash.split("#");
const context = contexts[1];
const info = contexts.length > 1 ? contexts[2] : "";
switch (context) {
case "project_not_found":
return `Project Not found - The project ${
info !== "" && `with ID (${info})`
} was not found.`;
default:
return "Page not Found - looks like we have hit a roadblock";
function getErrorContext() {
const contexts = hash.split("#");
const context = contexts[1];
const info = contexts.length > 1 ? contexts[2] : "";
switch (context) {
case "project_not_found":
return `Project Not found - The project ${info !== "" && `with ID (${info})`} was not found.`;
default:
return "Page not Found - looks like we have hit a roadblock";
}
}
}
return (
<div className="page-not-found-wrapper">
<div className="page-not-found-container">
<div className="text-404">
<img
src={text404}
alt=""
style={savedTheme === "dark" ? { filter: "invert(1)" } : {}}
/>
return (
<div className="page-not-found-wrapper">
<div className="page-not-found-container">
<div className="text-404">
<img src={text404} alt="" style={savedTheme === "dark" ? { filter: "invert(1)" } : {}} />
</div>
<div className="hero-container">
<img src={hero} alt="" />
</div>
<div className="context">{getErrorContext()}</div>
<button
className="back-to-home"
id="go-back-home-404-btn"
onClick={() => {
if (isLogedIn) {
navigate("/Dashboard");
setLayoutType(null);
} else {
navigate("/");
setLayoutType(null);
}
}}
>
Go Back to Home
</button>
</div>
</div>
<div className="hero-container">
<img src={hero} alt="" />
</div>
<div className="context">{getErrorContext()}</div>
<button
className="back-to-home"
id="go-back-home-404-btn"
onClick={() => {
if (isLogedIn) {
navigate("/Dashboard");
} else {
navigate("/");
}
}}
>
Go Back to Home
</button>
</div>
</div>
);
);
};
export default PageNotFound;

View File

@@ -3,13 +3,12 @@ import { useNavigate, useParams } from "react-router-dom";
import useModuleStore from "../store/ui/useModuleStore";
import { useSocketStore } from "../store/socket/useSocketStore";
import { useSelectedUserStore } from "../store/collaboration/useCollabStore";
import { useSceneStore } from "../store/scene/useSceneStore";
import { useProjectName, useActiveTool } from "../store/builder/store";
import { handleCanvasCursors } from "../utils/mouseUtils/handleCanvasCursors";
import { getUserData } from "../functions/getUserData";
import { viewProjectApi } from "../services/dashboard/viewProjectApi";
import { getAllProjectsApi } from "../services/dashboard/getAllProjectsApi";
import { sharedWithMeProjectsApi } from "../services/dashboard/sharedWithMeProjectApi";
import { useLogger } from "../components/ui/log/LoggerContext";
import { SceneProvider } from "../modules/scene/sceneContext";
@@ -22,6 +21,7 @@ import ComparisonScene from "../components/layout/scenes/ComparisonScene";
const Project: React.FC = () => {
let navigate = useNavigate();
const { layoutType, setLayoutType } = useSceneStore();
const echo = useLogger();
const { setActiveModule } = useModuleStore();
const {
@@ -47,26 +47,25 @@ const Project: React.FC = () => {
if (!email || !userId) {
console.error("User data not found in localStorage");
navigate("/page-not-found");
setLayoutType(null);
return;
}
const fetchProjects = async () => {
try {
const projects = await getAllProjectsApi();
const shared = await sharedWithMeProjectsApi();
const allProjects = [...(projects?.Projects || []), ...(shared?.Shared || [])];
const matchedProject = allProjects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
if (matchedProject) {
setProjectName(matchedProject.projectName);
await viewProjectApi(matchedProject._id);
} else {
console.warn("Project not found with given ID:", projectId);
navigate(`/not_found#project_not_found#${projectId}`);
}
} catch (error) {
console.error("Error fetching projects:", error);
}
viewProjectApi(projectId || "")
.then((project) => {
if (project.projectData) {
setProjectName(project.projectData.projectName);
setLayoutType(project.projectData.projectType);
} else {
console.warn("Project not found with given ID:", projectId);
navigate(`/not_found#project_not_found#${projectId}`);
setLayoutType(null);
}
})
.catch(() => {
console.warn("Error fetching project:", projectId);
});
};
fetchProjects();
@@ -77,13 +76,14 @@ const Project: React.FC = () => {
useEffect(() => {
const token = localStorage.getItem("token");
const refreshToken = localStorage.getItem("refreshToken");
if (token && refreshToken && projectId) {
echo.warn("Validating token");
initializeBuilderSocket(token, refreshToken, projectId);
echo.success("Builder socket initialized");
} else {
navigate("/");
setLayoutType(null);
return;
}
@@ -98,12 +98,13 @@ const Project: React.FC = () => {
useEffect(() => {
const token = localStorage.getItem("token");
const refreshToken = localStorage.getItem("refreshToken");
if (token && refreshToken && projectId) {
initializeVisualizationSocket(token, refreshToken, projectId);
echo.success("Visualization socket initialized");
} else {
navigate("/");
setLayoutType(null);
return;
}
@@ -118,12 +119,13 @@ const Project: React.FC = () => {
useEffect(() => {
const token = localStorage.getItem("token");
const refreshToken = localStorage.getItem("refreshToken");
if (token && refreshToken && projectId) {
initializeThreadSocket(token, refreshToken, projectId);
echo.success("Thread socket initialized");
} else {
navigate("/");
setLayoutType(null);
return;
}
@@ -141,10 +143,10 @@ const Project: React.FC = () => {
return (
<div className="project-main">
<SceneProvider layout="Main Layout">
<SceneProvider layout="Main Layout" layoutType={layoutType}>
<MainScene />
</SceneProvider>
<SceneProvider layout="Comparison Layout">
<SceneProvider layout="Comparison Layout" layoutType={layoutType}>
<ComparisonScene />
</SceneProvider>
{selectedUser && <FollowPerson />}

View File

@@ -1,15 +1,17 @@
import React, { useState, FormEvent, useEffect } from "react";
import FingerprintJS from "@fingerprintjs/fingerprintjs";
import { useNavigate } from "react-router-dom";
import { LogoIconLarge } from "../components/icons/Logo";
import { EyeIcon } from "../components/icons/ExportCommonIcons";
import { useLoadingProgress } from "../store/builder/store";
import { useSceneStore } from "../store/scene/useSceneStore";
import { signInApi } from "../services/factoryBuilder/signInSignUp/signInApi";
import { signUpApi } from "../services/factoryBuilder/signInSignUp/signUpApi";
import FingerprintJS from "@fingerprintjs/fingerprintjs";
import { recentlyViewedApi } from "../services/dashboard/recentlyViewedApi";
import { getUserData } from "../functions/getUserData";
const UserAuth: React.FC = () => {
const { setLayoutType } = useSceneStore();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
@@ -55,10 +57,12 @@ const UserAuth: React.FC = () => {
navigate(`/projects/${recent_opend_projectID}`);
} else {
navigate("/Dashboard");
setLayoutType(null);
}
} else {
setLoadingProgress(1);
navigate("/Dashboard");
setLayoutType(null);
}
}
} catch (error) {
@@ -71,6 +75,7 @@ const UserAuth: React.FC = () => {
} else if (res.message === "Already LoggedIn on another browser....Please logout!!!") {
setError("Already logged in on another browser. Please logout first.");
navigate("/");
setLayoutType(null);
setError("");
}
} catch {
@@ -168,11 +173,25 @@ const UserAuth: React.FC = () => {
</form>
<p className="policy">
By signing up for, or logging into, an account, you agree to our{" "}
<span className="link" onClick={() => navigate("/privacy")} style={{ cursor: "pointer" }}>
<span
className="link"
onClick={() => {
navigate("/privacy");
setLayoutType(null);
}}
style={{ cursor: "pointer" }}
>
privacy policy
</span>{" "}
&{" "}
<span className="link" onClick={() => navigate("/terms")} style={{ cursor: "pointer" }}>
<span
className="link"
onClick={() => {
navigate("/terms");
setLayoutType(null);
}}
style={{ cursor: "pointer" }}
>
terms of service
</span>{" "}
whether you read them or not. You can also find these terms on our website.

View File

@@ -17,6 +17,10 @@ type SceneStore = {
setCamera: (pos: THREE.Vector3, target: THREE.Vector3) => void;
setCamType: (type: "orthographic" | "perspective") => void;
layoutType: "project" | "usecase" | "tutorial" | null;
setLayoutType: (layoutType: "project" | "usecase" | "tutorial" | null) => void;
};
export const useSceneStore = create<SceneStore>()(
@@ -55,5 +59,13 @@ export const useSceneStore = create<SceneStore>()(
state.camType = type;
});
},
layoutType: null,
setLayoutType: (layoutType) => {
set((state) => {
state.layoutType = layoutType;
});
},
}))
);