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
|
PORT=8200
|
||||||
|
|
||||||
# Base URL for the server socket API, used for real-time communication (e.g., WebSockets).
|
# 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.
|
# 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.
|
# Base URL for the server marketplace, used for market place model blob.
|
||||||
REACT_APP_SERVER_MARKETPLACE_URL=185.100.212.76:50011
|
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 { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
||||||
import Dashboard from "./pages/Dashboard";
|
import Dashboard from "./pages/Dashboard";
|
||||||
import Project from "./pages/Project";
|
import Project from "./pages/Project";
|
||||||
|
@ -7,13 +7,24 @@ import "./styles/main.scss";
|
||||||
import { LoggerProvider } from "./components/ui/log/LoggerContext";
|
import { LoggerProvider } from "./components/ui/log/LoggerContext";
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
const handlePopState = () => {
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("popstate", handlePopState);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener("popstate", handlePopState);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
return (
|
return (
|
||||||
<LoggerProvider>
|
<LoggerProvider>
|
||||||
<Router>
|
<Router>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<UserAuth />} />
|
<Route path="/" element={<UserAuth />} />
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
<Route path="/dashboard" element={<Dashboard />} />
|
||||||
<Route path="/project" element={<Project />} />
|
<Route path="/:projectId" element={<Project />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
</LoggerProvider>
|
</LoggerProvider>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 237 KiB |
Binary file not shown.
After Width: | Height: | Size: 251 KiB |
|
@ -1,24 +1,77 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { KebabIcon } from "../../icons/ExportCommonIcons";
|
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 (
|
return (
|
||||||
<div className="dashboard-card-container">
|
<div className="dashboard-card-container" onClick={navigateToProject} title={projectName}>
|
||||||
<div className="preview-container">
|
<div className="preview-container">
|
||||||
<img src={img} alt="" />
|
{thumbnail ? <img src={thumbnail} alt="" /> : <img src={img} alt="" />}
|
||||||
</div>
|
</div>
|
||||||
<div className="project-details-container">
|
<div className="project-details-container">
|
||||||
<div className="project-details">
|
<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 className="project-data">24-12-2025</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="users-list-container">
|
<div className="users-list-container">
|
||||||
<div className="user-profile">V</div>
|
<div className="user-profile">
|
||||||
|
{userName ? userName.charAt(0).toUpperCase() : "Anonymous"}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleKebabIconClick();
|
||||||
|
}}
|
||||||
|
>
|
||||||
<KebabIcon />
|
<KebabIcon />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,134 @@
|
||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import DashboardCard from "./DashboardCard";
|
import DashboardCard from "./DashboardCard";
|
||||||
import DashboardNavBar from "./DashboardNavBar";
|
import DashboardNavBar from "./DashboardNavBar";
|
||||||
import MarketPlaceBanner from "./MarketPlaceBanner";
|
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 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 (
|
return (
|
||||||
<div className="dashboard-home-container">
|
<div className="dashboard-home-container">
|
||||||
<DashboardNavBar page={"home"} />
|
<DashboardNavBar
|
||||||
|
page="home"
|
||||||
|
handleRecentProjectSearch={handleRecentProjectSearch}
|
||||||
|
/>
|
||||||
|
|
||||||
<MarketPlaceBanner />
|
<MarketPlaceBanner />
|
||||||
|
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="header">Recents</div>
|
<h2 className="section-header">Recent Projects</h2>
|
||||||
<div className="cards-container">
|
<div className="cards-container">{renderProjects()}</div>
|
||||||
<DashboardCard />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,16 +4,38 @@ import Search from "../../ui/inputs/Search";
|
||||||
|
|
||||||
interface DashboardNavBarProps {
|
interface DashboardNavBarProps {
|
||||||
page: React.ReactNode;
|
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 (
|
return (
|
||||||
<div className="dashboard-navbar-container">
|
<div className="dashboard-navbar-container">
|
||||||
<div className="title">{page}</div>
|
<div className="title">{page}</div>
|
||||||
<div className="market-place-button">
|
<div className="market-place-button">
|
||||||
<CartIcon isActive /> Market Place
|
<CartIcon isActive /> Market Place
|
||||||
</div>
|
</div>
|
||||||
<Search onChange={() => {}} />
|
<Search onChange={handleSearch} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
import {
|
||||||
DocumentationIcon,
|
DocumentationIcon,
|
||||||
HelpIcon,
|
HelpIcon,
|
||||||
|
@ -9,40 +9,98 @@ import {
|
||||||
TutorialsIcon,
|
TutorialsIcon,
|
||||||
} from "../../icons/DashboardIcon";
|
} from "../../icons/DashboardIcon";
|
||||||
import { SettingsIcon, TrashIcon } from "../../icons/ExportCommonIcons";
|
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 (
|
return (
|
||||||
<div className="side-pannel-container">
|
<div className="side-pannel-container">
|
||||||
<div className="side-pannel-header">
|
<div className="side-pannel-header">
|
||||||
<div className="user-container">
|
<div className="user-container">
|
||||||
<div className="user-profile">{userName[0]}</div>
|
<div className="user-profile">{userName?.charAt(0).toUpperCase()}</div>
|
||||||
<div className="user-name">{userName}</div>
|
<div className="user-name">{userName ? userName.charAt(0).toUpperCase() + userName.slice(1).toLowerCase() : "Anonymous"}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="notifications-container">
|
<div className="notifications-container">
|
||||||
<NotificationIcon />
|
<NotificationIcon />
|
||||||
</div>
|
</div>
|
||||||
</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-content-container">
|
||||||
<div className="side-bar-options-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 />
|
<HomeIcon />
|
||||||
Home
|
Home
|
||||||
</div>
|
</div>
|
||||||
<div className="option-list" title="coming soon">
|
<div className={activeTab === "Projects" ? "option-list active" : "option-list"} title="Projects" onClick={() => setActiveTab("Projects")}>
|
||||||
<ProjectsIcon />
|
<ProjectsIcon />
|
||||||
Projects
|
Projects
|
||||||
</div>
|
</div>
|
||||||
<div className="option-list" title="coming soon">
|
<div className={activeTab === "Trash" ? "option-list active" : "option-list"} title="Trash" onClick={() => setActiveTab("Trash")}>
|
||||||
<TrashIcon />
|
<TrashIcon />
|
||||||
Trash
|
Trash
|
||||||
</div>
|
</div>
|
||||||
<div className="option-list" title="coming soon">
|
<div className={activeTab === "Tutorials" ? "option-list active" : "option-list"} title="coming soon" onClick={() => setActiveTab("Tutorials")}>
|
||||||
<TutorialsIcon />
|
<TutorialsIcon />
|
||||||
Tutorials
|
Tutorials
|
||||||
</div>
|
</div>
|
||||||
<div className="option-list" title="coming soon">
|
<div className={activeTab === "Documentation" ? "option-list active" : "option-list"} title="coming soon" onClick={() => setActiveTab("Documentation")}>
|
||||||
<DocumentationIcon />
|
<DocumentationIcon />
|
||||||
Documentation
|
Documentation
|
||||||
</div>
|
</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 RenderOverlay from "./Overlay";
|
||||||
import { LogoIconLarge } from "../icons/Logo";
|
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 {
|
interface LoadingPageProps {
|
||||||
progress: number; // Expect progress as a percentage (0-100)
|
progress: number; // Expect progress as a percentage (0-100)
|
||||||
|
@ -8,12 +11,46 @@ interface LoadingPageProps {
|
||||||
|
|
||||||
const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
|
const LoadingPage: React.FC<LoadingPageProps> = ({ progress }) => {
|
||||||
const validatedProgress = Math.min(100, Math.max(0, 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 (
|
return (
|
||||||
<RenderOverlay>
|
<RenderOverlay>
|
||||||
<div className="loading-wrapper">
|
<div className="loading-wrapper">
|
||||||
<div className="loading-container">
|
<div className="loading-container">
|
||||||
<div className="project-name">Untitled</div>
|
<div className="project-name">{projectName}</div>
|
||||||
<div className="loading-hero-container">
|
<div className="loading-hero-container">
|
||||||
<div className="logo">
|
<div className="logo">
|
||||||
<LogoIconLarge />
|
<LogoIconLarge />
|
||||||
|
|
|
@ -3,10 +3,17 @@ import RenameInput from "./inputs/RenameInput";
|
||||||
import { ArrowIcon } from "../icons/ExportCommonIcons";
|
import { ArrowIcon } from "../icons/ExportCommonIcons";
|
||||||
import MenuBar from "./menu/menu";
|
import MenuBar from "./menu/menu";
|
||||||
import { ProjectIcon } from "../icons/HeaderIcons";
|
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 FileMenu: React.FC = () => {
|
||||||
const [openMenu, setOpenMenu] = useState(false);
|
const [openMenu, setOpenMenu] = useState(false);
|
||||||
|
const { projectName, setProjectName } = useProjectName();
|
||||||
|
const { dashBoardSocket } = useSocketStore();
|
||||||
const containerRef = useRef<HTMLButtonElement>(null);
|
const containerRef = useRef<HTMLButtonElement>(null);
|
||||||
|
const { projectId } = useParams();
|
||||||
let clickTimeout: NodeJS.Timeout | null = null;
|
let clickTimeout: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
|
@ -31,20 +38,65 @@ const FileMenu: React.FC = () => {
|
||||||
return () => document.removeEventListener("mousedown", handleClickOutside);
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// project
|
|
||||||
const [projectName, setProjectName] = useState("Demo Project");
|
|
||||||
|
|
||||||
// Load project name from localStorage on mount
|
const handleProjectRename = async (projectName: string) => {
|
||||||
useEffect(() => {
|
setProjectName(projectName);
|
||||||
const savedName = localStorage.getItem("projectName");
|
if (!projectId) return
|
||||||
if (savedName) {
|
// localStorage.setItem("projectName", newName);
|
||||||
setProjectName(savedName);
|
try {
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const userId = localStorage.getItem("userId");
|
||||||
|
|
||||||
|
if (!email || !userId) {
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleProjectRename = (newName: string) => {
|
const emailParts = email.split("@");
|
||||||
setProjectName(newName);
|
if (emailParts.length < 2) {
|
||||||
localStorage.setItem("projectName", newName);
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -38,8 +38,7 @@ const Search: React.FC<SearchProps> = ({
|
||||||
return (
|
return (
|
||||||
<div className="search-wrapper">
|
<div className="search-wrapper">
|
||||||
<div
|
<div
|
||||||
className={`search-container ${
|
className={`search-container ${isFocused || inputValue ? "active" : ""
|
||||||
isFocused || inputValue ? "active" : ""
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="icon-container">
|
<div className="icon-container">
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Visualization from "../visualization/visualization";
|
||||||
import Setup from "./setup/setup";
|
import Setup from "./setup/setup";
|
||||||
import Simulation from "../simulation/simulation";
|
import Simulation from "../simulation/simulation";
|
||||||
import Collaboration from "../collaboration/collaboration";
|
import Collaboration from "../collaboration/collaboration";
|
||||||
|
import { useSocketStore } from "../../store/builder/store";
|
||||||
|
|
||||||
export default function Scene() {
|
export default function Scene() {
|
||||||
const map = useMemo(
|
const map = useMemo(
|
||||||
|
@ -19,11 +20,13 @@ export default function Scene() {
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardControls map={map}>
|
<KeyboardControls map={map}>
|
||||||
<Canvas
|
<Canvas
|
||||||
|
id="canvas-container"
|
||||||
eventPrefix="client"
|
eventPrefix="client"
|
||||||
gl={{ powerPreference: "high-performance", antialias: true }}
|
gl={{ powerPreference: "high-performance", antialias: true, alpha: true, preserveDrawingBuffer: true, }}
|
||||||
onContextMenu={(e) => {
|
onContextMenu={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,12 +1,34 @@
|
||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import SidePannel from '../components/layout/Dashboard/SidePannel';
|
import SidePannel from '../components/layout/Dashboard/SidePannel';
|
||||||
import DashboardHome from '../components/layout/Dashboard/DashboardHome';
|
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 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 (
|
return (
|
||||||
<div className="dashboard-main">
|
<div className="dashboard-main">
|
||||||
<SidePannel />
|
<SidePannel setActiveTab={setActiveTab} activeTab={activeTab} />
|
||||||
<DashboardHome />
|
{activeTab == 'Home' && <DashboardHome />}
|
||||||
|
{activeTab == 'Projects' && <DashboardProjects />}
|
||||||
|
{activeTab == 'Trash' && <DashboardTrash />}
|
||||||
|
{activeTab == 'Tutorials' && <DashboardTutorial />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import ModuleToggle from "../components/ui/ModuleToggle";
|
import ModuleToggle from "../components/ui/ModuleToggle";
|
||||||
import SideBarLeft from "../components/layout/sidebarLeft/SideBarLeft";
|
import SideBarLeft from "../components/layout/sidebarLeft/SideBarLeft";
|
||||||
import SideBarRight from "../components/layout/sidebarRight/SideBarRight";
|
import SideBarRight from "../components/layout/sidebarRight/SideBarRight";
|
||||||
|
@ -14,8 +14,10 @@ import {
|
||||||
useZones,
|
useZones,
|
||||||
useLoadingProgress,
|
useLoadingProgress,
|
||||||
useWidgetSubOption,
|
useWidgetSubOption,
|
||||||
|
useProjectName,
|
||||||
|
useStartSimulation,
|
||||||
} from "../store/builder/store";
|
} from "../store/builder/store";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { usePlayButtonStore } from "../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../store/usePlayButtonStore";
|
||||||
import MarketPlace from "../modules/market/MarketPlace";
|
import MarketPlace from "../modules/market/MarketPlace";
|
||||||
import LoadingPage from "../components/templates/LoadingPage";
|
import LoadingPage from "../components/templates/LoadingPage";
|
||||||
|
@ -32,19 +34,59 @@ import RenderOverlay from "../components/templates/Overlay";
|
||||||
import LogList from "../components/ui/log/LogList";
|
import LogList from "../components/ui/log/LogList";
|
||||||
import Footer from "../components/footer/Footer";
|
import Footer from "../components/footer/Footer";
|
||||||
import SelectFloorPlan from "../components/temporary/SelectFloorPlan";
|
import SelectFloorPlan from "../components/temporary/SelectFloorPlan";
|
||||||
|
import { getAllProjects } from "../services/dashboard/getAllProjects";
|
||||||
|
import { viewProject } from "../services/dashboard/viewProject";
|
||||||
|
|
||||||
const Project: React.FC = () => {
|
const Project: React.FC = () => {
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
const echo = useLogger();
|
const echo = useLogger();
|
||||||
|
|
||||||
const { activeModule, setActiveModule } = useModuleStore();
|
const { activeModule, setActiveModule } = useModuleStore();
|
||||||
const { loadingProgress } = useLoadingProgress();
|
const { loadingProgress, setLoadingProgress } = useLoadingProgress();
|
||||||
const { setUserName } = useUserName();
|
const { setUserName } = useUserName();
|
||||||
const { setOrganization } = useOrganization();
|
const { setOrganization } = useOrganization();
|
||||||
const { setFloorItems } = useFloorItems();
|
const { setFloorItems } = useFloorItems();
|
||||||
const { setWallItems } = useWallItems();
|
const { setWallItems } = useWallItems();
|
||||||
const { setZones } = useZones();
|
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(() => {
|
useEffect(() => {
|
||||||
setFloorItems([]);
|
setFloorItems([]);
|
||||||
setWallItems([]);
|
setWallItems([]);
|
||||||
|
@ -53,7 +95,7 @@ const Project: React.FC = () => {
|
||||||
const email = localStorage.getItem("email");
|
const email = localStorage.getItem("email");
|
||||||
if (email) {
|
if (email) {
|
||||||
const Organization = email.split("@")[1].split(".")[0];
|
const Organization = email.split("@")[1].split(".")[0];
|
||||||
useSocketStore.getState().initializeSocket(email, Organization);
|
// useSocketStore.getState().initializeSocket(email, Organization);
|
||||||
const name = localStorage.getItem("userName");
|
const name = localStorage.getItem("userName");
|
||||||
if (Organization && name) {
|
if (Organization && name) {
|
||||||
setOrganization(Organization);
|
setOrganization(Organization);
|
||||||
|
@ -82,6 +124,7 @@ const Project: React.FC = () => {
|
||||||
const { selectedZone } = useSelectedZoneStore();
|
const { selectedZone } = useSelectedZoneStore();
|
||||||
const { setFloatingWidget } = useFloatingWidget();
|
const { setFloatingWidget } = useFloatingWidget();
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="project-main">
|
<div className="project-main">
|
||||||
{!selectedUser && (
|
{!selectedUser && (
|
||||||
|
|
|
@ -26,19 +26,23 @@ const UserAuth: React.FC = () => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const organization = email.split("@")[1].split(".")[0];
|
const organization = email.split("@")[1].split(".")[0];
|
||||||
|
console.log('email, password, organization: ', email, password, organization);
|
||||||
try {
|
try {
|
||||||
const res = await signInApi(email, password, organization);
|
const res = await signInApi(email, password, organization);
|
||||||
|
|
||||||
|
|
||||||
if (res.message === "login successfull") {
|
if (res.message === "login successfull") {
|
||||||
setError("");
|
setError("");
|
||||||
setOrganization(organization);
|
setOrganization(organization);
|
||||||
setUserName(res.name);
|
setUserName(res.name);
|
||||||
|
console.log(' res.userId: ', res.userId);
|
||||||
localStorage.setItem("userId", res.userId);
|
localStorage.setItem("userId", res.userId);
|
||||||
localStorage.setItem("email", res.email);
|
localStorage.setItem("email", res.email);
|
||||||
localStorage.setItem("userName", res.name);
|
localStorage.setItem("userName", res.name);
|
||||||
if (res.isShare) {
|
if (res.isShare) {
|
||||||
setLoadingProgress(1);
|
setLoadingProgress(1);
|
||||||
navigate("/Project");
|
// navigate("/Project");
|
||||||
|
navigate("/Dashboard");
|
||||||
}
|
}
|
||||||
} else if (res.message === "User Not Found!!! Kindly signup...") {
|
} else if (res.message === "User Not Found!!! Kindly signup...") {
|
||||||
setError("Account not found");
|
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();
|
const result = await response.json();
|
||||||
|
console.log("result: ", result);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
echo.error("Failed to sign-up");
|
echo.error("Failed to sign-up");
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { io } from "socket.io-client";
|
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) => ({
|
export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||||
socket: null,
|
socket: null,
|
||||||
initializeSocket: (email: string, organization: string) => {
|
initializeSocket: (email: string, organization: string, userId?: string) => {
|
||||||
const existingSocket = get().socket;
|
const existingSocket = get().socket;
|
||||||
if (existingSocket) {
|
if (existingSocket) {
|
||||||
return;
|
return;
|
||||||
|
@ -27,12 +27,21 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
set({ socket, visualizationSocket });
|
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: () => {
|
disconnectSocket: () => {
|
||||||
set((state: any) => {
|
set((state: any) => {
|
||||||
state.socket?.disconnect();
|
state.socket?.disconnect();
|
||||||
state.visualizationSocket?.disconnect();
|
state.visualizationSocket?.disconnect();
|
||||||
|
state.dashBoardSocket?.disconnect();
|
||||||
return { socket: null };
|
return { socket: null };
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -90,7 +99,13 @@ export const useZonePoints = create<ZonePointsState>((set) => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export const useSelectedItem = create<any>((set: any) => ({
|
export const useSelectedItem = create<any>((set: any) => ({
|
||||||
selectedItem: { name: "", id: "", type: undefined, category: '', subCatergory: '' },
|
selectedItem: {
|
||||||
|
name: "",
|
||||||
|
id: "",
|
||||||
|
type: undefined,
|
||||||
|
category: "",
|
||||||
|
subCatergory: "",
|
||||||
|
},
|
||||||
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -385,10 +400,38 @@ export const useLimitDistance = create<any>((set: any) => ({
|
||||||
limitDistance: true,
|
limitDistance: true,
|
||||||
setLimitDistance: (x: any) => set({ limitDistance: x }),
|
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) => ({
|
export const useTileDistance = create<any>((set: any) => ({
|
||||||
gridValue: { size: CONSTANTS.gridConfig.size, divisions: CONSTANTS.gridConfig.divisions },
|
gridValue: {
|
||||||
planeValue: { height: CONSTANTS.planeConfig.height, width: CONSTANTS.planeConfig.width },
|
size: CONSTANTS.gridConfig.size,
|
||||||
|
divisions: CONSTANTS.gridConfig.divisions,
|
||||||
|
},
|
||||||
|
planeValue: {
|
||||||
|
height: CONSTANTS.planeConfig.height,
|
||||||
|
width: CONSTANTS.planeConfig.width,
|
||||||
|
},
|
||||||
|
|
||||||
setGridValue: (value: any) =>
|
setGridValue: (value: any) =>
|
||||||
set((state: any) => ({
|
set((state: any) => ({
|
||||||
|
|
Loading…
Reference in New Issue