fix: dashboard types updated, tutorial started
This commit is contained in:
@@ -14,36 +14,21 @@ import { restoreTrashApi } from "../../services/dashboard/restoreTrashApi";
|
||||
import { generateUniqueId } from "../../functions/generateUniqueId";
|
||||
import ProjectSocketRes from "./socket/projectSocketRes";
|
||||
|
||||
interface Project {
|
||||
_id: string;
|
||||
projectName: string;
|
||||
thumbnail: string;
|
||||
createdBy: { _id: string; userName: string };
|
||||
projectUuid?: string;
|
||||
createdAt?: string;
|
||||
DeletedAt?: string;
|
||||
}
|
||||
|
||||
interface ProjectCollection {
|
||||
[key: string]: Project[];
|
||||
}
|
||||
|
||||
type Folder = "home" | "projects" | "shared" | "trash";
|
||||
|
||||
interface DashboardMainProps {
|
||||
activeFolder: Folder;
|
||||
}
|
||||
|
||||
const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
const [activeSubFolder, setActiveSubFolder] = useState("myProjects");
|
||||
const [projectsData, setProjectsData] = useState<ProjectCollection>({});
|
||||
const [projectsData, setProjectsData] = useState<DashboardProjectCollection>({});
|
||||
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
|
||||
const [duplicateData, setDuplicateData] = useState<Object>({});
|
||||
const [openKebabProjectId, setOpenKebabProjectId] = useState<string | null>(null);
|
||||
const [projectsCache, setProjectsCache] = useState<{ [key: string]: ProjectCollection }>({});
|
||||
const [projectsCache, setProjectsCache] = useState<{ [key: string]: DashboardProjectCollection }>({});
|
||||
|
||||
const { userId, organization } = getUserData();
|
||||
const { projectSocket } = useSocketStore();
|
||||
console.log("duplicateData: ", duplicateData);
|
||||
|
||||
// #region API Fetchers
|
||||
const fetchData = async () => {
|
||||
@@ -55,7 +40,7 @@ const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
}
|
||||
|
||||
try {
|
||||
let projects: ProjectCollection = {}; // initialize as empty object
|
||||
let projects: DashboardProjectCollection = {}; // initialize as empty object
|
||||
|
||||
switch (activeFolder) {
|
||||
case "home":
|
||||
@@ -71,6 +56,8 @@ const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
case "trash":
|
||||
projects = await getTrashApi();
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Only update cache if projects is not empty
|
||||
@@ -129,7 +116,11 @@ const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
updateStateAfterRemove(projectId);
|
||||
};
|
||||
|
||||
const handleDuplicate = async (projectId: string, projectName: string, thumbnail: string): Promise<void> => {
|
||||
const handleDuplicate = async (
|
||||
projectId: string,
|
||||
projectName: string,
|
||||
thumbnail: string
|
||||
): Promise<void> => {
|
||||
if (projectSocket) {
|
||||
projectSocket.emit("v1:project:Duplicate", {
|
||||
userId,
|
||||
@@ -144,7 +135,7 @@ const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
|
||||
// #region Project Map
|
||||
const updateStateAfterRemove = (projectId: string) => {
|
||||
setProjectsData((prev: ProjectCollection) => {
|
||||
setProjectsData((prev: DashboardProjectCollection) => {
|
||||
const key = Object.keys(prev)[0];
|
||||
const updatedList = prev[key]?.filter((p) => p._id !== projectId) || [];
|
||||
return { ...prev, [key]: updatedList };
|
||||
@@ -204,7 +195,12 @@ const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
<div className="dashboard-home-container">
|
||||
<DashboardNavBar
|
||||
page={activeFolder}
|
||||
{...(activeFolder === "trash" ? { handleTrashSearch: handleSearch } : { handleProjectsSearch: handleSearch, handleRecentProjectSearch: handleSearch })}
|
||||
{...(activeFolder === "trash"
|
||||
? { handleTrashSearch: handleSearch }
|
||||
: {
|
||||
handleProjectsSearch: handleSearch,
|
||||
handleRecentProjectSearch: handleSearch,
|
||||
})}
|
||||
/>
|
||||
|
||||
{activeFolder === "home" && <MarketPlaceBanner />}
|
||||
@@ -212,10 +208,16 @@ const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
<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")}>
|
||||
<button
|
||||
className={`header ${activeSubFolder === "myProjects" && "active"}`}
|
||||
onClick={() => setActiveSubFolder("myProjects")}
|
||||
>
|
||||
My Projects
|
||||
</button>
|
||||
<button className={`header ${activeSubFolder === "shared" && "active"}`} onClick={() => setActiveSubFolder("shared")}>
|
||||
<button
|
||||
className={`header ${activeSubFolder === "shared" && "active"}`}
|
||||
onClick={() => setActiveSubFolder("shared")}
|
||||
>
|
||||
Shared with me
|
||||
</button>
|
||||
</div>
|
||||
@@ -223,7 +225,12 @@ const DashboardMain: React.FC<DashboardMainProps> = ({ activeFolder }) => {
|
||||
|
||||
<div className="cards-container">{renderProjects()}</div>
|
||||
|
||||
<ProjectSocketRes setIsSearchActive={setIsSearchActive} {...(activeFolder === "home" ? { setRecentProjects: setProjectsData } : { setWorkspaceProjects: setProjectsData })} />
|
||||
<ProjectSocketRes
|
||||
setIsSearchActive={setIsSearchActive}
|
||||
{...(activeFolder === "home"
|
||||
? { setRecentProjects: setProjectsData }
|
||||
: { setWorkspaceProjects: setProjectsData })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,61 +1,12 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import DashboardNavBar from "./DashboardNavBar";
|
||||
import DashboardCard from "./DashboardCard";
|
||||
import { projectTutorialApi } from "../../services/dashboard/projectTutorialApi";
|
||||
|
||||
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 projectTutorialApi();
|
||||
setTutorialProject(tutorial);
|
||||
} catch {}
|
||||
};
|
||||
|
||||
const [openKebabProjectId, setOpenKebabProjectId] = useState<string | null>(null);
|
||||
|
||||
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}
|
||||
openKebabProjectId={openKebabProjectId}
|
||||
setOpenKebabProjectId={setOpenKebabProjectId}
|
||||
/>
|
||||
));
|
||||
};
|
||||
return (
|
||||
<div className="dashboard-home-container">
|
||||
<DashboardNavBar page="tutorial" />
|
||||
|
||||
<div className="dashboard-container" style={{ height: "calc(100% - 87px)" }}>
|
||||
<div className="header" style={{ display: "flex", gap: "7px" }}></div>
|
||||
<div className="cards-container">{renderTrashProjects()}</div>
|
||||
<button className="add-tutorials-button">+</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -115,9 +115,9 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
||||
<button
|
||||
className={activeTab === "Tutorials" ? "option-list active" : "option-list"}
|
||||
title="coming soon"
|
||||
disabled
|
||||
// disabled
|
||||
onClick={() => {
|
||||
// setActiveTab("Tutorials");
|
||||
setActiveTab("Tutorials");
|
||||
console.warn("Tutorials comming soon");
|
||||
}}
|
||||
>
|
||||
@@ -127,9 +127,9 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
|
||||
<button
|
||||
className={activeTab === "Documentation" ? "option-list active" : "option-list"}
|
||||
title="coming soon"
|
||||
disabled
|
||||
disabled // remove when added
|
||||
onClick={() => {
|
||||
// setActiveTab("Documentation");
|
||||
setActiveTab("Documentation");
|
||||
console.warn("Documentation comming soon");
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -5,24 +5,14 @@ import { getAllProjectsApi } from "../../../services/dashboard/getAllProjectsApi
|
||||
import { recentlyViewedApi } from "../../../services/dashboard/recentlyViewedApi";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
interface Project {
|
||||
_id: string;
|
||||
projectName: string;
|
||||
thumbnail: string;
|
||||
createdBy: { _id: string; userName: string };
|
||||
projectUuid?: string;
|
||||
createdAt?: string;
|
||||
DeletedAt?: string;
|
||||
isViewed?: string;
|
||||
}
|
||||
|
||||
interface ProjectCollection {
|
||||
[key: string]: Project[];
|
||||
interface DashboardProjectCollection {
|
||||
[key: string]: DashboardProject[];
|
||||
}
|
||||
|
||||
interface ProjectSocketResProps {
|
||||
setRecentProjects?: React.Dispatch<React.SetStateAction<ProjectCollection>>;
|
||||
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<ProjectCollection>>;
|
||||
setRecentProjects?: React.Dispatch<React.SetStateAction<DashboardProjectCollection>>;
|
||||
setWorkspaceProjects?: React.Dispatch<React.SetStateAction<DashboardProjectCollection>>;
|
||||
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,31 +6,27 @@ import DashboardTutorial from "../components/Dashboard/DashboardTutorial";
|
||||
import DashboardMain from "../components/Dashboard/DashboardMain";
|
||||
|
||||
const Dashboard: React.FC = () => {
|
||||
const [activeTab, setActiveTab] = useState<string>("Home");
|
||||
const { socket } = useSocketStore();
|
||||
const { organization, email } = getUserData();
|
||||
const [activeTab, setActiveTab] = useState<string>("Home");
|
||||
const { socket } = useSocketStore();
|
||||
const { organization, email } = getUserData();
|
||||
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
if (token && refreshToken) {
|
||||
useSocketStore
|
||||
.getState()
|
||||
.initializeSocket(email, organization, token, refreshToken);
|
||||
}
|
||||
}, [socket, email, organization]);
|
||||
|
||||
return (
|
||||
<div className="dashboard-main">
|
||||
<SidePannel setActiveTab={setActiveTab} activeTab={activeTab} />
|
||||
<DashboardMain
|
||||
activeFolder={
|
||||
activeTab.toLowerCase() as "home" | "projects" | "shared" | "trash"
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem("token");
|
||||
const refreshToken = localStorage.getItem("refreshToken");
|
||||
if (token && refreshToken) {
|
||||
useSocketStore.getState().initializeSocket(email, organization, token, refreshToken);
|
||||
}
|
||||
/>
|
||||
{activeTab === "Tutorials" && <DashboardTutorial />}
|
||||
</div>
|
||||
);
|
||||
}, [socket, email, organization]);
|
||||
|
||||
return (
|
||||
<div className="dashboard-main">
|
||||
<SidePannel setActiveTab={setActiveTab} activeTab={activeTab} />
|
||||
{["Home", "Projects", "Shared", "Trash"].includes(activeTab) && (
|
||||
<DashboardMain activeFolder={activeTab.toLowerCase() as Folder} />
|
||||
)}
|
||||
{activeTab === "Tutorials" && <DashboardTutorial />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dashboard;
|
||||
|
||||
@@ -31,7 +31,7 @@ const ForgotPassword: React.FC = () => {
|
||||
try {
|
||||
const emailResponse = await checkEmailApi(email);
|
||||
|
||||
if (emailResponse.message == "OTP sent Successfully") {
|
||||
if (emailResponse.message === "OTP sent Successfully") {
|
||||
setCode(emailResponse.OTP);
|
||||
}
|
||||
} catch {}
|
||||
@@ -41,7 +41,7 @@ const ForgotPassword: React.FC = () => {
|
||||
try {
|
||||
const emailResponse = await checkEmailApi(email);
|
||||
|
||||
if (emailResponse.message == "OTP sent Successfully") {
|
||||
if (emailResponse.message === "OTP sent Successfully") {
|
||||
setStep(2);
|
||||
setCode(emailResponse.OTP);
|
||||
}
|
||||
@@ -52,7 +52,7 @@ const ForgotPassword: React.FC = () => {
|
||||
try {
|
||||
const otpResponse = await verifyOtpApi(email, Number(code));
|
||||
|
||||
if (otpResponse.message == "OTP verified successfully") {
|
||||
if (otpResponse.message === "OTP verified successfully") {
|
||||
setResetToken(otpResponse.resetToken);
|
||||
setStep(3);
|
||||
} else {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import React, { useEffect } from 'react'
|
||||
|
||||
function sessionValidity() {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default sessionValidity
|
||||
16
app/src/types/dashboard.d.ts
vendored
Normal file
16
app/src/types/dashboard.d.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
interface DashboardProject {
|
||||
_id: string;
|
||||
projectName: string;
|
||||
thumbnail: string;
|
||||
createdBy: { _id: string; userName: string };
|
||||
projectUuid?: string;
|
||||
createdAt?: string;
|
||||
DeletedAt?: string;
|
||||
}
|
||||
|
||||
interface DashboardProjectCollection {
|
||||
[key: string]: DashboardProject[];
|
||||
}
|
||||
|
||||
type Folder = "home" | "projects" | "shared" | "trash";
|
||||
Reference in New Issue
Block a user