Enhance dashboard components with user collaboration features and project management improvements

This commit is contained in:
2025-06-26 09:25:02 +05:30
parent 62e315e3d9
commit b3b0831a7f
10 changed files with 380 additions and 114 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from "react";
import React, { useState, useRef, useEffect, act } from "react";
import img from "../../assets/image/image.png";
import { useNavigate } from "react-router-dom";
import { getUserData } from "../../functions/getUserData";
@@ -14,13 +14,15 @@ interface DashBoardCardProps {
projectId: string;
createdAt?: string;
isViewed?: string;
createdBy?: { _id: string, userName: string };
handleDeleteProject?: (projectId: string) => Promise<void>;
handleTrashDeleteProject?: (projectId: string) => Promise<void>;
handleRestoreProject?: (projectId: string) => Promise<void>;
handleDuplicateWorkspaceProject?: (
projectId: string,
projectName: string,
thumbnail: string
thumbnail: string,
userId?: string
) => Promise<void>;
handleDuplicateRecentProject?: (
projectId: string,
@@ -31,6 +33,7 @@ interface DashBoardCardProps {
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
setRecentDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
setProjectDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
setActiveFolder?: React.Dispatch<React.SetStateAction<string>>;
}
type RelativeTimeFormatUnit = any;
@@ -45,8 +48,10 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
handleDuplicateWorkspaceProject,
handleDuplicateRecentProject,
createdAt,
createdBy,
setRecentDuplicateData,
setProjectDuplicateData,
setActiveFolder
}) => {
const navigate = useNavigate();
const { setProjectName } = useProjectName();
@@ -59,10 +64,18 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
const kebabRef = useRef<HTMLDivElement>(null);
const navigateToProject = async (e: any) => {
console.log('active: ', active);
if (active && active == "trash") return;
setLoadingProgress(1)
setProjectName(projectName);
navigate(`/${projectId}`);
try {
const viewProjects = await viewProject(organization, projectId, userId)
console.log('viewProjects: ', viewProjects);
console.log('projectName: ', projectName);
setLoadingProgress(1)
setProjectName(projectName);
navigate(`/${projectId}`);
} catch {
}
};
const handleOptionClick = async (option: string) => {
@@ -81,11 +94,18 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
break;
case "open in new tab":
try {
await viewProject(organization, projectId, userId);
setProjectName(projectName);
setIsKebabOpen(false);
if (active === "shared" && createdBy) {
console.log("ihreq");
const newTab = await viewProject(organization, projectId, createdBy?._id);
console.log('newTab: ', newTab);
} else {
const newTab = await viewProject(organization, projectId, userId);
console.log('newTab: ', newTab);
setProjectName(projectName);
setIsKebabOpen(false);
}
} catch (error) {
console.error("Error opening project in new tab:", error);
}
window.open(`/${projectId}`, "_blank");
break;
@@ -100,13 +120,17 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
projectName,
thumbnail,
});
await handleDuplicateWorkspaceProject(projectId, projectName, thumbnail);
await handleDuplicateWorkspaceProject(projectId, projectName, thumbnail, userId);
if (active === "shared" && setActiveFolder) {
setActiveFolder("myProjects")
}
} else if (handleDuplicateRecentProject) {
setRecentDuplicateData &&
setRecentDuplicateData({
projectId,
projectName,
thumbnail,
userId
});
await handleDuplicateRecentProject(projectId, projectName, thumbnail);
}
@@ -128,7 +152,6 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
try {
const projects = await getAllProjects(userId, organization);
if (!projects || !projects.Projects) return;
// console.log("projects: ", projects);
let projectUuid = projects.Projects.find(
(val: any) => val.projectUuid === projectId || val._id === projectId
);
@@ -173,6 +196,19 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
return "just now";
}
const kebabOptionsMap: Record<string, string[]> = {
default: ["rename", "delete", "duplicate", "open in new tab"],
trash: ["restore", "delete"],
shared: ["duplicate", "open in new tab"],
};
const getOptions = () => {
if (active === "trash") return kebabOptionsMap.trash;
if (active === "shared") return kebabOptionsMap.shared;
if (createdBy && createdBy?._id !== userId) return kebabOptionsMap.shared;
return kebabOptionsMap.default;
};
return (
<button
className="dashboard-card-container"
@@ -212,13 +248,12 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
<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"}
{(!createdBy) ? userName ? userName?.charAt(0).toUpperCase() : "A" : createdBy?.userName?.charAt(0).toUpperCase()}
</div>
<button
className="kebab-wrapper"
@@ -232,29 +267,9 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
</div>
</div>
</div>
{isKebabOpen && active !== "trash" && (
{isKebabOpen && (
<div className="kebab-options-wrapper">
{["rename", "delete", "duplicate", "open in new tab"].map(
(option) => (
<button
key={option}
className="option"
title={""}
onClick={(e) => {
e.stopPropagation();
handleOptionClick(option);
}}
>
{option}
</button>
)
)}
</div>
)}
{isKebabOpen && active && active == "trash" && (
<div className="kebab-options-wrapper">
{["restore", "delete"].map((option) => (
{getOptions().map((option) => (
<button
key={option}
className="option"