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 { createPortal } from "react-dom";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import img from "../../assets/image/image.png"; import img from "../../assets/image/image.png";
import { getUserData } from "../../functions/getUserData";
import { useLoadingProgress, useProjectName } from "../../store/builder/store"; import { useLoadingProgress, useProjectName } from "../../store/builder/store";
import OuterClick from "../../utils/outerClick";
import { KebabIcon } from "../icons/ExportCommonIcons"; import { KebabIcon } from "../icons/ExportCommonIcons";
import { getAllProjectsApi } from "../../services/dashboard/getAllProjectsApi"; import { getAllProjectsApi } from "../../services/dashboard/getAllProjectsApi";
import { useSocketStore } from "../../store/socket/useSocketStore"; import { useSocketStore } from "../../store/socket/useSocketStore";
import { getUserData } from "../../functions/getUserData";
import OuterClick from "../../utils/outerClick";
import { Modal } from "../templates/PreviewModal"; import { Modal } from "../templates/PreviewModal";
// import { viewProject } from "../../services/dashboard/viewProject"; // import { viewProject } from "../../services/dashboard/viewProject";
// import { updateProject } from "../../services/dashboard/updateProject"; // import { updateProject } from "../../services/dashboard/updateProject";

View File

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

View File

@@ -1,52 +1,53 @@
import React from "react"; import React from "react";
import { useNavigate } from "react-router-dom";
import { ToggleSidebarIcon } from "../../icons/HeaderIcons"; import { ToggleSidebarIcon } from "../../icons/HeaderIcons";
import { LogoIcon } from "../../icons/Logo"; import { LogoIcon } from "../../icons/Logo";
import FileMenu from "../../ui/FileMenu";
import { useToggleStore } from "../../../store/ui/useUIToggleStore"; import { useToggleStore } from "../../../store/ui/useUIToggleStore";
import { useSceneStore } from "../../../store/scene/useSceneStore";
import useModuleStore from "../../../store/ui/useModuleStore"; import useModuleStore from "../../../store/ui/useModuleStore";
import { useNavigate } from "react-router-dom";
import useRestStates from "../../../hooks/useResetStates"; import useRestStates from "../../../hooks/useResetStates";
import FileMenu from "../../ui/FileMenu";
const Header: React.FC = () => { const Header: React.FC = () => {
const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore(); const navigate = useNavigate();
const { activeModule } = useModuleStore(); const { setLayoutType } = useSceneStore();
const navigate = useNavigate(); const { toggleUILeft, toggleUIRight, setToggleUI } = useToggleStore();
const { resetStates } = useRestStates(); const { activeModule } = useModuleStore();
const { resetStates } = useRestStates();
return ( return (
<div className="header-container"> <div className="header-container">
<div className="header-content"> <div className="header-content">
<button <button
className="logo-container" className="logo-container"
onClick={() => { onClick={() => {
resetStates(); resetStates();
navigate("/Dashboard") navigate("/Dashboard");
}} setLayoutType(null);
title="Back to Dashboard" }}
> title="Back to Dashboard"
<LogoIcon /> >
</button> <LogoIcon />
<div className="header-title"> </button>
<FileMenu /> <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>
</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; export default Header;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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