added dashboard with add delete and recently view the projects

This commit is contained in:
Poovizhi99 2025-05-19 14:50:33 +05:30
parent eebc91831d
commit 0ecb85a211
33 changed files with 1467 additions and 288 deletions

View File

@ -2,10 +2,13 @@
PORT=8200
# Base URL for the server socket API, used for real-time communication (e.g., WebSockets).
REACT_APP_SERVER_SOCKET_API_BASE_URL=185.100.212.76:8000
REACT_APP_SERVER_SOCKET_API_BASE_URL=192.168.0.110:8000
# REACT_APP_SERVER_SOCKET_API_BASE_URL=185.100.212.76:8000
# Base URL for the server REST API, used for HTTP requests to the backend server.
REACT_APP_SERVER_REST_API_BASE_URL=185.100.212.76:5000
REACT_APP_SERVER_REST_API_BASE_URL=192.168.0.110:5000
# REACT_APP_SERVER_REST_API_BASE_URL=192.168.0.102:5000
# REACT_APP_SERVER_REST_API_BASE_URL=185.100.212.76:5000
# Base URL for the server marketplace, used for market place model blob.
REACT_APP_SERVER_MARKETPLACE_URL=185.100.212.76:50011

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Dashboard from "./pages/Dashboard";
import Project from "./pages/Project";
@ -7,13 +7,24 @@ import "./styles/main.scss";
import { LoggerProvider } from "./components/ui/log/LoggerContext";
const App: React.FC = () => {
useEffect(() => {
const handlePopState = () => {
window.location.reload();
};
window.addEventListener("popstate", handlePopState);
return () => {
window.removeEventListener("popstate", handlePopState);
};
}, []);
return (
<LoggerProvider>
<Router>
<Routes>
<Route path="/" element={<UserAuth />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/project" element={<Project />} />
<Route path="/:projectId" element={<Project />} />
</Routes>
</Router>
</LoggerProvider>

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

View File

@ -1,25 +1,78 @@
import React from "react";
import { KebabIcon } from "../../icons/ExportCommonIcons";
import img from "../../../assets/image/image.png"
import img from "../../../assets/image/image.png";
import { useNavigate } from "react-router-dom";
import { useProjectName } from "../../../store/builder/store";
import { viewProject } from "../../../services/dashboard/viewProject";
import { getUserData } from "./functions/getUserData";
interface DashBoardCardProps {
projectName: string;
thumbnail: any;
projectId: string;
handleDeleteProject?: (projectId: string) => Promise<void>;
handleRestoreProject?: (projectId: string) => Promise<void>;
}
const DashboardCard: React.FC<DashBoardCardProps> = ({
projectName,
handleDeleteProject,
thumbnail,
projectId,
handleRestoreProject,
}) => {
let navigate = useNavigate();
const { setProjectName } = useProjectName();
const { userId, organization, userName } = getUserData();
const handleKebabIconClick = async () => {
try {
if (handleRestoreProject) {
await handleRestoreProject(projectId);
} else if (handleDeleteProject) {
await handleDeleteProject(projectId);
}
} catch { }
};
const navigateToProject = async () => {
try {
const viewedProject = await viewProject(organization, projectId, userId);
console.log("Saved viewwdProject:", viewedProject);
} catch (error) {
console.error("Error deleting project:", error);
}
setProjectName(projectName);
navigate(`/${projectId}`);
};
const DashboardCard:React.FC = () => {
return (
<div className="dashboard-card-container">
<div className="dashboard-card-container" onClick={navigateToProject} title={projectName}>
<div className="preview-container">
<img src={img} alt="" />
{thumbnail ? <img src={thumbnail} alt="" /> : <img src={img} alt="" />}
</div>
<div className="project-details-container">
<div className="project-details">
<div className="project-name">Untitled</div>
<div className="project-name">{projectName}</div>
<div className="project-data">24-12-2025</div>
</div>
<div className="users-list-container">
<div className="user-profile">V</div>
<KebabIcon />
<div className="user-profile">
{userName ? userName.charAt(0).toUpperCase() : "Anonymous"}
</div>
<div
onClick={(e) => {
e.stopPropagation();
handleKebabIconClick();
}}
>
<KebabIcon />
</div>
</div>
</div>
</div>
);
};
export default DashboardCard;
export default DashboardCard;

View File

@ -1,21 +1,137 @@
import React from "react";
import React, { useEffect, useState } from "react";
import DashboardCard from "./DashboardCard";
import DashboardNavBar from "./DashboardNavBar";
import MarketPlaceBanner from "./MarketPlaceBanner";
import { recentlyViewed } from "../../../services/dashboard/recentlyViewed";
import { getUserData } from "./functions/getUserData";
import { searchProject } from "../../../services/dashboard/searchProjects";
import { deleteProject } from "../../../services/dashboard/deleteProject";
import { useSocketStore } from "../../../store/builder/store";
interface Project {
_id: string;
projectName: string;
thumbnail: string;
createdBy: string;
projectUuid?: string;
}
interface RecentProjectsData {
[key: string]: Project[];
}
const DashboardHome: React.FC = () => {
const [recentProjects, setRecentProjects] = useState<RecentProjectsData>({});
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
const { userId, organization } = getUserData();
const { dashBoardSocket } = useSocketStore();
const fetchRecentProjects = async () => {
try {
const projects = await recentlyViewed(organization, userId);
if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) {
setRecentProjects(projects);
}
} catch (error) {
console.error("Error fetching recent projects:", error);
}
};
const handleRecentProjectSearch = async (inputValue: string) => {
if (!inputValue.trim()) {
setIsSearchActive(false);
return;
}
const filterRecentProcess = await searchProject(organization, userId, inputValue);
setIsSearchActive(true);
setRecentProjects(filterRecentProcess.message ? {} : filterRecentProcess);
};
const handleDeleteProject = async (projectId: any) => {
try {
//API for delete project
// const deletedProject = await deleteProject(
// projectId,
// userId,
// Organization
// );
//socket for delete Project
const deleteProject = {
projectId,
organization,
userId,
};
if (dashBoardSocket) {
const handleResponse = (data: any) => {
console.log("Project add response:", data);
dashBoardSocket.off("v1-project:response:delete", handleResponse);
};
dashBoardSocket.on("v1-project:response:delete", handleResponse);
dashBoardSocket.emit("v1:project:delete", deleteProject);
}
setRecentProjects((prevDiscardedProjects: RecentProjectsData) => {
if (!Array.isArray(prevDiscardedProjects?.RecentlyViewed)) {
return prevDiscardedProjects;
}
const updatedProjectDatas = prevDiscardedProjects.RecentlyViewed.filter(
(project) => project._id !== projectId
);
return {
...prevDiscardedProjects,
RecentlyViewed: updatedProjectDatas,
};
});
setIsSearchActive(false);
} catch (error) {
console.error("Error deleting project:", error);
}
};
const renderProjects = () => {
const projectList = recentProjects[Object.keys(recentProjects)[0]];
if (!projectList?.length) {
return <div className="empty-state">No recent projects found</div>;
}
return projectList.map((project) => (
<DashboardCard
key={project._id}
projectName={project.projectName}
thumbnail={project.thumbnail}
projectId={project._id}
handleDeleteProject={handleDeleteProject}
/>
));
};
useEffect(() => {
if (!isSearchActive) {
fetchRecentProjects();
}
}, [isSearchActive]);
return (
<div className="dashboard-home-container">
<DashboardNavBar page={"home"} />
<DashboardNavBar
page="home"
handleRecentProjectSearch={handleRecentProjectSearch}
/>
<MarketPlaceBanner />
<div className="container">
<div className="header">Recents</div>
<div className="cards-container">
<DashboardCard />
</div>
<h2 className="section-header">Recent Projects</h2>
<div className="cards-container">{renderProjects()}</div>
</div>
</div>
);
};
export default DashboardHome;
export default DashboardHome;

View File

@ -4,18 +4,40 @@ import Search from "../../ui/inputs/Search";
interface DashboardNavBarProps {
page: React.ReactNode;
handleProjectsSearch?: (inputValue: string) => Promise<void>;
handleTrashSearch?: (inputValue: string) => Promise<void>;
handleRecentProjectSearch?: (inputValue: string) => Promise<void>;
}
const DashboardNavBar: React.FC<DashboardNavBarProps> = ({ page }) => {
const DashboardNavBar: React.FC<DashboardNavBarProps> = ({
page,
handleProjectsSearch,
handleTrashSearch,
handleRecentProjectSearch,
}) => {
const handleSearch = async (inputValue: string) => {
try {
if (handleProjectsSearch) {
await handleProjectsSearch(inputValue);
} else if (handleTrashSearch) {
await handleTrashSearch(inputValue);
} else if (handleRecentProjectSearch) {
await handleRecentProjectSearch(inputValue);
}
} catch (error) {
console.error("Search failed:", error);
}
};
return (
<div className="dashboard-navbar-container">
<div className="title">{page}</div>
<div className="market-place-button">
<CartIcon isActive /> Market Place
</div>
<Search onChange={() => {}} />
<Search onChange={handleSearch} />
</div>
);
};
export default DashboardNavBar;
export default DashboardNavBar;

View File

@ -0,0 +1,155 @@
import React, { useEffect, useState } from 'react';
import DashboardNavBar from './DashboardNavBar';
import DashboardCard from './DashboardCard';
import { getAllProjects } from '../../../services/dashboard/getAllProjects';
import { getUserData } from './functions/getUserData';
import { searchProject } from '../../../services/dashboard/searchProjects';
import { deleteProject } from '../../../services/dashboard/deleteProject';
import { useSocketStore } from '../../../store/builder/store';
interface Project {
_id: string;
projectName: string;
thumbnail: string;
createdBy: string;
projectUuid?: string;
}
interface WorkspaceProjects {
[key: string]: Project[];
}
const DashboardProjects: React.FC = () => {
const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>({});
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
const [activeFolder, setActiveFolder] = useState<string>("myProjects");
const { dashBoardSocket } = useSocketStore();
const { userId, organization } = getUserData();
const fetchAllProjects = async () => {
try {
const projects = await getAllProjects(userId, organization);
if (JSON.stringify(projects) !== JSON.stringify(workspaceProjects)) {
setWorkspaceProjects(projects);
}
} catch (error) {
console.error("Error fetching projects:", error);
}
};
const handleProjectsSearch = async (
inputValue: string
) => {
if (!inputValue.trim()) {
setIsSearchActive(false);
return;
}
if (!setWorkspaceProjects || !setIsSearchActive) return;
const searchedProject = await searchProject(organization, userId, inputValue);
setIsSearchActive(true);
setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
};
const handleDeleteProject = async (projectId: any) => {
try {
const Organization = organization
// const deletedProject = await deleteProject(
// projectId,
// userId,
// Organization
// );
const deleteProject = {
projectId,
organization: organization,
userId
}
if (dashBoardSocket) {
const handleResponse = (data: any) => {
console.log('Project add response:', data);
dashBoardSocket.off("v1-project:response:delete", handleResponse); // Clean up
};
dashBoardSocket.on("v1-project:response:delete", handleResponse);
dashBoardSocket.emit("v1:project:delete", deleteProject);
} else {
console.error("Socket is not connected.");
}
setWorkspaceProjects((prevDiscardedProjects: WorkspaceProjects) => {
if (!Array.isArray(prevDiscardedProjects?.Projects)) {
return prevDiscardedProjects;
}
const updatedProjectDatas = prevDiscardedProjects.Projects.filter(
(project) => project._id !== projectId
);
return {
...prevDiscardedProjects,
Projects: updatedProjectDatas
};
});
setIsSearchActive(false)
} catch (error) {
console.error('Error deleting project:', error);
}
};
const renderProjects = () => {
if (activeFolder !== "myProjects") return null;
const projectList = workspaceProjects[Object.keys(workspaceProjects)[0]];
if (!projectList?.length) {
return <div className="empty-state">No projects found</div>;
}
return projectList.map((project) => (
<DashboardCard
key={project._id}
projectName={project.projectName}
thumbnail={project.thumbnail}
projectId={project._id}
handleDeleteProject={handleDeleteProject}
/>
));
};
useEffect(() => {
if (!isSearchActive) {
fetchAllProjects();
}
}, [isSearchActive]);
return (
<div className="dashboard-home-container">
<DashboardNavBar
page="projects"
handleProjectsSearch={handleProjectsSearch}
/>
<div className="container">
<div className="header" style={{ display: "flex", gap: "7px" }}>
<div
style={{ color: activeFolder === "myProjects" ? "#c4abf1" : "black" }}
onClick={() => setActiveFolder("myProjects")}
>
My Projects
</div>
<div
style={{ color: activeFolder === "shared" ? "#c4abf1" : "black" }}
onClick={() => setActiveFolder("shared")}
>
Shared with me
</div>
</div>
<div className="cards-container">
{renderProjects()}
</div>
</div>
</div>
);
};
export default DashboardProjects;

View File

@ -0,0 +1,122 @@
import React, { useEffect, useState } from 'react';
import { getTrash } from '../../../services/dashboard/getTrash';
import DashboardCard from './DashboardCard';
import DashboardNavBar from './DashboardNavBar';
import { getUserData } from './functions/getUserData';
import { trashSearchProject } from '../../../services/dashboard/trashSearchProject';
import { restoreTrash } from '../../../services/dashboard/restoreTrash';
interface Project {
_id: string;
projectName: string;
thumbnail: string;
createdBy: string;
projectUuid?: string;
}
interface DiscardedProjects {
[key: string]: Project[];
}
const DashboardTrash: React.FC = () => {
const [discardedProjects, setDiscardedProjects] = useState<DiscardedProjects>({});
console.log('discardedProjects: ', discardedProjects);
const [isSearchActive, setIsSearchActive] = useState(false);
const { userId, organization } = getUserData();
const fetchTrashProjects = async () => {
try {
const projects = await getTrash(organization);
console.log('organization: ', organization);
console.log('trashedprojects: ', projects);
if (JSON.stringify(projects) !== JSON.stringify(discardedProjects)) {
setDiscardedProjects(projects);
}
} catch (error) {
console.error('Error fetching trash projects:', error);
}
};
const handleTrashSearch = async (
inputValue: string
) => {
if (!inputValue.trim()) {
setIsSearchActive(false);
return;
}
if (!setDiscardedProjects || !setIsSearchActive) return;
const filterTrashedProcess = await trashSearchProject(organization, userId, inputValue);
setIsSearchActive(true);
setDiscardedProjects(filterTrashedProcess.message ? {} : filterTrashedProcess);
};
const handleRestoreProject = async (projectId: any) => {
try {
const Organization = organization;
const restoreProject = await restoreTrash(
Organization,
projectId
);
setDiscardedProjects((prevDiscardedProjects: DiscardedProjects) => {
// Check if TrashDatas exists and is an array
if (!Array.isArray(prevDiscardedProjects?.TrashDatas)) {
console.error('TrashDatas is not an array', prevDiscardedProjects);
return prevDiscardedProjects;
}
const updatedTrashDatas = prevDiscardedProjects.TrashDatas.filter(
(project) => project._id !== projectId
);
return {
...prevDiscardedProjects,
TrashDatas: updatedTrashDatas
};
});
setIsSearchActive(false)
} catch (error) {
console.error('Error deleting project:', error);
}
};
const renderTrashProjects = () => {
const projectList = discardedProjects[Object.keys(discardedProjects)[0]];
if (!projectList?.length) {
return <div className="empty-state">No deleted projects found</div>;
}
return projectList.map((project) => (
<DashboardCard
key={project._id}
projectName={project.projectName}
thumbnail={project.thumbnail}
projectId={project._id}
handleRestoreProject={handleRestoreProject}
/>
));
};
useEffect(() => {
console.log('isSearchActive:trash ', isSearchActive);
if (!isSearchActive) {
fetchTrashProjects();
}
}, [isSearchActive]);
return (
<div className="dashboard-home-container">
<DashboardNavBar
page="trash"
handleTrashSearch={handleTrashSearch}
/>
<div className="container">
<div className="header" style={{ display: 'flex', gap: '7px' }}></div>
<div className="cards-container">
{renderTrashProjects()}
</div>
</div>
</div>
);
};
export default DashboardTrash;

View File

@ -0,0 +1,62 @@
import React, { useEffect, useState } from 'react';
import { projectTutorial } from '../../../services/dashboard/projectTutorial';
import DashboardNavBar from './DashboardNavBar';
import DashboardCard from './DashboardCard';
interface Project {
_id: string;
projectName: string;
thumbnail: string;
createdBy: string;
projectUuid?: string;
}
interface DiscardedProjects {
[key: string]: Project[];
}
const DashboardTutorial = () => {
const [tutorialProject, setTutorialProject] = useState<DiscardedProjects>({})
const handleIcon = async () => {
try {
let tutorial = await projectTutorial()
setTutorialProject(tutorial)
} catch {
}
}
useEffect(() => {
handleIcon()
}, [])
const renderTrashProjects = () => {
const projectList = tutorialProject[Object.keys(tutorialProject)[0]];
if (!projectList?.length) {
return <div className="empty-state">No deleted projects found</div>;
}
return projectList.map((tutorials: any) => (
<DashboardCard
key={tutorials._id}
projectName={tutorials.projectName}
thumbnail={tutorials.thumbnail}
projectId={tutorials._id}
/>
));
};
return (
<div className="dashboard-home-container">
<DashboardNavBar
page="tutorial"
/>
<div className="container">
<div className="header" style={{ display: 'flex', gap: '7px' }}></div>
<div className="cards-container">
{renderTrashProjects()}
</div>
</div>
</div>
);
}
export default DashboardTutorial;

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect, useState } from "react";
import {
DocumentationIcon,
HelpIcon,
@ -9,40 +9,98 @@ import {
TutorialsIcon,
} from "../../icons/DashboardIcon";
import { SettingsIcon, TrashIcon } from "../../icons/ExportCommonIcons";
import { useNavigate } from "react-router-dom";
import img from "../../../assets/image/image.png"
import darkThemeImage from "../../../assets/image/darkThemeProject.png"
import lightThemeImage from "../../../assets/image/lightThemeProject.png"
import { createProject } from "../../../services/dashboard/createProject";
import { getUserData } from "./functions/getUserData";
import { useSocketStore } from "../../../store/builder/store";
interface SidePannelProps {
setActiveTab: React.Dispatch<React.SetStateAction<string>>;
activeTab: string
}
const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
const { userName, userId, organization } = getUserData();
const navigate = useNavigate();
const { dashBoardSocket } = useSocketStore();
const savedTheme = localStorage.getItem("theme") ?? "light";
function generateProjectId() {
const randomBytes = new Uint8Array(12);
crypto.getRandomValues(randomBytes);
return Array.from(randomBytes, (byte) =>
byte.toString(16).padStart(2, "0")).join("");
}
const handleCreateNewProject = async () => {
try {
const projectId = generateProjectId();
navigate(`/${projectId}`);
//API for creating new Project
// const project = await createProject(
// projectId,
// userId,
// img,
// organization
// );
// console.log('Created project: ', project);
const addProject = {
userId,
thumbnail: savedTheme === "dark" ? darkThemeImage : lightThemeImage,
organization: organization,
projectUuid: projectId,
};
if (dashBoardSocket) {
// console.log('addProject: ', addProject);
const handleResponse = (data: any) => {
console.log('Project add response:', data);
dashBoardSocket.off("v1-project:response:add", handleResponse); // Clean up
};
dashBoardSocket.on("v1-project:response:add", handleResponse);
dashBoardSocket.emit("v1:project:add", addProject);
} else {
console.error("Socket is not connected.");
}
} catch (error) {
console.error("Error creating project:", error);
}
};
const SidePannel: React.FC = () => {
const userName = localStorage.getItem("userName") ?? "Anonymous";
return (
<div className="side-pannel-container">
<div className="side-pannel-header">
<div className="user-container">
<div className="user-profile">{userName[0]}</div>
<div className="user-name">{userName}</div>
<div className="user-profile">{userName?.charAt(0).toUpperCase()}</div>
<div className="user-name">{userName ? userName.charAt(0).toUpperCase() + userName.slice(1).toLowerCase() : "Anonymous"}</div>
</div>
<div className="notifications-container">
<NotificationIcon />
</div>
</div>
<div className="new-project-button">+ New project</div>
<div className="new-project-button" style={{ cursor: "pointer" }} onClick={handleCreateNewProject}>+ New project</div>
<div className="side-bar-content-container">
<div className="side-bar-options-container">
<div className="option-list active">
<div className={activeTab === "Home" ? "option-list active" : "option-list"} onClick={() => setActiveTab("Home")}>
<HomeIcon />
Home
</div>
<div className="option-list" title="coming soon">
<div className={activeTab === "Projects" ? "option-list active" : "option-list"} title="Projects" onClick={() => setActiveTab("Projects")}>
<ProjectsIcon />
Projects
</div>
<div className="option-list" title="coming soon">
<div className={activeTab === "Trash" ? "option-list active" : "option-list"} title="Trash" onClick={() => setActiveTab("Trash")}>
<TrashIcon />
Trash
</div>
<div className="option-list" title="coming soon">
<div className={activeTab === "Tutorials" ? "option-list active" : "option-list"} title="coming soon" onClick={() => setActiveTab("Tutorials")}>
<TutorialsIcon />
Tutorials
</div>
<div className="option-list" title="coming soon">
<div className={activeTab === "Documentation" ? "option-list active" : "option-list"} title="coming soon" onClick={() => setActiveTab("Documentation")}>
<DocumentationIcon />
Documentation
</div>
@ -52,7 +110,7 @@ const SidePannel: React.FC = () => {
<SettingsIcon />
Settings
</div>
<div className="option-list" style={{cursor: "pointer"}}>
<div className="option-list" style={{ cursor: "pointer" }}>
<LogoutIcon />
Log out
</div>

View File

@ -0,0 +1,31 @@
interface UserData {
email: string;
userId: string;
userName?: string; // Optional
organization: string;
}
export const getUserData = (): UserData => {
const email = localStorage.getItem("email");
const userId = localStorage.getItem("userId");
const userName = localStorage.getItem("userName");
if (!email || !userId) {
throw new Error("User data not found in localStorage");
}
const [_, emailDomain] = email.split("@");
if (!emailDomain) {
throw new Error("Invalid email format");
}
const [organization] = emailDomain.split(".");
return {
email: email,
userId: userId,
userName: userName ?? undefined,
organization,
};
};

View File

@ -1,6 +1,9 @@
import React from "react";
import React, { useEffect } from "react";
import RenderOverlay from "./Overlay";
import { LogoIconLarge } from "../icons/Logo";
import { useProjectName } from "../../store/builder/store";
import { useParams } from "react-router-dom";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
interface LoadingPageProps {
progress: number; // Expect progress as a percentage (0-100)
@ -8,12 +11,46 @@ interface LoadingPageProps {
const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
const validatedProgress = Math.min(100, Math.max(0, progress));
const { projectName, setProjectName } = useProjectName();
const { projectId } = useParams();
const generateThumbnail = async () => {
const email = localStorage.getItem("email");
const userId = localStorage.getItem("userId");
try {
if (!email || !userId) {
console.error("User data not found in localStorage");
return;
}
const emailParts = email.split("@");
if (emailParts.length < 2) {
console.error("Invalid email format");
return;
}
const domainParts = emailParts[1].split(".");
const Organization = domainParts[0];
const projects = await getAllProjects(
userId, Organization
);
const filterProject = projects?.Projects.find((val: any) => val.projectUuid === projectId || val._id
=== projectId)
setProjectName(filterProject.projectName)
}
catch {
}
}
useEffect(() => {
generateThumbnail();
}, []);
return (
<RenderOverlay>
<div className="loading-wrapper">
<div className="loading-container">
<div className="project-name">Untitled</div>
<div className="project-name">{projectName}</div>
<div className="loading-hero-container">
<div className="logo">
<LogoIconLarge />

View File

@ -3,10 +3,17 @@ import RenameInput from "./inputs/RenameInput";
import { ArrowIcon } from "../icons/ExportCommonIcons";
import MenuBar from "./menu/menu";
import { ProjectIcon } from "../icons/HeaderIcons";
import { useProjectName, useSocketStore } from "../../store/builder/store";
import { useParams } from "react-router-dom";
import { updateProject } from "../../services/dashboard/updateProject";
import { getAllProjects } from "../../services/dashboard/getAllProjects";
const FileMenu: React.FC = () => {
const [openMenu, setOpenMenu] = useState(false);
const { projectName, setProjectName } = useProjectName();
const { dashBoardSocket } = useSocketStore();
const containerRef = useRef<HTMLButtonElement>(null);
const { projectId } = useParams();
let clickTimeout: NodeJS.Timeout | null = null;
const handleClick = () => {
@ -31,20 +38,65 @@ const FileMenu: React.FC = () => {
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
// project
const [projectName, setProjectName] = useState("Demo Project");
// Load project name from localStorage on mount
useEffect(() => {
const savedName = localStorage.getItem("projectName");
if (savedName) {
setProjectName(savedName);
const handleProjectRename = async (projectName: string) => {
setProjectName(projectName);
if (!projectId) return
// localStorage.setItem("projectName", newName);
try {
const email = localStorage.getItem("email");
const userId = localStorage.getItem("userId");
if (!email || !userId) {
return;
}
const emailParts = email.split("@");
if (emailParts.length < 2) {
return;
}
const domainParts = emailParts[1].split(".");
const Organization = domainParts[0];
const projects = await getAllProjects(
userId, Organization
);
console.log('projects: ', projects);
let projectUuid = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id
=== projectId)
const updateProject = {
projectId: projectUuid,
organization: Organization,
userId,
projectName,
thumbnail: undefined
}
if (dashBoardSocket) {
const handleResponse = (data: any) => {
console.log('Project update response:', data);
dashBoardSocket.off("v1-project:response:update", handleResponse); // Clean up
};
dashBoardSocket.on("v1-project:response:update", handleResponse);
dashBoardSocket.emit("v1:project:update", updateProject);
}
//API for projects rename
// const updatedProjectName = await updateProject(
// projectId,
// userId,
// Organization,
// undefined,
// projectName
// );
//
} catch (error) {
}
}, []);
const handleProjectRename = (newName: string) => {
setProjectName(newName);
localStorage.setItem("projectName", newName);
};
return (

View File

@ -38,9 +38,8 @@ const Search: React.FC<SearchProps> = ({
return (
<div className="search-wrapper">
<div
className={`search-container ${
isFocused || inputValue ? "active" : ""
}`}
className={`search-container ${isFocused || inputValue ? "active" : ""
}`}
>
<div className="icon-container">
<SearchIcon />

View File

@ -7,6 +7,7 @@ import Visualization from "../visualization/visualization";
import Setup from "./setup/setup";
import Simulation from "../simulation/simulation";
import Collaboration from "../collaboration/collaboration";
import { useSocketStore } from "../../store/builder/store";
export default function Scene() {
const map = useMemo(
@ -19,11 +20,13 @@ export default function Scene() {
[]
);
return (
<KeyboardControls map={map}>
<Canvas
id="canvas-container"
eventPrefix="client"
gl={{ powerPreference: "high-performance", antialias: true }}
gl={{ powerPreference: "high-performance", antialias: true, alpha: true, preserveDrawingBuffer: true, }}
onContextMenu={(e) => {
e.preventDefault();
}}

View File

@ -1,14 +1,36 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import SidePannel from '../components/layout/Dashboard/SidePannel';
import DashboardHome from '../components/layout/Dashboard/DashboardHome';
import DashboardProjects from '../components/layout/Dashboard/DashboardProjects';
import DashboardTrash from '../components/layout/Dashboard/DashboardTrash';
import { useOrganization, useSocketStore, useUserName, useZones } from '../store/builder/store';
import { getUserData } from '../components/layout/Dashboard/functions/getUserData';
import DashboardTutorial from '../components/layout/Dashboard/DashboardTutorial';
const Dashboard: React.FC = () => {
const [activeTab, setActiveTab] = useState<string>('Home');
const { setUserName } = useUserName();
const { setOrganization } = useOrganization();
const { userId, organization, email, userName } = getUserData();
useEffect(() => {
if (email) {
useSocketStore.getState().initializeSocket(email, organization, userId);
if (organization && userName) {
setOrganization(organization);
setUserName(userName);
}
}
}, [])
return (
<div className="dashboard-main">
<SidePannel />
<DashboardHome />
<SidePannel setActiveTab={setActiveTab} activeTab={activeTab} />
{activeTab == 'Home' && <DashboardHome />}
{activeTab == 'Projects' && <DashboardProjects />}
{activeTab == 'Trash' && <DashboardTrash />}
{activeTab == 'Tutorials' && <DashboardTutorial />}
</div>
);
};
export default Dashboard;
export default Dashboard;

View File

@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import React, { useEffect, useState } from "react";
import ModuleToggle from "../components/ui/ModuleToggle";
import SideBarLeft from "../components/layout/sidebarLeft/SideBarLeft";
import SideBarRight from "../components/layout/sidebarRight/SideBarRight";
@ -14,8 +14,10 @@ import {
useZones,
useLoadingProgress,
useWidgetSubOption,
useProjectName,
useStartSimulation,
} from "../store/builder/store";
import { useNavigate } from "react-router-dom";
import { useNavigate, useParams } from "react-router-dom";
import { usePlayButtonStore } from "../store/usePlayButtonStore";
import MarketPlace from "../modules/market/MarketPlace";
import LoadingPage from "../components/templates/LoadingPage";
@ -32,19 +34,59 @@ import RenderOverlay from "../components/templates/Overlay";
import LogList from "../components/ui/log/LogList";
import Footer from "../components/footer/Footer";
import SelectFloorPlan from "../components/temporary/SelectFloorPlan";
import { getAllProjects } from "../services/dashboard/getAllProjects";
import { viewProject } from "../services/dashboard/viewProject";
const Project: React.FC = () => {
let navigate = useNavigate();
const echo = useLogger();
const { activeModule, setActiveModule } = useModuleStore();
const { loadingProgress } = useLoadingProgress();
const { loadingProgress, setLoadingProgress } = useLoadingProgress();
const { setUserName } = useUserName();
const { setOrganization } = useOrganization();
const { setFloorItems } = useFloorItems();
const { setWallItems } = useWallItems();
const { setZones } = useZones();
const { projectId } = useParams();
const { setProjectName } = useProjectName();
const generateThumbnail = async () => {
const email = localStorage.getItem("email");
const userId = localStorage.getItem("userId");
try {
if (!email || !userId) {
console.error("User data not found in localStorage");
return;
}
const emailParts = email.split("@");
if (emailParts.length < 2) {
console.error("Invalid email format");
return;
}
const domainParts = emailParts[1].split(".");
const Organization = domainParts[0];
const projects = await getAllProjects(
userId, Organization
);
const filterProject = projects?.Projects.find((val: any) => val.projectUuid === projectId || val._id
=== projectId)
const viewedProject = await viewProject(
Organization,
filterProject._id,
userId,
);
setProjectName(filterProject.projectName)
}
catch {
}
}
useEffect(() => {
generateThumbnail();
}, []);
useEffect(() => {
setFloorItems([]);
setWallItems([]);
@ -53,7 +95,7 @@ const Project: React.FC = () => {
const email = localStorage.getItem("email");
if (email) {
const Organization = email.split("@")[1].split(".")[0];
useSocketStore.getState().initializeSocket(email, Organization);
// useSocketStore.getState().initializeSocket(email, Organization);
const name = localStorage.getItem("userName");
if (Organization && name) {
setOrganization(Organization);
@ -82,6 +124,7 @@ const Project: React.FC = () => {
const { selectedZone } = useSelectedZoneStore();
const { setFloatingWidget } = useFloatingWidget();
return (
<div className="project-main">
{!selectedUser && (

View File

@ -26,19 +26,23 @@ const UserAuth: React.FC = () => {
e.preventDefault();
const organization = email.split("@")[1].split(".")[0];
console.log('email, password, organization: ', email, password, organization);
try {
const res = await signInApi(email, password, organization);
if (res.message === "login successfull") {
setError("");
setOrganization(organization);
setUserName(res.name);
console.log(' res.userId: ', res.userId);
localStorage.setItem("userId", res.userId);
localStorage.setItem("email", res.email);
localStorage.setItem("userName", res.name);
if (res.isShare) {
setLoadingProgress(1);
navigate("/Project");
// navigate("/Project");
navigate("/Dashboard");
}
} else if (res.message === "User Not Found!!! Kindly signup...") {
setError("Account not found");

View File

@ -0,0 +1,38 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
// let url_Backend_dwinzo = `http://192.168.0.110:5000`;
export const createProject = async (
projectUuid: string,
userId: string,
thumbnail: string,
organization: string
) => {
try {
const response = await fetch(`${url_Backend_dwinzo}/api/v1/upsertProject`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
projectUuid,
userId,
thumbnail,
organization,
}),
});
if (!response.ok) {
throw new Error("Failed to add project");
}
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@ -0,0 +1,35 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
export const deleteProject = async (
projectId: string,
userId: string,
organization: string
) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1//Project/archive/${projectId}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ userId, organization }),
}
);
if (!response.ok) {
throw new Error("Failed to clearPanel in the zone");
}
const result = await response.json();
return result;
} catch (error) {
echo.error("Failed to clean pannel");
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@ -0,0 +1,24 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const getAllProjects = async (userId: string, organization: string) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/Projects/${userId}/${organization}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch assets");
}
return await response.json();
} catch (error: any) {
echo.error("Failed to get asset image");
throw new Error(error.message);
}
};

View File

@ -0,0 +1,28 @@
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
// const url_Backend_dwinzo = `http://192.168.0.102:5000`;
export const getTrash = async (organization: string) => {
console.log("Organization:", organization);
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/Trash/Lists?organization=${organization}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch trash data");
}
const data = await response.json();
return data;
} catch (error: any) {
console.error("Failed to fetch trash data:", error);
throw new Error(error.message || "Unknown error");
}
};

View File

@ -0,0 +1,27 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const projectTutorial = async () => {
try {
const response = await fetch(`${url_Backend_dwinzo}/api/v1/tutorials`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
console.log("response: ", response);
if (!response.ok) {
throw new Error("Failed to add project");
}
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@ -0,0 +1,24 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const recentlyViewed = async (organization: string, userId: string) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/RecentlyViewed/${userId}/${organization}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch project");
}
return await response.json();
} catch (error: any) {
console.error("Failed to get project");
throw new Error(error.message);
}
};

View File

@ -0,0 +1,26 @@
const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
// const url_Backend_dwinzo = `http://192.168.0.102:5000`;
export const restoreTrash = async (organization: string, projectId: string) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/restore?organization=${organization}&projectId=${projectId}`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch trash data");
}
const data = await response.json();
return data;
} catch (error: any) {
console.error("Failed to fetch trash data:", error);
throw new Error(error.message || "Unknown error");
}
};

View File

@ -0,0 +1,35 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const searchProject = async (
organization: string,
userId: string,
searchName: string
) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/searchProjects?organization=${organization}&userId=${userId}&searchName=${searchName}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to Search project");
}
console.log("response: ", response);
const result = await response.json();
console.log("result: ", result);
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@ -0,0 +1,32 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const trashSearchProject = async (
organization: string,
userId: string,
searchName: string
) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/searchTrashProjects?organization=${organization}&userId=${userId}&searchName=${searchName}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to add project");
}
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@ -0,0 +1,45 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
// let url_Backend_dwinzo = `http://192.168.0.102:5000`;
export const updateProject = async (
projectId: string,
userId: string,
organization: string,
thumbnail?: string,
projectName?: string
) => {
const body: any = {
projectId,
userId,
organization,
};
if (projectName) body.projectName = projectName;
if (thumbnail) body.thumbnail = thumbnail;
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/Project/modify`,
{
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
if (!response.ok) {
throw new Error("Failed to clearPanel in the zone");
}
const result = await response.json();
return result;
} catch (error) {
if (error instanceof Error) {
throw new Error(error.message);
} else {
throw new Error("An unknown error occurred");
}
}
};

View File

@ -0,0 +1,28 @@
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
export const viewProject = async (
organization: string,
projectId: string,
userId: string
) => {
try {
const response = await fetch(
`${url_Backend_dwinzo}/api/v1/Project/view?organization=${organization}&projectId=${projectId}&userId=${userId}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
if (!response.ok) {
throw new Error("Failed to fetch");
}
return await response.json();
} catch (error: any) {
console.error("Failed to get asset image:", error);
throw new Error(error.message);
}
};

View File

@ -20,6 +20,7 @@ export const signUpApi = async (
}
const result = await response.json();
console.log("result: ", result);
return result;
} catch (error) {
echo.error("Failed to sign-up");

View File

@ -1,454 +1,497 @@
import * as THREE from "three";
import { create } from "zustand";
import { io } from "socket.io-client";
import * as CONSTANTS from '../../types/world/worldConstants';
import * as CONSTANTS from "../../types/world/worldConstants";
export const useSocketStore = create<any>((set: any, get: any) => ({
socket: null,
initializeSocket: (email: string, organization: string) => {
const existingSocket = get().socket;
if (existingSocket) {
return;
}
socket: null,
initializeSocket: (email: string, organization: string, userId?: string) => {
const existingSocket = get().socket;
if (existingSocket) {
return;
}
const socket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
{
reconnection: true,
auth: { email, organization },
}
);
const socket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder`,
{
reconnection: true,
auth: { email, organization },
}
);
const visualizationSocket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`,
{
reconnection: true,
auth: { email, organization },
}
);
const visualizationSocket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization`,
{
reconnection: true,
auth: { email, organization },
}
);
set({ socket, visualizationSocket });
},
disconnectSocket: () => {
set((state: any) => {
state.socket?.disconnect();
state.visualizationSocket?.disconnect();
return { socket: null };
});
},
const dashBoardSocket = io(
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
{
reconnection: true,
auth: { email, organization, userId },
}
);
set({ socket, visualizationSocket, dashBoardSocket });
},
disconnectSocket: () => {
set((state: any) => {
state.socket?.disconnect();
state.visualizationSocket?.disconnect();
state.dashBoardSocket?.disconnect();
return { socket: null };
});
},
}));
export const useLoadingProgress = create<{
loadingProgress: number;
setLoadingProgress: (x: number) => void;
loadingProgress: number;
setLoadingProgress: (x: number) => void;
}>((set) => ({
loadingProgress: 1,
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
loadingProgress: 1,
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
}));
export const useOrganization = create<any>((set: any) => ({
organization: "",
setOrganization: (x: any) => set(() => ({ organization: x })),
organization: "",
setOrganization: (x: any) => set(() => ({ organization: x })),
}));
export const useToggleView = create<any>((set: any) => ({
toggleView: false,
setToggleView: (x: any) => set(() => ({ toggleView: x })),
toggleView: false,
setToggleView: (x: any) => set(() => ({ toggleView: x })),
}));
export const useUpdateScene = create<any>((set: any) => ({
updateScene: false,
setUpdateScene: (x: any) => set(() => ({ updateScene: x })),
updateScene: false,
setUpdateScene: (x: any) => set(() => ({ updateScene: x })),
}));
export const useWalls = create<any>((set: any) => ({
walls: [],
setWalls: (x: any) => set(() => ({ walls: x })),
walls: [],
setWalls: (x: any) => set(() => ({ walls: x })),
}));
export const useRoomsState = create<any>((set: any) => ({
roomsState: [],
setRoomsState: (x: any) => set(() => ({ roomsState: x })),
roomsState: [],
setRoomsState: (x: any) => set(() => ({ roomsState: x })),
}));
export const useZones = create<any>((set: any) => ({
zones: [],
setZones: (callback: any) =>
set((state: any) => ({
zones: typeof callback === "function" ? callback(state.zones) : callback,
})),
zones: [],
setZones: (callback: any) =>
set((state: any) => ({
zones: typeof callback === "function" ? callback(state.zones) : callback,
})),
}));
interface ZonePointsState {
zonePoints: THREE.Vector3[];
setZonePoints: (points: THREE.Vector3[]) => void;
zonePoints: THREE.Vector3[];
setZonePoints: (points: THREE.Vector3[]) => void;
}
export const useZonePoints = create<ZonePointsState>((set) => ({
zonePoints: [],
setZonePoints: (points) => set({ zonePoints: points }),
zonePoints: [],
setZonePoints: (points) => set({ zonePoints: points }),
}));
export const useSelectedItem = create<any>((set: any) => ({
selectedItem: { name: "", id: "", type: undefined, category: '', subCatergory: '' },
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
selectedItem: {
name: "",
id: "",
type: undefined,
category: "",
subCatergory: "",
},
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
}));
export const useNavMesh = create<any>((set: any) => ({
navMesh: null,
setNavMesh: (x: any) => set({ navMesh: x }),
navMesh: null,
setNavMesh: (x: any) => set({ navMesh: x }),
}));
export const useSelectedAssets = create<any>((set: any) => ({
selectedAssets: [],
setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })),
selectedAssets: [],
setSelectedAssets: (x: any) => set(() => ({ selectedAssets: x })),
}));
export const useLayers = create<any>((set: any) => ({
Layers: 1,
setLayers: (x: any) => set(() => ({ Layers: x })),
Layers: 1,
setLayers: (x: any) => set(() => ({ Layers: x })),
}));
export const useCamPosition = create<any>((set: any) => ({
camPosition: { x: undefined, y: undefined, z: undefined },
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
camPosition: { x: undefined, y: undefined, z: undefined },
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
}));
export const useMenuVisible = create<any>((set: any) => ({
menuVisible: false,
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
menuVisible: false,
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
}));
export const useDeleteTool = create<any>((set: any) => ({
deleteTool: false,
setDeleteTool: (x: any) => set(() => ({ deleteTool: x })),
deleteTool: false,
setDeleteTool: (x: any) => set(() => ({ deleteTool: x })),
}));
export const useToolMode = create<any>((set: any) => ({
toolMode: null,
setToolMode: (x: any) => set(() => ({ toolMode: x })),
toolMode: null,
setToolMode: (x: any) => set(() => ({ toolMode: x })),
}));
export const useNewLines = create<any>((set: any) => ({
newLines: [],
setNewLines: (x: any) => set(() => ({ newLines: x })),
newLines: [],
setNewLines: (x: any) => set(() => ({ newLines: x })),
}));
export const useDeletedLines = create<any>((set: any) => ({
deletedLines: [],
setDeletedLines: (x: any) => set(() => ({ deletedLines: x })),
deletedLines: [],
setDeletedLines: (x: any) => set(() => ({ deletedLines: x })),
}));
export const useMovePoint = create<any>((set: any) => ({
movePoint: false,
setMovePoint: (x: any) => set(() => ({ movePoint: x })),
movePoint: false,
setMovePoint: (x: any) => set(() => ({ movePoint: x })),
}));
export const useDeletePointOrLine = create<any>((set: any) => ({
deletePointOrLine: false,
setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })),
deletePointOrLine: false,
setDeletePointOrLine: (x: any) => set(() => ({ deletePointOrLine: x })),
}));
export const useFloorItems = create<any>((set: any) => ({
floorItems: null,
setFloorItems: (callback: any) =>
set((state: any) => ({
floorItems:
typeof callback === "function" ? callback(state.floorItems) : callback,
})),
floorItems: null,
setFloorItems: (callback: any) =>
set((state: any) => ({
floorItems:
typeof callback === "function" ? callback(state.floorItems) : callback,
})),
}));
export const useWallItems = create<any>((set: any) => ({
wallItems: [],
setWallItems: (callback: any) =>
set((state: any) => ({
wallItems:
typeof callback === "function" ? callback(state.wallItems) : callback,
})),
wallItems: [],
setWallItems: (callback: any) =>
set((state: any) => ({
wallItems:
typeof callback === "function" ? callback(state.wallItems) : callback,
})),
}));
export const useSelectedWallItem = create<any>((set: any) => ({
selectedWallItem: null,
setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })),
selectedWallItem: null,
setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })),
}));
export const useSelectedFloorItem = create<any>((set: any) => ({
selectedFloorItem: null,
setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })),
selectedFloorItem: null,
setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })),
}));
export const useDeletableFloorItem = create<any>((set: any) => ({
deletableFloorItem: null,
setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })),
deletableFloorItem: null,
setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })),
}));
export const useSetScale = create<any>((set: any) => ({
scale: null,
setScale: (x: any) => set(() => ({ scale: x })),
scale: null,
setScale: (x: any) => set(() => ({ scale: x })),
}));
export const useRoofVisibility = create<any>((set: any) => ({
roofVisibility: false,
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
roofVisibility: false,
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
}));
export const useWallVisibility = create<any>((set: any) => ({
wallVisibility: false,
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
wallVisibility: false,
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
}));
export const useShadows = create<any>((set: any) => ({
shadows: false,
setShadows: (x: any) => set(() => ({ shadows: x })),
shadows: false,
setShadows: (x: any) => set(() => ({ shadows: x })),
}));
export const useSunPosition = create<any>((set: any) => ({
sunPosition: { x: undefined, y: undefined, z: undefined },
setSunPosition: (newSuntPosition: any) =>
set({ sunPosition: newSuntPosition }),
sunPosition: { x: undefined, y: undefined, z: undefined },
setSunPosition: (newSuntPosition: any) =>
set({ sunPosition: newSuntPosition }),
}));
export const useRemoveLayer = create<any>((set: any) => ({
removeLayer: false,
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
removeLayer: false,
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
}));
export const useRemovedLayer = create<any>((set: any) => ({
removedLayer: null,
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
removedLayer: null,
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
}));
export const useActiveLayer = create<any>((set: any) => ({
activeLayer: 1,
setActiveLayer: (x: any) => set({ activeLayer: x }),
activeLayer: 1,
setActiveLayer: (x: any) => set({ activeLayer: x }),
}));
interface RefTextUpdateState {
refTextupdate: number;
setRefTextUpdate: (
callback: (currentValue: number) => number | number
) => void;
refTextupdate: number;
setRefTextUpdate: (
callback: (currentValue: number) => number | number
) => void;
}
export const useRefTextUpdate = create<RefTextUpdateState>((set) => ({
refTextupdate: -1000,
setRefTextUpdate: (callback) =>
set((state) => ({
refTextupdate:
typeof callback === "function"
? callback(state.refTextupdate)
: callback,
})),
refTextupdate: -1000,
setRefTextUpdate: (callback) =>
set((state) => ({
refTextupdate:
typeof callback === "function"
? callback(state.refTextupdate)
: callback,
})),
}));
export const useResetCamera = create<any>((set: any) => ({
resetCamera: false,
setResetCamera: (x: any) => set({ resetCamera: x }),
resetCamera: false,
setResetCamera: (x: any) => set({ resetCamera: x }),
}));
export const useAddAction = create<any>((set: any) => ({
addAction: null,
setAddAction: (x: any) => set({ addAction: x }),
addAction: null,
setAddAction: (x: any) => set({ addAction: x }),
}));
export const useActiveTool = create<any>((set: any) => ({
activeTool: "cursor",
setActiveTool: (x: any) => set({ activeTool: x }),
activeTool: "cursor",
setActiveTool: (x: any) => set({ activeTool: x }),
}));
export const useActiveSubTool = create<any>((set: any) => ({
activeSubTool: "cursor",
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
activeSubTool: "cursor",
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
}));
export const use2DUndoRedo = create<any>((set: any) => ({
is2DUndoRedo: null,
set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }),
is2DUndoRedo: null,
set2DUndoRedo: (x: any) => set({ is2DUndoRedo: x }),
}));
export const useElevation = create<any>((set: any) => ({
elevation: 45,
setElevation: (x: any) => set({ elevation: x }),
elevation: 45,
setElevation: (x: any) => set({ elevation: x }),
}));
export const useAzimuth = create<any>((set: any) => ({
azimuth: -160,
setAzimuth: (x: any) => set({ azimuth: x }),
azimuth: -160,
setAzimuth: (x: any) => set({ azimuth: x }),
}));
export const useRenderDistance = create<any>((set: any) => ({
renderDistance: 40,
setRenderDistance: (x: any) => set({ renderDistance: x }),
renderDistance: 40,
setRenderDistance: (x: any) => set({ renderDistance: x }),
}));
export const useCamMode = create<any>((set: any) => ({
camMode: "ThirdPerson",
setCamMode: (x: any) => set({ camMode: x }),
camMode: "ThirdPerson",
setCamMode: (x: any) => set({ camMode: x }),
}));
export const useUserName = create<any>((set: any) => ({
userName: "",
setUserName: (x: any) => set({ userName: x }),
userName: "",
setUserName: (x: any) => set({ userName: x }),
}));
export const useObjectPosition = create<any>((set: any) => ({
objectPosition: { x: undefined, y: undefined, z: undefined },
setObjectPosition: (newObjectPosition: any) =>
set({ objectPosition: newObjectPosition }),
objectPosition: { x: undefined, y: undefined, z: undefined },
setObjectPosition: (newObjectPosition: any) =>
set({ objectPosition: newObjectPosition }),
}));
export const useObjectRotation = create<any>((set: any) => ({
objectRotation: { x: undefined, y: undefined, z: undefined },
setObjectRotation: (newObjectRotation: any) =>
set({ objectRotation: newObjectRotation }),
objectRotation: { x: undefined, y: undefined, z: undefined },
setObjectRotation: (newObjectRotation: any) =>
set({ objectRotation: newObjectRotation }),
}));
export const useDrieTemp = create<any>((set: any) => ({
drieTemp: undefined,
setDrieTemp: (x: any) => set({ drieTemp: x }),
drieTemp: undefined,
setDrieTemp: (x: any) => set({ drieTemp: x }),
}));
export const useActiveUsers = create<any>((set: any) => ({
activeUsers: [],
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
set((state: { activeUsers: any[] }) => ({
activeUsers:
typeof callback === "function" ? callback(state.activeUsers) : callback,
})),
activeUsers: [],
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
set((state: { activeUsers: any[] }) => ({
activeUsers:
typeof callback === "function" ? callback(state.activeUsers) : callback,
})),
}));
export const useDrieUIValue = create<any>((set: any) => ({
drieUIValue: { touch: null, temperature: null, humidity: null },
drieUIValue: { touch: null, temperature: null, humidity: null },
setDrieUIValue: (x: any) =>
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
setDrieUIValue: (x: any) =>
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
setTouch: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, touch: value },
})),
setTemperature: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, temperature: value },
})),
setHumidity: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, humidity: value },
})),
setTouch: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, touch: value },
})),
setTemperature: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, temperature: value },
})),
setHumidity: (value: any) =>
set((state: any) => ({
drieUIValue: { ...state.drieUIValue, humidity: value },
})),
}));
export const useStartSimulation = create<any>((set: any) => ({
startSimulation: false,
setStartSimulation: (x: any) => set({ startSimulation: x }),
startSimulation: false,
setStartSimulation: (x: any) => set({ startSimulation: x }),
}));
export const useEyeDropMode = create<any>((set: any) => ({
eyeDropMode: false,
setEyeDropMode: (x: any) => set({ eyeDropMode: x }),
eyeDropMode: false,
setEyeDropMode: (x: any) => set({ eyeDropMode: x }),
}));
export const useEditingPoint = create<any>((set: any) => ({
editingPoint: false,
setEditingPoint: (x: any) => set({ editingPoint: x }),
editingPoint: false,
setEditingPoint: (x: any) => set({ editingPoint: x }),
}));
export const usezoneTarget = create<any>((set: any) => ({
zoneTarget: [],
setZoneTarget: (x: any) => set({ zoneTarget: x }),
zoneTarget: [],
setZoneTarget: (x: any) => set({ zoneTarget: x }),
}));
export const usezonePosition = create<any>((set: any) => ({
zonePosition: [],
setZonePosition: (x: any) => set({ zonePosition: x }),
zonePosition: [],
setZonePosition: (x: any) => set({ zonePosition: x }),
}));
interface EditPositionState {
Edit: boolean;
setEdit: (value: boolean) => void;
Edit: boolean;
setEdit: (value: boolean) => void;
}
export const useEditPosition = create<EditPositionState>((set) => ({
Edit: false,
setEdit: (value) => set({ Edit: value }),
Edit: false,
setEdit: (value) => set({ Edit: value }),
}));
export const useAsset3dWidget = create<any>((set: any) => ({
widgetSelect: "",
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
widgetSelect: "",
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
}));
export const useWidgetSubOption = create<any>((set: any) => ({
widgetSubOption: "2D",
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
widgetSubOption: "2D",
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
}));
export const useLimitDistance = create<any>((set: any) => ({
limitDistance: true,
setLimitDistance: (x: any) => set({ limitDistance: x }),
limitDistance: true,
setLimitDistance: (x: any) => set({ limitDistance: x }),
}));
export const useProjectName = create<any>((set: any) => ({
projectName: "Creating Your Project",
setProjectName: (x: any) => set({ projectName: x }),
}));
// // export const useProjectCount = create<any>((set: any) => ({
// // projectCount: 1, // Initial state for projectCount
// // // Function to update projectCount
// // setProjectCount: (x: number) =>
// // set((state: any) => ({
// // projectCount: state.projectCount + x,
// // })),
// // }));
// export const useProjectCount = create<any>((set: any) => ({
// projectCount: Number(localStorage.getItem("projectCount")) || 1, // Load from localStorage or default to 1
// setProjectCount: (x: number) =>
// set((state: any) => {
// const newCount = state.projectCount + x;
// localStorage.setItem("projectCount", newCount.toString()); // Sync with localStorage
// return { projectCount: newCount };
// }),
// }));
export const useTileDistance = create<any>((set: any) => ({
gridValue: { size: CONSTANTS.gridConfig.size, divisions: CONSTANTS.gridConfig.divisions },
planeValue: { height: CONSTANTS.planeConfig.height, width: CONSTANTS.planeConfig.width },
gridValue: {
size: CONSTANTS.gridConfig.size,
divisions: CONSTANTS.gridConfig.divisions,
},
planeValue: {
height: CONSTANTS.planeConfig.height,
width: CONSTANTS.planeConfig.width,
},
setGridValue: (value: any) =>
set((state: any) => ({
gridValue: { ...state.gridValue, ...value },
})),
setGridValue: (value: any) =>
set((state: any) => ({
gridValue: { ...state.gridValue, ...value },
})),
setPlaneValue: (value: any) =>
set((state: any) => ({
planeValue: { ...state.planeValue, ...value },
})),
setPlaneValue: (value: any) =>
set((state: any) => ({
planeValue: { ...state.planeValue, ...value },
})),
}));
export const usePlayAgv = create<any>((set, get) => ({
PlayAgv: [],
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
set({ PlayAgv: updateFn(get().PlayAgv) }),
PlayAgv: [],
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
set({ PlayAgv: updateFn(get().PlayAgv) }),
}));
// Define the Asset type
type Asset = {
id: string;
name: string;
position?: [number, number, number]; // Optional: 3D position
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
id: string;
name: string;
position?: [number, number, number]; // Optional: 3D position
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
};
// Zustand store type
type ZoneAssetState = {
zoneAssetId: Asset | null;
setZoneAssetId: (asset: Asset | null) => void;
zoneAssetId: Asset | null;
setZoneAssetId: (asset: Asset | null) => void;
};
// Zustand store
export const useZoneAssetId = create<ZoneAssetState>((set) => ({
zoneAssetId: null,
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
zoneAssetId: null,
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
}));
// version visible hidden
interface VersionHistoryState {
viewVersionHistory: boolean;
setVersionHistory: (value: boolean) => void;
viewVersionHistory: boolean;
setVersionHistory: (value: boolean) => void;
}
const useVersionHistoryStore = create<VersionHistoryState>((set) => ({
viewVersionHistory: false,
setVersionHistory: (value) => set({ viewVersionHistory: value }),
viewVersionHistory: false,
setVersionHistory: (value) => set({ viewVersionHistory: value }),
}));
export default useVersionHistoryStore;
interface ShortcutStore {
showShortcuts: boolean;
setShowShortcuts: (value: boolean) => void;
toggleShortcuts: () => void;
showShortcuts: boolean;
setShowShortcuts: (value: boolean) => void;
toggleShortcuts: () => void;
}
export const useShortcutStore = create<ShortcutStore>((set) => ({
showShortcuts: false,
setShowShortcuts: (value) => set({ showShortcuts: value }),
toggleShortcuts: () =>
set((state) => ({ showShortcuts: !state.showShortcuts })),
}));
showShortcuts: false,
setShowShortcuts: (value) => set({ showShortcuts: value }),
toggleShortcuts: () =>
set((state) => ({ showShortcuts: !state.showShortcuts })),
}));