refactor: Clean up DashboardMain, SidePannel, and ProjectSocketRes components by removing unused imports and optimizing code structure
This commit is contained in:
@@ -15,258 +15,220 @@ import { generateUniqueId } from "../../functions/generateUniqueId";
|
|||||||
import ProjectSocketRes from "./socket/projectSocketRes";
|
import ProjectSocketRes from "./socket/projectSocketRes";
|
||||||
|
|
||||||
interface Project {
|
interface Project {
|
||||||
_id: string;
|
_id: string;
|
||||||
projectName: string;
|
projectName: string;
|
||||||
thumbnail: string;
|
thumbnail: string;
|
||||||
createdBy: { _id: string; userName: string };
|
createdBy: { _id: string; userName: string };
|
||||||
projectUuid?: string;
|
projectUuid?: string;
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
DeletedAt?: string;
|
DeletedAt?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProjectCollection {
|
interface ProjectCollection {
|
||||||
[key: string]: Project[];
|
[key: string]: Project[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type Folder = "home" | "projects" | "shared" | "trash";
|
type Folder = "home" | "projects" | "shared" | "trash";
|
||||||
|
|
||||||
interface DashboardMainProps {
|
interface DashboardMainProps {
|
||||||
activeFolder: Folder;
|
activeFolder: Folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||||
const [activeSubFolder, setActiveSubFolder] = useState("myProjects");
|
const [activeSubFolder, setActiveSubFolder] = useState("myProjects");
|
||||||
const [projectsData, setProjectsData] = useState<ProjectCollection>({});
|
const [projectsData, setProjectsData] = useState<ProjectCollection>({});
|
||||||
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
|
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
|
||||||
const [duplicateData, setDuplicateData] = useState<Object>({});
|
const [duplicateData, setDuplicateData] = useState<Object>({});
|
||||||
const [openKebabProjectId, setOpenKebabProjectId] = useState<string | null>(
|
const [openKebabProjectId, setOpenKebabProjectId] = useState<string | null>(null);
|
||||||
null
|
const [projectsCache, setProjectsCache] = useState<{
|
||||||
);
|
[key: string]: ProjectCollection;
|
||||||
const [projectsCache, setProjectsCache] = useState<{
|
}>({});
|
||||||
[key: string]: ProjectCollection;
|
|
||||||
}>({});
|
|
||||||
|
|
||||||
const { userId, organization } = getUserData();
|
const { userId, organization } = getUserData();
|
||||||
const { projectSocket } = useSocketStore();
|
const { projectSocket } = useSocketStore();
|
||||||
|
|
||||||
// #region API Fetchers
|
// #region API Fetchers
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
const cacheKey =
|
const cacheKey = activeFolder + (activeFolder === "projects" ? `-${activeSubFolder}` : "");
|
||||||
activeFolder + (activeFolder === "projects" ? `-${activeSubFolder}` : "");
|
|
||||||
|
|
||||||
if (projectsCache[cacheKey] && !isSearchActive) {
|
if (projectsCache[cacheKey] && !isSearchActive) {
|
||||||
setProjectsData(projectsCache[cacheKey]);
|
setProjectsData(projectsCache[cacheKey]);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
let projects: ProjectCollection = {}; // initialize as empty object
|
|
||||||
|
|
||||||
switch (activeFolder) {
|
|
||||||
case "home":
|
|
||||||
projects = await recentlyViewed(organization, userId);
|
|
||||||
break;
|
|
||||||
case "projects":
|
|
||||||
if (activeSubFolder === "myProjects") {
|
|
||||||
projects = await getAllProjects(userId, organization);
|
|
||||||
} else {
|
|
||||||
projects = await sharedWithMeProjects();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "trash":
|
|
||||||
projects = await getTrash(organization);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only update cache if projects is not empty
|
|
||||||
if (
|
|
||||||
projects &&
|
|
||||||
JSON.stringify(projects) !== JSON.stringify(projectsData)
|
|
||||||
) {
|
|
||||||
setProjectsCache((prev) => ({ ...prev, [cacheKey]: projects }));
|
|
||||||
setProjectsData(projects);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// #region Search Handlers
|
|
||||||
const handleSearch = async (inputValue: string) => {
|
|
||||||
if (!inputValue.trim()) {
|
|
||||||
setIsSearchActive(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let results;
|
|
||||||
if (activeFolder === "trash") {
|
|
||||||
results = await trashSearchProject(organization, userId, inputValue);
|
|
||||||
} else {
|
|
||||||
results = await searchProject(organization, userId, inputValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsSearchActive(true);
|
|
||||||
setProjectsData(results?.message ? {} : results);
|
|
||||||
};
|
|
||||||
|
|
||||||
// #region Socket Actions
|
|
||||||
const handleDelete = async (projectId: string): Promise<void> => {
|
|
||||||
if (projectSocket) {
|
|
||||||
projectSocket.emit("v1:project:delete", {
|
|
||||||
projectId,
|
|
||||||
organization,
|
|
||||||
userId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
updateStateAfterRemove(projectId);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePermanentDelete = async (projectId: string): Promise<void> => {
|
|
||||||
if (projectSocket) {
|
|
||||||
projectSocket.emit("v1:trash:delete", {
|
|
||||||
projectId,
|
|
||||||
organization,
|
|
||||||
userId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
updateStateAfterRemove(projectId);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleRestore = async (projectId: string): Promise<void> => {
|
|
||||||
await restoreTrash(organization, projectId);
|
|
||||||
updateStateAfterRemove(projectId);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDuplicate = async (
|
|
||||||
projectId: string,
|
|
||||||
projectName: string,
|
|
||||||
thumbnail: string
|
|
||||||
): Promise<void> => {
|
|
||||||
if (projectSocket) {
|
|
||||||
projectSocket.emit("v1:project:Duplicate", {
|
|
||||||
userId,
|
|
||||||
thumbnail,
|
|
||||||
organization,
|
|
||||||
projectUuid: generateUniqueId(),
|
|
||||||
refProjectID: projectId,
|
|
||||||
projectName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// #region Project Map
|
|
||||||
const updateStateAfterRemove = (projectId: string) => {
|
|
||||||
setProjectsData((prev: ProjectCollection) => {
|
|
||||||
const key = Object.keys(prev)[0];
|
|
||||||
const updatedList = prev[key]?.filter((p) => p._id !== projectId) || [];
|
|
||||||
return { ...prev, [key]: updatedList };
|
|
||||||
});
|
|
||||||
setIsSearchActive(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderProjects = () => {
|
|
||||||
const key = Object.keys(projectsData)[0];
|
|
||||||
const projectList = projectsData[key];
|
|
||||||
|
|
||||||
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}
|
|
||||||
createdBy={project.createdBy}
|
|
||||||
createdAt={
|
|
||||||
activeFolder === "trash" ? project.DeletedAt : project.createdAt
|
|
||||||
}
|
}
|
||||||
{...(activeFolder === "home" && {
|
|
||||||
handleDeleteProject: handleDelete,
|
|
||||||
handleDuplicateRecentProject: handleDuplicate,
|
|
||||||
setRecentDuplicateData: setDuplicateData,
|
|
||||||
})}
|
|
||||||
{...(activeSubFolder === "myProjects" && {
|
|
||||||
handleDeleteProject: handleDelete,
|
|
||||||
handleDuplicateWorkspaceProject: handleDuplicate,
|
|
||||||
setProjectDuplicateData: setDuplicateData,
|
|
||||||
})}
|
|
||||||
{...(activeSubFolder === "shared" && {
|
|
||||||
handleDuplicateWorkspaceProject: handleDuplicate,
|
|
||||||
setProjectDuplicateData: setDuplicateData,
|
|
||||||
active: "shared",
|
|
||||||
})}
|
|
||||||
{...(activeFolder === "trash" && {
|
|
||||||
handleRestoreProject: handleRestore,
|
|
||||||
handleTrashDeleteProject: handlePermanentDelete,
|
|
||||||
active: "trash",
|
|
||||||
})}
|
|
||||||
openKebabProjectId={openKebabProjectId}
|
|
||||||
setOpenKebabProjectId={setOpenKebabProjectId}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
// #region Use Effects
|
try {
|
||||||
useEffect(() => {
|
let projects: ProjectCollection = {}; // initialize as empty object
|
||||||
if (!isSearchActive) fetchData();
|
|
||||||
// eslint-disable-next-line
|
|
||||||
}, [activeFolder, isSearchActive, activeSubFolder]);
|
|
||||||
|
|
||||||
return (
|
switch (activeFolder) {
|
||||||
<div className="dashboard-home-container">
|
case "home":
|
||||||
<DashboardNavBar
|
projects = await recentlyViewed(organization, userId);
|
||||||
page={activeFolder}
|
break;
|
||||||
{...(activeFolder === "trash"
|
case "projects":
|
||||||
? { handleTrashSearch: handleSearch }
|
if (activeSubFolder === "myProjects") {
|
||||||
: {
|
projects = await getAllProjects(userId, organization);
|
||||||
handleProjectsSearch: handleSearch,
|
} else {
|
||||||
handleRecentProjectSearch: handleSearch,
|
projects = await sharedWithMeProjects();
|
||||||
})}
|
}
|
||||||
/>
|
break;
|
||||||
|
case "trash":
|
||||||
|
projects = await getTrash(organization);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
{activeFolder === "home" && <MarketPlaceBanner />}
|
// Only update cache if projects is not empty
|
||||||
|
if (projects && JSON.stringify(projects) !== JSON.stringify(projectsData)) {
|
||||||
|
setProjectsCache((prev) => ({ ...prev, [cacheKey]: projects }));
|
||||||
|
setProjectsData(projects);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
<div
|
// #region Search Handlers
|
||||||
className="dashboard-container"
|
const handleSearch = async (inputValue: string) => {
|
||||||
style={{ height: "calc(100% - 87px)" }}
|
if (!inputValue.trim()) {
|
||||||
>
|
setIsSearchActive(false);
|
||||||
{activeFolder === "projects" && (
|
return;
|
||||||
<div
|
}
|
||||||
className="header-wrapper"
|
|
||||||
style={{ display: "flex", gap: "7px" }}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className={`header ${
|
|
||||||
activeSubFolder === "myProjects" && "active"
|
|
||||||
}`}
|
|
||||||
onClick={() => setActiveSubFolder("myProjects")}
|
|
||||||
>
|
|
||||||
My Projects
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className={`header ${activeSubFolder === "shared" && "active"}`}
|
|
||||||
onClick={() => setActiveSubFolder("shared")}
|
|
||||||
>
|
|
||||||
Shared with me
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="cards-container">{renderProjects()}</div>
|
let results;
|
||||||
|
if (activeFolder === "trash") {
|
||||||
|
results = await trashSearchProject(organization, userId, inputValue);
|
||||||
|
} else {
|
||||||
|
results = await searchProject(organization, userId, inputValue);
|
||||||
|
}
|
||||||
|
|
||||||
{duplicateData && Object.keys(duplicateData).length > 0 && (
|
setIsSearchActive(true);
|
||||||
<ProjectSocketRes
|
setProjectsData(results?.message ? {} : results);
|
||||||
setIsSearchActive={setIsSearchActive}
|
};
|
||||||
{...(activeFolder === "home"
|
|
||||||
? { setRecentProjects: setProjectsData }
|
// #region Socket Actions
|
||||||
: { setWorkspaceProjects: setProjectsData })}
|
const handleDelete = async (projectId: string): Promise<void> => {
|
||||||
/>
|
if (projectSocket) {
|
||||||
)}
|
projectSocket.emit("v1:project:delete", {
|
||||||
</div>
|
projectId,
|
||||||
</div>
|
organization,
|
||||||
);
|
userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateStateAfterRemove(projectId);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePermanentDelete = async (projectId: string): Promise<void> => {
|
||||||
|
if (projectSocket) {
|
||||||
|
projectSocket.emit("v1:trash:delete", {
|
||||||
|
projectId,
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateStateAfterRemove(projectId);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRestore = async (projectId: string): Promise<void> => {
|
||||||
|
await restoreTrash(organization, projectId);
|
||||||
|
updateStateAfterRemove(projectId);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDuplicate = async (projectId: string, projectName: string, thumbnail: string): Promise<void> => {
|
||||||
|
if (projectSocket) {
|
||||||
|
projectSocket.emit("v1:project:Duplicate", {
|
||||||
|
userId,
|
||||||
|
thumbnail,
|
||||||
|
organization,
|
||||||
|
projectUuid: generateUniqueId(),
|
||||||
|
refProjectID: projectId,
|
||||||
|
projectName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// #region Project Map
|
||||||
|
const updateStateAfterRemove = (projectId: string) => {
|
||||||
|
setProjectsData((prev: ProjectCollection) => {
|
||||||
|
const key = Object.keys(prev)[0];
|
||||||
|
const updatedList = prev[key]?.filter((p) => p._id !== projectId) || [];
|
||||||
|
return { ...prev, [key]: updatedList };
|
||||||
|
});
|
||||||
|
setIsSearchActive(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderProjects = () => {
|
||||||
|
const key = Object.keys(projectsData)[0];
|
||||||
|
const projectList = projectsData[key];
|
||||||
|
|
||||||
|
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}
|
||||||
|
createdBy={project.createdBy}
|
||||||
|
createdAt={activeFolder === "trash" ? project.DeletedAt : project.createdAt}
|
||||||
|
{...(activeFolder === "home" && {
|
||||||
|
handleDeleteProject: handleDelete,
|
||||||
|
handleDuplicateRecentProject: handleDuplicate,
|
||||||
|
setRecentDuplicateData: setDuplicateData,
|
||||||
|
})}
|
||||||
|
{...(activeSubFolder === "myProjects" && {
|
||||||
|
handleDeleteProject: handleDelete,
|
||||||
|
handleDuplicateWorkspaceProject: handleDuplicate,
|
||||||
|
setProjectDuplicateData: setDuplicateData,
|
||||||
|
})}
|
||||||
|
{...(activeSubFolder === "shared" && {
|
||||||
|
handleDuplicateWorkspaceProject: handleDuplicate,
|
||||||
|
setProjectDuplicateData: setDuplicateData,
|
||||||
|
active: "shared",
|
||||||
|
})}
|
||||||
|
{...(activeFolder === "trash" && {
|
||||||
|
handleRestoreProject: handleRestore,
|
||||||
|
handleTrashDeleteProject: handlePermanentDelete,
|
||||||
|
active: "trash",
|
||||||
|
})}
|
||||||
|
openKebabProjectId={openKebabProjectId}
|
||||||
|
setOpenKebabProjectId={setOpenKebabProjectId}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
// #region Use Effects
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isSearchActive) fetchData();
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [activeFolder, isSearchActive, activeSubFolder]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="dashboard-home-container">
|
||||||
|
<DashboardNavBar
|
||||||
|
page={activeFolder}
|
||||||
|
{...(activeFolder === "trash" ? { handleTrashSearch: handleSearch } : { handleProjectsSearch: handleSearch, handleRecentProjectSearch: handleSearch })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{activeFolder === "home" && <MarketPlaceBanner />}
|
||||||
|
|
||||||
|
<div className="dashboard-container" style={{ height: "calc(100% - 87px)" }}>
|
||||||
|
{activeFolder === "projects" && (
|
||||||
|
<div className="header-wrapper" style={{ display: "flex", gap: "7px" }}>
|
||||||
|
<button className={`header ${activeSubFolder === "myProjects" && "active"}`} onClick={() => setActiveSubFolder("myProjects")}>
|
||||||
|
My Projects
|
||||||
|
</button>
|
||||||
|
<button className={`header ${activeSubFolder === "shared" && "active"}`} onClick={() => setActiveSubFolder("shared")}>
|
||||||
|
Shared with me
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="cards-container">{renderProjects()}</div>
|
||||||
|
|
||||||
|
<ProjectSocketRes setIsSearchActive={setIsSearchActive} {...(activeFolder === "home" ? { setRecentProjects: setProjectsData } : { setWorkspaceProjects: setProjectsData })} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardMain;
|
export default DashboardMain;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import darkThemeImage from "../../assets/image/darkThemeProject.png";
|
|||||||
import lightThemeImage from "../../assets/image/lightThemeProject.png";
|
import lightThemeImage from "../../assets/image/lightThemeProject.png";
|
||||||
import { SettingsIcon, TrashIcon } from "../icons/ExportCommonIcons";
|
import { SettingsIcon, TrashIcon } from "../icons/ExportCommonIcons";
|
||||||
import { getUserData } from "../../functions/getUserData";
|
import { getUserData } from "../../functions/getUserData";
|
||||||
import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
|
import { useSocketStore } from "../../store/builder/store";
|
||||||
|
|
||||||
// import { createProject } from "../../services/dashboard/createProject";
|
// import { createProject } from "../../services/dashboard/createProject";
|
||||||
|
|
||||||
@@ -25,23 +25,20 @@ interface SidePannelProps {
|
|||||||
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 { setLoadingProgress } = useLoadingProgress();
|
|
||||||
const { projectSocket, initializeSocket } = useSocketStore();
|
const { projectSocket, initializeSocket } = 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");
|
||||||
const refreshToken = localStorage.getItem("refreshToken");
|
const refreshToken = localStorage.getItem("refreshToken");
|
||||||
if (!token || !refreshToken) {
|
if (!token || !refreshToken) {
|
||||||
console.error('token expired');
|
console.error("token expired");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,15 +53,8 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
|||||||
organization: organization,
|
organization: organization,
|
||||||
projectUuid: projectId,
|
projectUuid: projectId,
|
||||||
};
|
};
|
||||||
const handleResponse = (data: any) => {
|
|
||||||
if (data.message === "Project created successfully") {
|
|
||||||
setLoadingProgress(1);
|
|
||||||
navigate(`/projects/${data.data.projectId}`);
|
|
||||||
}
|
|
||||||
projectSocket.off("v1-project:response:add", handleResponse);
|
|
||||||
};
|
|
||||||
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 {
|
||||||
// API
|
// API
|
||||||
@@ -81,11 +71,11 @@ 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">
|
<div className="user-profile">{userName?.charAt(0).toUpperCase()}</div>
|
||||||
{userName?.charAt(0).toUpperCase()}
|
|
||||||
</div>
|
|
||||||
<div className="user-name">
|
<div className="user-name">
|
||||||
{userName ? userName.charAt(0).toUpperCase() + userName.slice(1).toLowerCase() : "Anonymous"}
|
{userName
|
||||||
|
? userName.charAt(0).toUpperCase() + userName.slice(1).toLowerCase()
|
||||||
|
: "Anonymous"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="notifications-container">
|
<div className="notifications-container">
|
||||||
@@ -98,18 +88,14 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
|||||||
<div className="side-bar-content-container">
|
<div className="side-bar-content-container">
|
||||||
<div className="side-bar-options-container">
|
<div className="side-bar-options-container">
|
||||||
<button
|
<button
|
||||||
className={
|
className={activeTab === "Home" ? "option-list active" : "option-list"}
|
||||||
activeTab === "Home" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
onClick={() => setActiveTab("Home")}
|
onClick={() => setActiveTab("Home")}
|
||||||
>
|
>
|
||||||
<HomeIcon />
|
<HomeIcon />
|
||||||
Home
|
Home
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={
|
className={activeTab === "Projects" ? "option-list active" : "option-list"}
|
||||||
activeTab === "Projects" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
title="Projects"
|
title="Projects"
|
||||||
onClick={() => setActiveTab("Projects")}
|
onClick={() => setActiveTab("Projects")}
|
||||||
>
|
>
|
||||||
@@ -117,9 +103,7 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
|||||||
Projects
|
Projects
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={
|
className={activeTab === "Trash" ? "option-list active" : "option-list"}
|
||||||
activeTab === "Trash" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
title="Trash"
|
title="Trash"
|
||||||
onClick={() => setActiveTab("Trash")}
|
onClick={() => setActiveTab("Trash")}
|
||||||
>
|
>
|
||||||
@@ -127,9 +111,7 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
|||||||
Trash
|
Trash
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={
|
className={activeTab === "Tutorials" ? "option-list active" : "option-list"}
|
||||||
activeTab === "Tutorials" ? "option-list active" : "option-list"
|
|
||||||
}
|
|
||||||
title="coming soon"
|
title="coming soon"
|
||||||
disabled
|
disabled
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -142,9 +124,7 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
className={
|
className={
|
||||||
activeTab === "Documentation"
|
activeTab === "Documentation" ? "option-list active" : "option-list"
|
||||||
? "option-list active"
|
|
||||||
: "option-list"
|
|
||||||
}
|
}
|
||||||
title="coming soon"
|
title="coming soon"
|
||||||
disabled
|
disabled
|
||||||
|
|||||||
@@ -1,90 +1,97 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useSocketStore } from "../../../store/builder/store";
|
import { useLoadingProgress, useSocketStore } from "../../../store/builder/store";
|
||||||
import { getUserData } from "../../../functions/getUserData";
|
import { getUserData } from "../../../functions/getUserData";
|
||||||
import { getAllProjects } from "../../../services/dashboard/getAllProjects";
|
import { getAllProjects } from "../../../services/dashboard/getAllProjects";
|
||||||
import { recentlyViewed } from "../../../services/dashboard/recentlyViewed";
|
import { recentlyViewed } from "../../../services/dashboard/recentlyViewed";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
interface Project {
|
interface Project {
|
||||||
_id: string;
|
_id: string;
|
||||||
projectName: string;
|
projectName: string;
|
||||||
thumbnail: string;
|
thumbnail: string;
|
||||||
createdBy: { _id: string; userName: string };
|
createdBy: { _id: string; userName: string };
|
||||||
projectUuid?: string;
|
projectUuid?: string;
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
DeletedAt?: string;
|
DeletedAt?: string;
|
||||||
isViewed?: string;
|
isViewed?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProjectCollection {
|
interface ProjectCollection {
|
||||||
[key: string]: Project[];
|
[key: string]: Project[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProjectSocketResProps {
|
interface ProjectSocketResProps {
|
||||||
setRecentProjects?: React.Dispatch<React.SetStateAction<ProjectCollection>>;
|
setRecentProjects?: React.Dispatch<React.SetStateAction<ProjectCollection>>;
|
||||||
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<ProjectCollection>>;
|
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<ProjectCollection>>;
|
||||||
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProjectSocketRes = ({
|
const ProjectSocketRes = ({
|
||||||
setRecentProjects,
|
setRecentProjects,
|
||||||
setWorkspaceProjects,
|
setWorkspaceProjects,
|
||||||
setIsSearchActive,
|
setIsSearchActive,
|
||||||
}: ProjectSocketResProps) => {
|
}: ProjectSocketResProps) => {
|
||||||
const { projectSocket } = useSocketStore();
|
const navigate = useNavigate();
|
||||||
const { userId, organization } = getUserData();
|
const { projectSocket } = useSocketStore();
|
||||||
|
const { userId, organization } = getUserData();
|
||||||
|
const { setLoadingProgress } = useLoadingProgress();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!projectSocket) return;
|
console.log('projectSocket: ', projectSocket);
|
||||||
|
if (!projectSocket) return;
|
||||||
|
|
||||||
const handleAdd = (data: any) => {
|
const handleAdd = (data: any) => {
|
||||||
// console.log("Add:", data);
|
console.log('data: ', data);
|
||||||
};
|
if (data.message === "Project created successfully") {
|
||||||
|
setLoadingProgress(1);
|
||||||
|
navigate(`/projects/${data.data.projectId}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleDelete = (data: any) => {
|
const handleDelete = (data: any) => {
|
||||||
// console.log("Delete:", data);
|
// console.log("Delete:", data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdate = (data: any) => {
|
const handleUpdate = (data: any) => {
|
||||||
// console.log("Update:", data);
|
// console.log("Update:", data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTrashDelete = (data: any) => {
|
const handleTrashDelete = (data: any) => {
|
||||||
// console.log("Trash Delete:", data);
|
// console.log("Trash Delete:", data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDuplicate = async (data: any) => {
|
const handleDuplicate = async (data: any) => {
|
||||||
console.log("Project duplicate response:", data);
|
if (data?.message === "Project Duplicated successfully") {
|
||||||
if (data?.message === "Project Duplicated successfully") {
|
if (setWorkspaceProjects) {
|
||||||
if (setWorkspaceProjects) {
|
const allProjects = await getAllProjects(userId, organization);
|
||||||
const allProjects = await getAllProjects(userId, organization);
|
setWorkspaceProjects(allProjects);
|
||||||
setWorkspaceProjects(allProjects);
|
} else if (setRecentProjects) {
|
||||||
} else if (setRecentProjects) {
|
const recentProjects = await recentlyViewed(organization, userId);
|
||||||
const recentProjects = await recentlyViewed(organization, userId);
|
setRecentProjects(recentProjects);
|
||||||
setRecentProjects(recentProjects);
|
}
|
||||||
}
|
setIsSearchActive && setIsSearchActive(false);
|
||||||
setIsSearchActive && setIsSearchActive(false);
|
} else {
|
||||||
} else {
|
console.warn("Duplication failed or unexpected response.");
|
||||||
console.warn("Duplication failed or unexpected response.");
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
projectSocket.on("v1-project:response:add", handleAdd);
|
projectSocket.on("v1-project:response:add", handleAdd);
|
||||||
projectSocket.on("v1-project:response:delete", handleDelete);
|
projectSocket.on("v1-project:response:delete", handleDelete);
|
||||||
projectSocket.on("v1-project:response:update", handleUpdate);
|
projectSocket.on("v1-project:response:update", handleUpdate);
|
||||||
projectSocket.on("v1-project:response:Duplicate", handleDuplicate);
|
projectSocket.on("v1-project:response:Duplicate", handleDuplicate);
|
||||||
projectSocket.on("v1:trash:response:delete", handleTrashDelete);
|
projectSocket.on("v1:trash:response:delete", handleTrashDelete);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
projectSocket.off("v1-project:response:add", handleAdd);
|
projectSocket.off("v1-project:response:add", handleAdd);
|
||||||
projectSocket.off("v1-project:response:delete", handleDelete);
|
projectSocket.off("v1-project:response:delete", handleDelete);
|
||||||
projectSocket.off("v1-project:response:update", handleUpdate);
|
projectSocket.off("v1-project:response:update", handleUpdate);
|
||||||
projectSocket.off("v1-project:response:Duplicate", handleDuplicate);
|
projectSocket.off("v1-project:response:Duplicate", handleDuplicate);
|
||||||
projectSocket.off("v1:trash:response:delete", handleTrashDelete);
|
projectSocket.off("v1:trash:response:delete", handleTrashDelete);
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [projectSocket, userId, organization]);
|
}, [projectSocket, userId, organization]);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProjectSocketRes;
|
export default ProjectSocketRes;
|
||||||
|
|||||||
Reference in New Issue
Block a user