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