Refactor Dashboard components: add createdAt prop to Project interfaces, implement ProjectSocketRes for socket event handling, and remove unused handleDuplicateProjects function.

This commit is contained in:
Poovizhi99 2025-06-04 11:48:49 +05:30
parent 5ba7457276
commit ea400847a4
8 changed files with 309 additions and 435 deletions

View File

@ -12,17 +12,26 @@ interface DashBoardCardProps {
projectName: string; projectName: string;
thumbnail: any; thumbnail: any;
projectId: string; projectId: string;
createdAt?: string createdAt?: string;
handleDeleteProject?: (projectId: string) => Promise<void>; handleDeleteProject?: (projectId: string) => Promise<void>;
handleTrashDeleteProject?: (projectId: string) => Promise<void>; handleTrashDeleteProject?: (projectId: string) => Promise<void>;
handleRestoreProject?: (projectId: string) => Promise<void>; handleRestoreProject?: (projectId: string) => Promise<void>;
handleDuplicateWorkspaceProject?: (projectId: string, projectName: string, thumbnail: string) => Promise<void>; handleDuplicateWorkspaceProject?: (
handleDuplicateRecentProject?: (projectId: string, projectName: string, thumbnail: string) => Promise<void>; projectId: string,
projectName: string,
thumbnail: string
) => Promise<void>;
handleDuplicateRecentProject?: (
projectId: string,
projectName: string,
thumbnail: string
) => Promise<void>;
active?: string; active?: string;
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>; setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
setRecentDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
setProjectDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
} }
type RelativeTimeFormatUnit = any type RelativeTimeFormatUnit = any;
const DashboardCard: React.FC<DashBoardCardProps> = ({ const DashboardCard: React.FC<DashBoardCardProps> = ({
projectName, projectName,
@ -34,7 +43,9 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
handleTrashDeleteProject, handleTrashDeleteProject,
handleDuplicateWorkspaceProject, handleDuplicateWorkspaceProject,
handleDuplicateRecentProject, handleDuplicateRecentProject,
createdAt createdAt,
setRecentDuplicateData,
setProjectDuplicateData,
}) => { }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const { setProjectName } = useProjectName(); const { setProjectName } = useProjectName();
@ -44,9 +55,9 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
const [isRenaming, setIsRenaming] = useState(false); const [isRenaming, setIsRenaming] = useState(false);
const { projectSocket } = useSocketStore(); const { projectSocket } = useSocketStore();
const kebabRef = useRef<HTMLDivElement>(null); const kebabRef = useRef<HTMLDivElement>(null);
const savedTheme = localStorage.getItem("theme") ?? "light";
const navigateToProject = async (e: any) => { const navigateToProject = async (e: any) => {
if (active && active == "trash") return if (active && active == "trash") return;
try { try {
const viewedProject = await viewProject(organization, projectId, userId); const viewedProject = await viewProject(organization, projectId, userId);
console.log("Viewed project:", viewedProject); console.log("Viewed project:", viewedProject);
@ -63,8 +74,7 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
case "delete": case "delete":
if (handleDeleteProject) { if (handleDeleteProject) {
await handleDeleteProject(projectId); await handleDeleteProject(projectId);
} } else if (handleTrashDeleteProject) {
else if (handleTrashDeleteProject) {
await handleTrashDeleteProject(projectId); await handleTrashDeleteProject(projectId);
} }
break; break;
@ -76,7 +86,7 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
case "open in new tab": case "open in new tab":
try { try {
await viewProject(organization, projectId, userId); await viewProject(organization, projectId, userId);
setProjectName(projectName); // optional depending on scope setProjectName(projectName);
setIsKebabOpen(false); setIsKebabOpen(false);
} catch (error) { } catch (error) {
console.error("Error opening project in new tab:", error); console.error("Error opening project in new tab:", error);
@ -85,50 +95,25 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
break; break;
case "rename": case "rename":
setIsRenaming(true); setIsRenaming(true);
// setRenameValue(projectName);
// Add rename logic here
break; break;
case "duplicate": case "duplicate":
if (handleDuplicateWorkspaceProject) { if (handleDuplicateWorkspaceProject) {
setProjectDuplicateData &&
setProjectDuplicateData({
projectId,
projectName,
thumbnail,
});
await handleDuplicateWorkspaceProject(projectId, projectName, thumbnail); await handleDuplicateWorkspaceProject(projectId, projectName, thumbnail);
} else if (handleDuplicateRecentProject) { } else if (handleDuplicateRecentProject) {
setRecentDuplicateData &&
setRecentDuplicateData({
projectId,
projectName,
thumbnail,
});
await handleDuplicateRecentProject(projectId, projectName, thumbnail); await handleDuplicateRecentProject(projectId, projectName, thumbnail);
} }
// try {
// // const project = await duplicateProject(
// // projectId,
// // savedTheme === "dark" ? darkThemeImage : lightThemeImage,
// // projectName
// // );
// // console.log('project: ', project);
// // const duplicateProjectData = {
// // userId,
// // thumbnail: savedTheme === "dark" ? darkThemeImage : lightThemeImage,
// // organization,
// // projectUuid: projectId,
// // projectName,
// // };
// // if (projectSocket) {
// // // console.log('addProject: ', addProject);
// // const handleResponse = (data: any) => {
// // console.log('Project add response:', data);
// // projectSocket.off("v1-project:response:Duplicate", handleResponse); // Clean up
// // };
// // projectSocket.on("v1-project:response:Duplicate", handleResponse);
// // console.log('duplicate: ', duplicateProjectData);
// // projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
// // const projects = await getAllProjects(userId, organization);
// // console.log("after duplicate", projects);
// // setIsSearchActive && setIsSearchActive(false)
// // }
// } catch (error) {
// console.error("Error creating project:", error);
// }
// Add duplication logic here
break; break;
default: default:
break; break;
@ -140,49 +125,28 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
contextClassName: ["kebab-wrapper", "kebab-options-wrapper"], contextClassName: ["kebab-wrapper", "kebab-options-wrapper"],
setMenuVisible: () => setIsKebabOpen(false), setMenuVisible: () => setIsKebabOpen(false),
}); });
const handleProjectName = async (projectName: string) => {
// setProjectName(projectName);
setRenameValue(projectName)
if (!projectId) return
// localStorage.setItem("projectName", newName);
try {
const projects = await getAllProjects( const handleProjectName = async (projectName: string) => {
userId, organization setRenameValue(projectName);
if (!projectId) return;
try {
const projects = await getAllProjects(userId, organization);
console.log("projects: ", projects);
let projectUuid = projects.Projects.find(
(val: any) => val.projectUuid === projectId || val._id === projectId
); );
console.log('projects: ', projects);
let projectUuid = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId)
const updateProjects = { const updateProjects = {
projectId: projectUuid, projectId: projectUuid,
organization, organization,
userId, userId,
projectName, projectName,
thumbnail: undefined thumbnail: undefined,
} };
if (projectSocket) { if (projectSocket) {
const handleResponse = (data: any) => {
console.log('Project update response:', data);
projectSocket.off("v1-project:response:update", handleResponse); // Clean up
};
projectSocket.on("v1-project:response:update", handleResponse);
projectSocket.emit("v1:project:update", updateProjects); projectSocket.emit("v1:project:update", updateProjects);
} }
} catch (error) { }
//API for projects rename
// const updatedProjectName = await updateProject(
// projectId,
// userId,
// organization,
// undefined,
// projectName
// );
//
} catch (error) {
}
}; };
function getRelativeTime(dateString: string): string { function getRelativeTime(dateString: string): string {
@ -200,7 +164,7 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
second: 1, second: 1,
}; };
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' }); const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
for (const key in intervals) { for (const key in intervals) {
const unit = key as RelativeTimeFormatUnit; const unit = key as RelativeTimeFormatUnit;
@ -209,10 +173,9 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
return rtf.format(-diff, unit); return rtf.format(-diff, unit);
} }
} }
return 'just now'; return "just now";
} }
return ( return (
<button <button
className="dashboard-card-container" className="dashboard-card-container"
@ -221,20 +184,15 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
> >
<div className="dashboard-card-wrapper"> <div className="dashboard-card-wrapper">
<div className="preview-container"> <div className="preview-container">
{thumbnail ? ( {thumbnail ? <img src={thumbnail} alt="" /> : <img src={img} alt="" />}
<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">
{isRenaming ? ( {isRenaming ? (
<input <input
value={renameValue} value={renameValue}
onChange={(e) => { onChange={(e) => {
e.stopPropagation(); // Prevents click from bubbling up e.stopPropagation();
handleProjectName(e.target.value); handleProjectName(e.target.value);
}} }}
onBlur={() => { onBlur={() => {
@ -252,18 +210,21 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
) : ( ) : (
<span>{renameValue}</span> <span>{renameValue}</span>
)} )}
{createdAt && (
{createdAt && <div className="project-data">{active && active == "trash" ? `Trashed by you` : `Edited `} {getRelativeTime(createdAt)}</div>} <div className="project-data">
{active && active == "trash" ? `Trashed by you` : `Edited `}{" "}
{getRelativeTime(createdAt)}
</div>
)}
</div> </div>
<div className="users-list-container" ref={kebabRef}> <div className="users-list-container" ref={kebabRef}>
<div className="user-profile"> <div className="user-profile">
{userName ? userName.charAt(0).toUpperCase() : "A"} {userName ? userName.charAt(0).toUpperCase() : "A"}
</div> </div>
<button <button
className="kebab-wrapper" className="kebab-wrapper"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); // Prevents click from bubbling up e.stopPropagation();
console.log("Kebab menu clicked"); console.log("Kebab menu clicked");
setIsKebabOpen((prev) => !prev); setIsKebabOpen((prev) => !prev);
}} }}
@ -276,24 +237,26 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
{isKebabOpen && active !== "trash" && ( {isKebabOpen && active !== "trash" && (
<div className="kebab-options-wrapper"> <div className="kebab-options-wrapper">
{["rename", "delete", "duplicate", "open in new tab"].map((option) => ( {["rename", "delete", "duplicate", "open in new tab"].map(
<button (option) => (
key={option} <button
className="option" key={option}
title={""} className="option"
onClick={(e) => { title={""}
console.log(option); onClick={(e) => {
e.stopPropagation(); console.log(option);
handleOptionClick(option); e.stopPropagation();
}} handleOptionClick(option);
> }}
{option} >
</button> {option}
))} </button>
)
)}
</div> </div>
)} )}
{isKebabOpen && active && active == "trash" && ( {isKebabOpen && active && active == "trash" && (
< div className="kebab-options-wrapper"> <div className="kebab-options-wrapper">
{["restore", "delete"].map((option) => ( {["restore", "delete"].map((option) => (
<button <button
key={option} key={option}
@ -308,10 +271,9 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
</button> </button>
))} ))}
</div> </div>
) )}
} </button>
</button >
); );
}; };
export default DashboardCard; export default DashboardCard;

View File

@ -7,7 +7,7 @@ import { useSocketStore } from "../../store/builder/store";
import { recentlyViewed } from "../../services/dashboard/recentlyViewed"; import { recentlyViewed } from "../../services/dashboard/recentlyViewed";
import { searchProject } from "../../services/dashboard/searchProjects"; import { searchProject } from "../../services/dashboard/searchProjects";
import { deleteProject } from "../../services/dashboard/deleteProject"; import { deleteProject } from "../../services/dashboard/deleteProject";
import { handleDuplicateProjects } from "./functions/handleDuplicateProject"; import ProjectSocketRes from "./socket/projectSocketRes.dev";
interface Project { interface Project {
_id: string; _id: string;
@ -15,6 +15,7 @@ interface Project {
thumbnail: string; thumbnail: string;
createdBy: string; createdBy: string;
projectUuid?: string; projectUuid?: string;
createdAt: string;
} }
interface RecentProjectsData { interface RecentProjectsData {
@ -26,11 +27,13 @@ const DashboardHome: React.FC = () => {
const [isSearchActive, setIsSearchActive] = useState<boolean>(false); const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
const { userId, organization } = getUserData(); const { userId, organization } = getUserData();
const { projectSocket } = useSocketStore(); const { projectSocket } = useSocketStore();
const [recentDuplicateData, setRecentDuplicateData] = useState<Object>({});
console.log("duplicateData: ", recentDuplicateData);
const fetchRecentProjects = async () => { const fetchRecentProjects = async () => {
try { try {
const projects = await recentlyViewed(organization, userId); const projects = await recentlyViewed(organization, userId);
console.log('RecentlyViewed: ', projects); console.log("RecentlyViewed: ", projects);
if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) { if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) {
setRecentProjects(projects); setRecentProjects(projects);
@ -50,13 +53,12 @@ const DashboardHome: React.FC = () => {
userId, userId,
inputValue inputValue
); );
console.log('filterRecentProcess: ', filterRecentProcess);
setIsSearchActive(true); setIsSearchActive(true);
setRecentProjects(filterRecentProcess.message ? {} : filterRecentProcess); setRecentProjects(filterRecentProcess.message ? {} : filterRecentProcess);
}; };
const handleDeleteProject = async (projectId: any) => { const handleDeleteProject = async (projectId: any) => {
console.log('projectId:delete ', projectId); console.log("projectId:delete ", projectId);
try { try {
//API for delete project //API for delete project
// const deletedProject = await deleteProject( // const deletedProject = await deleteProject(
@ -74,12 +76,6 @@ const DashboardHome: React.FC = () => {
}; };
if (projectSocket) { if (projectSocket) {
const handleResponse = (data: any) => {
console.log("Project add response:", data);
projectSocket.off("v1-project:response:delete", handleResponse);
};
projectSocket.on("v1-project:response:delete", handleResponse);
projectSocket.emit("v1:project:delete", deleteProject); projectSocket.emit("v1:project:delete", deleteProject);
} }
@ -101,20 +97,20 @@ const DashboardHome: React.FC = () => {
} }
}; };
const handleDuplicateRecentProject = async (projectId: string, projectName: string, thumbnail: string) => { const handleDuplicateRecentProject = async (
projectId: string,
await handleDuplicateProjects({ projectName: string,
thumbnail: string
) => {
const duplicateRecentProjectData = {
userId, userId,
organization,
projectId,
projectName,
projectSocket,
thumbnail, thumbnail,
setRecentProjects, organization,
setIsSearchActive projectUuid: projectId,
}); projectName,
};
} projectSocket.emit("v1:project:Duplicate", duplicateRecentProjectData);
};
const renderProjects = () => { const renderProjects = () => {
const projectList = recentProjects[Object.keys(recentProjects)[0]]; const projectList = recentProjects[Object.keys(recentProjects)[0]];
@ -123,16 +119,21 @@ const DashboardHome: React.FC = () => {
return <div className="empty-state">No recent projects found</div>; return <div className="empty-state">No recent projects found</div>;
} }
return projectList && projectList.map((project) => ( return (
<DashboardCard projectList &&
key={project._id} projectList.map((project) => (
projectName={project.projectName} <DashboardCard
thumbnail={project.thumbnail} key={project._id}
projectId={project._id} projectName={project.projectName}
handleDeleteProject={handleDeleteProject} thumbnail={project.thumbnail}
handleDuplicateRecentProject={handleDuplicateRecentProject} projectId={project._id}
/> createdAt={project.createdAt}
)); handleDeleteProject={handleDeleteProject}
handleDuplicateRecentProject={handleDuplicateRecentProject}
setRecentDuplicateData={setRecentDuplicateData}
/>
))
);
}; };
useEffect(() => { useEffect(() => {
@ -147,17 +148,19 @@ const DashboardHome: React.FC = () => {
page="home" page="home"
handleRecentProjectSearch={handleRecentProjectSearch} handleRecentProjectSearch={handleRecentProjectSearch}
/> />
<MarketPlaceBanner /> <MarketPlaceBanner />
<div className="container"> <div className="container">
<h2 className="section-header">Recents</h2> <h2 className="section-header">Recents</h2>
<div className="cards-container">{renderProjects()}</div> <div className="cards-container">{renderProjects()}</div>
</div> </div>
{recentDuplicateData && Object.keys(recentDuplicateData).length > 0 && (
<ProjectSocketRes
setIsSearchActive={setIsSearchActive}
setRecentProjects={setRecentProjects}
/>
)}
</div> </div>
); );
}; };
export default DashboardHome; export default DashboardHome;

View File

@ -6,7 +6,7 @@ import { useSocketStore } from "../../store/builder/store";
import { getAllProjects } from "../../services/dashboard/getAllProjects"; import { getAllProjects } from "../../services/dashboard/getAllProjects";
import { searchProject } from "../../services/dashboard/searchProjects"; import { searchProject } from "../../services/dashboard/searchProjects";
import { deleteProject } from "../../services/dashboard/deleteProject"; import { deleteProject } from "../../services/dashboard/deleteProject";
import { handleDuplicateProjects } from "./functions/handleDuplicateProject"; import ProjectSocketRes from "./socket/projectSocketRes.dev";
interface Project { interface Project {
_id: string; _id: string;
@ -14,6 +14,7 @@ interface Project {
thumbnail: string; thumbnail: string;
createdBy: string; createdBy: string;
projectUuid?: string; projectUuid?: string;
createdAt: string;
} }
interface WorkspaceProjects { interface WorkspaceProjects {
@ -24,9 +25,9 @@ const DashboardProjects: React.FC = () => {
const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>( const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>(
{} {}
); );
console.log('workspaceProjects: ', workspaceProjects); const [projectDuplicateData, setProjectDuplicateData] = useState<Object>({});
console.log("projectDuplicateData: ", projectDuplicateData);
const [isSearchActive, setIsSearchActive] = useState<boolean>(false); const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
const [activeFolder, setActiveFolder] = useState<string>("myProjects"); const [activeFolder, setActiveFolder] = useState<string>("myProjects");
const { projectSocket } = useSocketStore(); const { projectSocket } = useSocketStore();
const { userId, organization } = getUserData(); const { userId, organization } = getUserData();
@ -50,11 +51,7 @@ const DashboardProjects: React.FC = () => {
} }
if (!setWorkspaceProjects || !setIsSearchActive) return; if (!setWorkspaceProjects || !setIsSearchActive) return;
const searchedProject = await searchProject( const searchedProject = await searchProject(organization, userId, inputValue);
organization,
userId,
inputValue
);
setIsSearchActive(true); setIsSearchActive(true);
setWorkspaceProjects(searchedProject.message ? {} : searchedProject); setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
}; };
@ -75,13 +72,6 @@ const DashboardProjects: React.FC = () => {
//socket for deleting the project //socket for deleting the project
if (projectSocket) { if (projectSocket) {
const handleResponse = (data: any) => {
console.log("Project add response:", data);
projectSocket.off("v1-project:response:delete", handleResponse); // Clean up
};
projectSocket.on("v1-project:response:delete", handleResponse);
projectSocket.emit("v1:project:delete", deleteProjects); projectSocket.emit("v1:project:delete", deleteProjects);
} else { } else {
console.error("Socket is not connected."); console.error("Socket is not connected.");
@ -104,20 +94,30 @@ const DashboardProjects: React.FC = () => {
} }
}; };
const handleDuplicateWorkspaceProject = async (projectId: string, projectName: string, thumbnail: string) => { const handleDuplicateWorkspaceProject = async (
projectId: string,
await handleDuplicateProjects({ projectName: string,
thumbnail: string
) => {
// await handleDuplicateProjects({
// userId,
// organization,
// projectId,
// projectName,
// projectSocket,
// thumbnail,
// setWorkspaceProjects,
// setIsSearchActive
// });
const duplicateProjectData = {
userId, userId,
organization,
projectId,
projectName,
projectSocket,
thumbnail, thumbnail,
setWorkspaceProjects, organization,
setIsSearchActive projectUuid: projectId,
}); projectName,
};
} projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
};
const renderProjects = () => { const renderProjects = () => {
if (activeFolder !== "myProjects") return null; if (activeFolder !== "myProjects") return null;
@ -134,9 +134,11 @@ const DashboardProjects: React.FC = () => {
projectName={project.projectName} projectName={project.projectName}
thumbnail={project.thumbnail} thumbnail={project.thumbnail}
projectId={project._id} projectId={project._id}
createdAt={project.createdAt}
handleDeleteProject={handleDeleteProject} handleDeleteProject={handleDeleteProject}
setIsSearchActive={setIsSearchActive} setIsSearchActive={setIsSearchActive}
handleDuplicateWorkspaceProject={handleDuplicateWorkspaceProject} handleDuplicateWorkspaceProject={handleDuplicateWorkspaceProject}
setProjectDuplicateData={setProjectDuplicateData}
/> />
)); ));
}; };
@ -170,9 +172,15 @@ const DashboardProjects: React.FC = () => {
</button> </button>
</div> </div>
<div className="cards-container">{renderProjects()}</div> <div className="cards-container">{renderProjects()}</div>
{projectDuplicateData && Object.keys(projectDuplicateData).length > 0 && (
<ProjectSocketRes
setIsSearchActive={setIsSearchActive}
setWorkspaceProjects={setWorkspaceProjects}
/>
)}
</div> </div>
</div> </div>
); );
}; };
export default DashboardProjects; export default DashboardProjects;

View File

@ -14,6 +14,7 @@ interface Project {
thumbnail: string; thumbnail: string;
createdBy: string; createdBy: string;
projectUuid?: string; projectUuid?: string;
DeletedAt: string;
} }
interface DiscardedProjects { interface DiscardedProjects {
@ -28,7 +29,6 @@ const DashboardTrash: React.FC = () => {
const { userId, organization } = getUserData(); const { userId, organization } = getUserData();
const { projectSocket } = useSocketStore(); const { projectSocket } = useSocketStore();
const fetchTrashProjects = async () => { const fetchTrashProjects = async () => {
try { try {
const projects = await getTrash(organization); const projects = await getTrash(organization);
@ -40,6 +40,7 @@ const DashboardTrash: React.FC = () => {
console.error("Error fetching trash projects:", error); console.error("Error fetching trash projects:", error);
} }
}; };
const handleTrashSearch = async (inputValue: string) => { const handleTrashSearch = async (inputValue: string) => {
if (!inputValue.trim()) { if (!inputValue.trim()) {
setIsSearchActive(false); setIsSearchActive(false);
@ -57,8 +58,9 @@ const DashboardTrash: React.FC = () => {
filterTrashedProcess.message ? {} : filterTrashedProcess filterTrashedProcess.message ? {} : filterTrashedProcess
); );
}; };
const handleRestoreProject = async (projectId: any) => { const handleRestoreProject = async (projectId: any) => {
console.log('projectId: ', projectId); console.log("projectId: ", projectId);
try { try {
const restoreProject = await restoreTrash(organization, projectId); const restoreProject = await restoreTrash(organization, projectId);
// console.log('restoreProject: ', restoreProject); // console.log('restoreProject: ', restoreProject);
@ -82,25 +84,19 @@ const DashboardTrash: React.FC = () => {
console.error("Error deleting project:", error); console.error("Error deleting project:", error);
} }
}; };
const handleTrashDeleteProject = async (projectId: any) => { const handleTrashDeleteProject = async (projectId: any) => {
try { try {
// const deletedProject = await deleteTrash( // const deletedProject = await deleteTrash(
// organization, projectId // organization, projectId
// ); // );
const deleteProjectTrash = { const deleteProjectTrash = {
projectId, projectId,
organization, organization,
userId, userId,
}; };
if (projectSocket) { if (projectSocket) {
const handleResponse = (data: any) => {
console.log('data:deleteTrash ', data);
projectSocket.off("v1:trash:response:delete", handleResponse);
};
projectSocket.on("v1:trash:response:delete", handleResponse);
console.log("duplicate: ", deleteProjectTrash);
projectSocket.emit("v1:trash:delete", deleteProjectTrash); projectSocket.emit("v1:trash:delete", deleteProjectTrash);
} }
setDiscardedProjects((prevDiscardedProjects: DiscardedProjects) => { setDiscardedProjects((prevDiscardedProjects: DiscardedProjects) => {
@ -138,6 +134,7 @@ const DashboardTrash: React.FC = () => {
handleRestoreProject={handleRestoreProject} handleRestoreProject={handleRestoreProject}
handleTrashDeleteProject={handleTrashDeleteProject} handleTrashDeleteProject={handleTrashDeleteProject}
active={"trash"} active={"trash"}
createdAt={project.DeletedAt}
/> />
)); ));
}; };
@ -160,4 +157,4 @@ const DashboardTrash: React.FC = () => {
); );
}; };
export default DashboardTrash; export default DashboardTrash;

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"; import React from "react";
import { import {
DocumentationIcon, DocumentationIcon,
HelpIcon, HelpIcon,
@ -15,33 +15,35 @@ import { SettingsIcon, TrashIcon } from "../icons/ExportCommonIcons";
import { getUserData } from "./functions/getUserData"; import { getUserData } from "./functions/getUserData";
import { useLoadingProgress, useSocketStore } from "../../store/builder/store"; import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
import { createProject } from "../../services/dashboard/createProject"; import { createProject } from "../../services/dashboard/createProject";
interface SidePannelProps { interface SidePannelProps {
setActiveTab: React.Dispatch<React.SetStateAction<string>>; setActiveTab: React.Dispatch<React.SetStateAction<string>>;
activeTab: string activeTab: string;
} }
const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => { const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
const { email, userName, userId, organization } = getUserData(); const { email, userName, userId, organization } = getUserData();
const navigate = useNavigate(); const navigate = useNavigate();
const { loadingProgress, setLoadingProgress } = useLoadingProgress(); const { setLoadingProgress } = useLoadingProgress();
const { dashBoardSocket, projectSocket } = useSocketStore(); const { projectSocket } = useSocketStore();
const savedTheme = localStorage.getItem("theme") ?? "light"; const savedTheme = localStorage.getItem("theme") ?? "light";
function generateProjectId() { function generateProjectId() {
const randomBytes = new Uint8Array(12); const randomBytes = new Uint8Array(12);
crypto.getRandomValues(randomBytes); crypto.getRandomValues(randomBytes);
return Array.from(randomBytes, (byte) => return Array.from(randomBytes, (byte) =>
byte.toString(16).padStart(2, "0")).join(""); byte.toString(16).padStart(2, "0")
).join("");
} }
const handleCreateNewProject = async () => { const handleCreateNewProject = async () => {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
try { try {
const projectId = generateProjectId(); const projectId = generateProjectId();
useSocketStore.getState().initializeSocket(email, organization, token); useSocketStore.getState().initializeSocket(email, organization, token);
console.log('projectId: ', projectId); console.log("projectId: ", projectId);
navigate(`/${projectId}`); navigate(`/${projectId}`);
setLoadingProgress(1) setLoadingProgress(1);
//API for creating new Project //API for creating new Project
// const project = await createProject( // const project = await createProject(
// projectId, // projectId,
@ -56,18 +58,8 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
organization: organization, organization: organization,
projectUuid: projectId, projectUuid: projectId,
}; };
// socket for creating new project console.log("projectSocket: ", projectSocket);
// console.log('dashBoardSocket: ', dashBoardSocket);
console.log('projectSocket: ', projectSocket);
if (projectSocket) { if (projectSocket) {
// console.log('addProject: ', addProject);
const handleResponse = (data: any) => {
console.log('Project add response:', data);
projectSocket.off("v1-project:response:add", handleResponse); // Clean up
};
projectSocket.on("v1-project:response:add", handleResponse);
console.log('addProject: ', addProject);
projectSocket.emit("v1:project:add", addProject); projectSocket.emit("v1:project:add", addProject);
} else { } else {
console.error("Socket is not connected."); console.error("Socket is not connected.");
@ -81,33 +73,76 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
<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?.charAt(0).toUpperCase()}</div> <div className="user-profile">
<div className="user-name">{userName ? userName.charAt(0).toUpperCase() + userName.slice(1).toLowerCase() : "Anonymous"}</div> {userName?.charAt(0).toUpperCase()}
</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" style={{ cursor: "pointer" }} onClick={handleCreateNewProject}>+ 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={activeTab === "Home" ? "option-list active" : "option-list"} onClick={() => setActiveTab("Home")}> <div
className={
activeTab === "Home" ? "option-list active" : "option-list"
}
onClick={() => setActiveTab("Home")}
>
<HomeIcon /> <HomeIcon />
Home Home
</div> </div>
<div className={activeTab === "Projects" ? "option-list active" : "option-list"} title="Projects" onClick={() => setActiveTab("Projects")}> <div
className={
activeTab === "Projects" ? "option-list active" : "option-list"
}
title="Projects"
onClick={() => setActiveTab("Projects")}
>
<ProjectsIcon /> <ProjectsIcon />
Projects Projects
</div> </div>
<div className={activeTab === "Trash" ? "option-list active" : "option-list"} title="Trash" onClick={() => setActiveTab("Trash")}> <div
className={
activeTab === "Trash" ? "option-list active" : "option-list"
}
title="Trash"
onClick={() => setActiveTab("Trash")}
>
<TrashIcon /> <TrashIcon />
Trash Trash
</div> </div>
<div className={activeTab === "Tutorials" ? "option-list active" : "option-list"} title="coming soon" onClick={() => setActiveTab("Tutorials")}> <div
className={
activeTab === "Tutorials" ? "option-list active" : "option-list"
}
title="coming soon"
onClick={() => setActiveTab("Tutorials")}
>
<TutorialsIcon /> <TutorialsIcon />
Tutorials Tutorials
</div> </div>
<div className={activeTab === "Documentation" ? "option-list active" : "option-list"} title="coming soon" onClick={() => setActiveTab("Documentation")}> <div
className={
activeTab === "Documentation"
? "option-list active"
: "option-list"
}
title="coming soon"
onClick={() => setActiveTab("Documentation")}
>
<DocumentationIcon /> <DocumentationIcon />
Documentation Documentation
</div> </div>
@ -131,4 +166,4 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
); );
}; };
export default SidePannel; export default SidePannel;

View File

@ -1,117 +0,0 @@
// import { getAllProjects } from "../../../services/dashboard/getAllProjects";
// interface HandleDuplicateProjectsParams {
// userId: string;
// organization: string;
// projectId: string;
// projectName: string;
// projectSocket: any;
// thumbnail: string;
// setWorkspaceProjects?: React.Dispatch<React.SetStateAction<any>>;
// setRecentProjects?: React.Dispatch<React.SetStateAction<any>>;
// setIsSearchActive: React.Dispatch<React.SetStateAction<boolean>>;
// }
// export const handleDuplicateProjects = async ({
// userId,
// organization,
// projectId,
// projectName,
// projectSocket,
// thumbnail,
// setWorkspaceProjects,
// setRecentProjects,
// setIsSearchActive,
// }: HandleDuplicateProjectsParams): Promise<void> => {
// const duplicateProjectData = {
// userId,
// thumbnail,
// organization,
// projectUuid: projectId,
// projectName,
// };
// if (projectSocket) {
// const handleResponse = (data: any) => {
// console.log("Project add response:", data);
// projectSocket.off("v1-project:response:Duplicate", handleResponse); // Clean up
// };
// projectSocket.on("v1-project:response:Duplicate", handleResponse);
// console.log("duplicate: ", duplicateProjectData);
// projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
// const projects = await getAllProjects(userId, organization);
// console.log("projects: works", projects);
// if (setIsSearchActive) {
// if (setWorkspaceProjects) {
// setWorkspaceProjects(projects);
// } else if (setRecentProjects) {
// setRecentProjects(projects);
// }
// setIsSearchActive(false);
// }
// }
// };
import { getAllProjects } from "../../../services/dashboard/getAllProjects";
import { recentlyViewed } from "../../../services/dashboard/recentlyViewed";
interface HandleDuplicateProjectsParams {
userId: string;
organization: string;
projectId: string;
projectName: string;
projectSocket: any;
thumbnail: string;
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<any>>;
setRecentProjects?: React.Dispatch<React.SetStateAction<any>>;
setIsSearchActive: React.Dispatch<React.SetStateAction<boolean>>;
}
export const handleDuplicateProjects = async ({
userId,
organization,
projectId,
projectName,
projectSocket,
thumbnail,
setWorkspaceProjects,
setRecentProjects,
setIsSearchActive,
}: HandleDuplicateProjectsParams): Promise<void> => {
const duplicateProjectData = {
userId,
thumbnail,
organization,
projectUuid: projectId,
projectName,
};
if (projectSocket) {
const handleResponse = async (data: any) => {
console.log("Project add response:", data);
if (data?.message === "Project Duplicated successfully") {
if (setWorkspaceProjects) {
const allProjects = await getAllProjects(userId, organization);
setWorkspaceProjects(allProjects);
} else if (setRecentProjects) {
const recentProjects = await recentlyViewed(organization, userId);
console.log('recentProjects: ', recentProjects);
setRecentProjects(recentProjects);
}
setIsSearchActive(false);
} else {
console.warn("Duplication failed or unexpected response.");
}
projectSocket.off("v1-project:response:Duplicate", handleResponse); // Clean up
};
projectSocket.on("v1-project:response:Duplicate", handleResponse);
console.log("Emitting duplicate:", duplicateProjectData);
projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
}
};

View File

@ -1,102 +0,0 @@
import React, { useEffect } from 'react';
import { useSocketStore } from '../../../store/builder/store';
import { getAllProjects } from '../../../services/dashboard/getAllProjects';
import { recentlyViewed } from '../../../services/dashboard/recentlyViewed';
import { data } from 'react-router-dom';
interface HandleDuplicateProjectsParams {
userId: string;
organization: string;
projectId: string;
projectName: string;
projectSocket: any;
thumbnail: string;
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<any>>;
setRecentProjects?: React.Dispatch<React.SetStateAction<any>>;
setIsSearchActive: React.Dispatch<React.SetStateAction<boolean>>;
}
const ProjectSocketDev = () => {
const { projectSocket } = useSocketStore();
useEffect(() => {
if (projectSocket) {
projectSocket.on("v1-project:response:add", (data: any) => {
// console.log('data: ', data);
})
projectSocket.on("v1-project:response:delete", (data: any) => {
// console.log('data: ', data)
})
projectSocket.on("v1-project:response:update", (data: any) => {
// console.log('data: ', data);
});
projectSocket.on("v1-project:response:Duplicate", (data: any) => {
// console.log('data: ', data);
})
projectSocket.on("v1:trash:response:delete", (data: any) => {
// console.log('data: ', data);
})
}
return (() => {
projectSocket.off("v1-project:response:add");
projectSocket.off("v1-project:response:delete");
projectSocket.off("v1-project:response:update");
projectSocket.off("v1-project:response:Duplicate");
projectSocket.off("v1:trash:response:delete");
})
}, [projectSocket])
// const handleDuplicateProjects = async ({
// userId,
// organization,
// projectId,
// projectName,
// projectSocket,
// thumbnail,
// setWorkspaceProjects,
// setRecentProjects,
// setIsSearchActive,
// }: HandleDuplicateProjectsParams): Promise<void> => {
// const duplicateProjectData = {
// userId,
// thumbnail,
// organization,
// projectUuid: projectId,
// projectName,
// };
// if (projectSocket) {
// const handleResponse = async (data: any) => {
// console.log("Project add response:", data);
// if (data?.message === "Project Duplicated successfully") {
// if (setWorkspaceProjects) {
// const allProjects = await getAllProjects(userId, organization);
// console.log("allProjects: ", allProjects);
// setWorkspaceProjects(allProjects);
// } else if (setRecentProjects) {
// const recentProjects = await recentlyViewed(organization, userId);
// console.log("recentProjects: ", recentProjects);
// setRecentProjects(recentProjects);
// }
// setIsSearchActive(false);
// } else {
// console.warn("Duplication failed or unexpected response.");
// }
// projectSocket.off("v1-project:response:Duplicate", handleResponse); // Clean up
// };
// projectSocket.on("v1-project:response:Duplicate", handleResponse);
// console.log("Emitting duplicate:", duplicateProjectData);
// }
// };
return <></>
}
export default ProjectSocketDev;

View File

@ -0,0 +1,88 @@
import React, { useEffect } from 'react';
import { useSocketStore } from '../../../store/builder/store';
import { getUserData } from '../functions/getUserData';
import { getAllProjects } from '../../../services/dashboard/getAllProjects';
import { recentlyViewed } from '../../../services/dashboard/recentlyViewed';
interface Project {
_id: string;
projectName: string;
thumbnail: string;
createdBy: string;
projectUuid?: string;
createdAt: string;
}
interface ProjectsData {
[key: string]: Project[];
}
interface ProjectSocketResProps {
setRecentProjects?: React.Dispatch<React.SetStateAction<ProjectsData>>;
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<ProjectsData>>;
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
}
const ProjectSocketRes = ({
setRecentProjects,
setWorkspaceProjects,
setIsSearchActive,
}: ProjectSocketResProps) => {
const { projectSocket } = useSocketStore();
const { userId, organization } = getUserData();
useEffect(() => {
if (!projectSocket) return;
const handleAdd = (data: any) => {
// console.log('Add:', data);
};
const handleDelete = (data: any) => {
// console.log('Delete:', data);
};
const handleUpdate = (data: any) => {
// console.log('Update:', data);
};
const handleTrashDelete = (data: any) => {
// console.log('Trash Delete:', data);
};
const handleDuplicate = async (data: any) => {
console.log("Project duplicate response:", data);
if (data?.message === "Project Duplicated successfully") {
if (setWorkspaceProjects) {
const allProjects = await getAllProjects(userId, organization);
console.log('allProjects: ', allProjects);
setWorkspaceProjects(allProjects);
} else if (setRecentProjects) {
const recentProjects = await recentlyViewed(organization, userId);
setRecentProjects && setRecentProjects(recentProjects);
}
setIsSearchActive && setIsSearchActive(false);
} else {
console.warn("Duplication failed or unexpected response.");
}
};
projectSocket.on("v1-project:response:add", handleAdd);
projectSocket.on("v1-project:response:delete", handleDelete);
projectSocket.on("v1-project:response:update", handleUpdate);
projectSocket.on("v1-project:response:Duplicate", handleDuplicate);
projectSocket.on("v1:trash:response:delete", handleTrashDelete);
return () => {
projectSocket.off("v1-project:response:add", handleAdd);
projectSocket.off("v1-project:response:delete", handleDelete);
projectSocket.off("v1-project:response:update", handleUpdate);
projectSocket.off("v1-project:response:Duplicate", handleDuplicate);
projectSocket.off("v1:trash:response:delete", handleTrashDelete);
};
}, [projectSocket, userId, organization]);
return null;
};
export default ProjectSocketRes;