added dashboard with add delete and recently view the projects
This commit is contained in:
parent
eebc91831d
commit
0ecb85a211
7
app/.env
7
app/.env
|
@ -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
|
||||
|
|
|
@ -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 |
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
};
|
|
@ -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 />
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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();
|
||||
}}
|
||||
|
|
|
@ -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;
|
|
@ -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 && (
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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");
|
||||
|
|
|
@ -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 })),
|
||||
}));
|
||||
|
|
Loading…
Reference in New Issue