updated dashboard duplication
This commit is contained in:
@@ -2,289 +2,314 @@ import React, { useState, useRef, useEffect, act } from "react";
|
|||||||
import img from "../../assets/image/image.png";
|
import img from "../../assets/image/image.png";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { getUserData } from "../../functions/getUserData";
|
import { getUserData } from "../../functions/getUserData";
|
||||||
import { useLoadingProgress, useProjectName, useSocketStore } from "../../store/builder/store";
|
import {
|
||||||
|
useLoadingProgress,
|
||||||
|
useProjectName,
|
||||||
|
useSocketStore,
|
||||||
|
} from "../../store/builder/store";
|
||||||
import { viewProject } from "../../services/dashboard/viewProject";
|
import { viewProject } from "../../services/dashboard/viewProject";
|
||||||
import OuterClick from "../../utils/outerClick";
|
import OuterClick from "../../utils/outerClick";
|
||||||
import { KebabIcon } from "../icons/ExportCommonIcons";
|
import { KebabIcon } from "../icons/ExportCommonIcons";
|
||||||
import { getAllProjects } from "../../services/dashboard/getAllProjects";
|
import { getAllProjects } from "../../services/dashboard/getAllProjects";
|
||||||
|
import { updateProject } from "../../services/dashboard/updateProject";
|
||||||
|
|
||||||
interface DashBoardCardProps {
|
interface DashBoardCardProps {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
thumbnail: any;
|
thumbnail: any;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
isViewed?: string;
|
isViewed?: string;
|
||||||
createdBy?: { _id: string, userName: string };
|
createdBy?: { _id: string; userName: 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?: (
|
handleDuplicateWorkspaceProject?: (
|
||||||
projectId: string,
|
projectId: string,
|
||||||
projectName: string,
|
projectName: string,
|
||||||
thumbnail: string,
|
thumbnail: string,
|
||||||
userId?: string
|
userId?: string
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
handleDuplicateRecentProject?: (
|
handleDuplicateRecentProject?: (
|
||||||
projectId: string,
|
projectId: string,
|
||||||
projectName: string,
|
projectName: string,
|
||||||
thumbnail: string
|
thumbnail: string
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
active?: string;
|
active?: string;
|
||||||
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsSearchActive?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
setRecentDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
|
setRecentDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
|
||||||
setProjectDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
|
setProjectDuplicateData?: React.Dispatch<React.SetStateAction<Object>>;
|
||||||
setActiveFolder?: React.Dispatch<React.SetStateAction<string>>;
|
setActiveFolder?: React.Dispatch<React.SetStateAction<string>>;
|
||||||
}
|
}
|
||||||
type RelativeTimeFormatUnit = any;
|
type RelativeTimeFormatUnit = any;
|
||||||
|
|
||||||
const DashboardCard: React.FC<DashBoardCardProps> = ({
|
const DashboardCard: React.FC<DashBoardCardProps> = ({
|
||||||
projectName,
|
projectName,
|
||||||
thumbnail,
|
thumbnail,
|
||||||
projectId,
|
projectId,
|
||||||
active,
|
active,
|
||||||
handleDeleteProject,
|
handleDeleteProject,
|
||||||
handleRestoreProject,
|
handleRestoreProject,
|
||||||
handleTrashDeleteProject,
|
handleTrashDeleteProject,
|
||||||
handleDuplicateWorkspaceProject,
|
handleDuplicateWorkspaceProject,
|
||||||
handleDuplicateRecentProject,
|
handleDuplicateRecentProject,
|
||||||
createdAt,
|
createdAt,
|
||||||
createdBy,
|
createdBy,
|
||||||
setRecentDuplicateData,
|
setRecentDuplicateData,
|
||||||
setProjectDuplicateData,
|
setProjectDuplicateData,
|
||||||
setActiveFolder
|
setActiveFolder,
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setProjectName } = useProjectName();
|
const { setProjectName } = useProjectName();
|
||||||
const { userId, organization, userName } = getUserData();
|
const { userId, organization, userName } = getUserData();
|
||||||
const [isKebabOpen, setIsKebabOpen] = useState(false);
|
const [isKebabOpen, setIsKebabOpen] = useState(false);
|
||||||
const [renameValue, setRenameValue] = useState(projectName);
|
const [renameValue, setRenameValue] = useState(projectName);
|
||||||
const [isRenaming, setIsRenaming] = useState(false);
|
const [isRenaming, setIsRenaming] = useState(false);
|
||||||
const { projectSocket } = useSocketStore();
|
const { projectSocket } = useSocketStore();
|
||||||
const { setLoadingProgress } = useLoadingProgress();
|
const { setLoadingProgress } = useLoadingProgress();
|
||||||
const kebabRef = useRef<HTMLDivElement>(null);
|
const kebabRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const navigateToProject = async (e: any) => {
|
const navigateToProject = async (e: any) => {
|
||||||
console.log('active: ', active);
|
if (active && active == "trash") return;
|
||||||
if (active && active == "trash") return;
|
try {
|
||||||
try {
|
const viewProjects = await viewProject(organization, projectId, userId);
|
||||||
const viewProjects = await viewProject(organization, projectId, userId)
|
|
||||||
console.log('viewProjects: ', viewProjects);
|
|
||||||
console.log('projectName: ', projectName);
|
|
||||||
setLoadingProgress(1)
|
|
||||||
setProjectName(projectName);
|
|
||||||
navigate(`/${projectId}`);
|
|
||||||
} catch {
|
|
||||||
|
|
||||||
|
setLoadingProgress(1);
|
||||||
|
setProjectName(projectName);
|
||||||
|
navigate(`/${projectId}`);
|
||||||
|
} catch {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOptionClick = async (option: string) => {
|
||||||
|
switch (option) {
|
||||||
|
case "delete":
|
||||||
|
if (handleDeleteProject) {
|
||||||
|
handleDeleteProject(projectId);
|
||||||
|
} else if (handleTrashDeleteProject) {
|
||||||
|
handleTrashDeleteProject(projectId);
|
||||||
}
|
}
|
||||||
};
|
break;
|
||||||
|
case "restore":
|
||||||
const handleOptionClick = async (option: string) => {
|
if (handleRestoreProject) {
|
||||||
switch (option) {
|
await handleRestoreProject(projectId);
|
||||||
case "delete":
|
|
||||||
if (handleDeleteProject) {
|
|
||||||
handleDeleteProject(projectId);
|
|
||||||
} else if (handleTrashDeleteProject) {
|
|
||||||
handleTrashDeleteProject(projectId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "restore":
|
|
||||||
if (handleRestoreProject) {
|
|
||||||
await handleRestoreProject(projectId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "open in new tab":
|
|
||||||
try {
|
|
||||||
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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
window.open(`/${projectId}`, "_blank");
|
|
||||||
break;
|
|
||||||
case "rename":
|
|
||||||
setIsRenaming(true);
|
|
||||||
break;
|
|
||||||
case "duplicate":
|
|
||||||
if (handleDuplicateWorkspaceProject) {
|
|
||||||
setProjectDuplicateData &&
|
|
||||||
setProjectDuplicateData({
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
setIsKebabOpen(false);
|
break;
|
||||||
};
|
case "open in new tab":
|
||||||
|
|
||||||
OuterClick({
|
|
||||||
contextClassName: ["kebab-wrapper", "kebab-options-wrapper"],
|
|
||||||
setMenuVisible: () => setIsKebabOpen(false),
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleProjectName = async (projectName: string) => {
|
|
||||||
setRenameValue(projectName);
|
|
||||||
if (!projectId) return;
|
|
||||||
try {
|
try {
|
||||||
const projects = await getAllProjects(userId, organization);
|
if (active === "shared" && createdBy) {
|
||||||
if (!projects || !projects.Projects) return;
|
const newTab = await viewProject(
|
||||||
let projectUuid = projects.Projects.find(
|
organization,
|
||||||
(val: any) => val.projectUuid === projectId || val._id === projectId
|
projectId,
|
||||||
|
createdBy?._id
|
||||||
);
|
);
|
||||||
const updateProjects = {
|
} else {
|
||||||
projectId: projectUuid,
|
const newTab = await viewProject(organization, projectId, userId);
|
||||||
organization,
|
|
||||||
userId,
|
|
||||||
projectName,
|
|
||||||
thumbnail: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (projectSocket) {
|
setProjectName(projectName);
|
||||||
projectSocket.emit("v1:project:update", updateProjects);
|
setIsKebabOpen(false);
|
||||||
}
|
}
|
||||||
} catch (error) { }
|
} catch (error) {}
|
||||||
};
|
window.open(`/${projectId}`, "_blank");
|
||||||
|
break;
|
||||||
function getRelativeTime(dateString: string): string {
|
case "rename":
|
||||||
const date = new Date(dateString);
|
setIsRenaming(true);
|
||||||
const now = new Date();
|
break;
|
||||||
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
case "duplicate":
|
||||||
|
if (handleDuplicateWorkspaceProject) {
|
||||||
const intervals: Record<RelativeTimeFormatUnit, number> = {
|
setProjectDuplicateData &&
|
||||||
year: 31536000,
|
setProjectDuplicateData({
|
||||||
month: 2592000,
|
projectId,
|
||||||
week: 604800,
|
projectName,
|
||||||
day: 86400,
|
thumbnail,
|
||||||
hour: 3600,
|
});
|
||||||
minute: 60,
|
await handleDuplicateWorkspaceProject(
|
||||||
second: 1,
|
projectId,
|
||||||
};
|
projectName,
|
||||||
|
thumbnail,
|
||||||
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
|
userId
|
||||||
|
);
|
||||||
for (const key in intervals) {
|
if (active === "shared" && setActiveFolder) {
|
||||||
const unit = key as RelativeTimeFormatUnit;
|
setActiveFolder("myProjects");
|
||||||
const diff = Math.floor(diffInSeconds / intervals[unit]);
|
}
|
||||||
if (diff >= 1) {
|
} else if (handleDuplicateRecentProject) {
|
||||||
return rtf.format(-diff, unit);
|
setRecentDuplicateData &&
|
||||||
}
|
setRecentDuplicateData({
|
||||||
|
projectId,
|
||||||
|
projectName,
|
||||||
|
thumbnail,
|
||||||
|
userId,
|
||||||
|
});
|
||||||
|
await handleDuplicateRecentProject(projectId, projectName, thumbnail);
|
||||||
}
|
}
|
||||||
return "just now";
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
setIsKebabOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
const kebabOptionsMap: Record<string, string[]> = {
|
OuterClick({
|
||||||
default: ["rename", "delete", "duplicate", "open in new tab"],
|
contextClassName: ["kebab-wrapper", "kebab-options-wrapper"],
|
||||||
trash: ["restore", "delete"],
|
setMenuVisible: () => setIsKebabOpen(false),
|
||||||
shared: ["duplicate", "open in new tab"],
|
});
|
||||||
|
|
||||||
|
const handleProjectName = async (projectName: string) => {
|
||||||
|
setRenameValue(projectName);
|
||||||
|
if (!projectId) return;
|
||||||
|
try {
|
||||||
|
const projects = await getAllProjects(userId, organization);
|
||||||
|
if (!projects || !projects.Projects) return;
|
||||||
|
let projectUuid = projects.Projects.find(
|
||||||
|
(val: any) => val.projectUuid === projectId || val._id === projectId
|
||||||
|
);
|
||||||
|
const updateProjects = {
|
||||||
|
projectId: projectUuid?._id,
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
projectName,
|
||||||
|
thumbnail: undefined,
|
||||||
|
};
|
||||||
|
// const updatedProjectName = await updateProject(
|
||||||
|
// projectUuid._id,
|
||||||
|
// userId,
|
||||||
|
// organization,
|
||||||
|
// undefined,
|
||||||
|
// projectName
|
||||||
|
// );
|
||||||
|
if (projectSocket) {
|
||||||
|
projectSocket.emit("v1:project:update", updateProjects);
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getRelativeTime(dateString: string): string {
|
||||||
|
const date = new Date(dateString);
|
||||||
|
const now = new Date();
|
||||||
|
const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
||||||
|
|
||||||
|
const intervals: Record<RelativeTimeFormatUnit, number> = {
|
||||||
|
year: 31536000,
|
||||||
|
month: 2592000,
|
||||||
|
week: 604800,
|
||||||
|
day: 86400,
|
||||||
|
hour: 3600,
|
||||||
|
minute: 60,
|
||||||
|
second: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOptions = () => {
|
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
|
||||||
if (active === "trash") return kebabOptionsMap.trash;
|
|
||||||
if (active === "shared") return kebabOptionsMap.shared;
|
|
||||||
if (createdBy && createdBy?._id !== userId) return kebabOptionsMap.shared;
|
|
||||||
return kebabOptionsMap.default;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
for (const key in intervals) {
|
||||||
<button
|
const unit = key as RelativeTimeFormatUnit;
|
||||||
className="dashboard-card-container"
|
const diff = Math.floor(diffInSeconds / intervals[unit]);
|
||||||
onClick={navigateToProject}
|
if (diff >= 1) {
|
||||||
title={projectName}
|
return rtf.format(-diff, unit);
|
||||||
onMouseLeave={() => setIsKebabOpen(false)}
|
}
|
||||||
|
}
|
||||||
|
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"
|
||||||
|
onClick={navigateToProject}
|
||||||
|
title={projectName}
|
||||||
|
onMouseLeave={() => setIsKebabOpen(false)}
|
||||||
|
>
|
||||||
|
<div className="dashboard-card-wrapper">
|
||||||
|
<div className="preview-container">
|
||||||
|
{thumbnail ? (
|
||||||
|
<img src={thumbnail} alt="" />
|
||||||
|
) : (
|
||||||
|
<img src={img} alt="" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="project-details-container"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="dashboard-card-wrapper">
|
<div className="project-details">
|
||||||
<div className="preview-container">
|
{isRenaming ? (
|
||||||
{thumbnail ? <img src={thumbnail} alt="" /> : <img src={img} alt="" />}
|
<input
|
||||||
</div>
|
value={renameValue}
|
||||||
<div className="project-details-container" onClick={(e) => { e.stopPropagation() }}>
|
onChange={(e) => {
|
||||||
<div className="project-details">
|
e.stopPropagation();
|
||||||
{isRenaming ? (
|
handleProjectName(e.target.value);
|
||||||
<input
|
}}
|
||||||
value={renameValue}
|
onBlur={() => {
|
||||||
onChange={(e) => {
|
setIsRenaming(false);
|
||||||
e.stopPropagation();
|
setProjectName(renameValue);
|
||||||
handleProjectName(e.target.value);
|
}}
|
||||||
}}
|
onKeyDown={(e) => {
|
||||||
onBlur={() => {
|
if (e.key === "Enter") {
|
||||||
setIsRenaming(false);
|
setProjectName(renameValue);
|
||||||
setProjectName(renameValue);
|
setIsRenaming(false);
|
||||||
}}
|
}
|
||||||
onKeyDown={(e) => {
|
}}
|
||||||
if (e.key === "Enter") {
|
autoFocus
|
||||||
setProjectName(renameValue);
|
/>
|
||||||
setIsRenaming(false);
|
) : (
|
||||||
}
|
<span>{renameValue}</span>
|
||||||
}}
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<span>{renameValue}</span>
|
|
||||||
)}
|
|
||||||
{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">
|
|
||||||
{(!createdBy) ? userName ? userName?.charAt(0).toUpperCase() : "A" : createdBy?.userName?.charAt(0).toUpperCase()}
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
className="kebab-wrapper"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
setIsKebabOpen((prev) => !prev);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<KebabIcon />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{isKebabOpen && (
|
|
||||||
<div className="kebab-options-wrapper">
|
|
||||||
{getOptions().map((option) => (
|
|
||||||
<button
|
|
||||||
key={option}
|
|
||||||
className="option"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
handleOptionClick(option);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{option}
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</button>
|
{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">
|
||||||
|
{!createdBy
|
||||||
|
? userName
|
||||||
|
? userName?.charAt(0).toUpperCase()
|
||||||
|
: "A"
|
||||||
|
: createdBy?.userName?.charAt(0).toUpperCase()}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="kebab-wrapper"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setIsKebabOpen((prev) => !prev);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<KebabIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{isKebabOpen && (
|
||||||
|
<div className="kebab-options-wrapper">
|
||||||
|
{getOptions().map((option) => (
|
||||||
|
<button
|
||||||
|
key={option}
|
||||||
|
className="option"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handleOptionClick(option);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardCard;
|
export default DashboardCard;
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ 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;
|
||||||
isViewed?: string
|
isViewed?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RecentProjectsData {
|
interface RecentProjectsData {
|
||||||
@@ -25,12 +25,12 @@ interface RecentProjectsData {
|
|||||||
|
|
||||||
const DashboardHome: React.FC = () => {
|
const DashboardHome: React.FC = () => {
|
||||||
const [recentProjects, setRecentProjects] = useState<RecentProjectsData>({});
|
const [recentProjects, setRecentProjects] = useState<RecentProjectsData>({});
|
||||||
|
|
||||||
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>({});
|
const [recentDuplicateData, setRecentDuplicateData] = useState<Object>({});
|
||||||
|
|
||||||
|
|
||||||
const fetchRecentProjects = async () => {
|
const fetchRecentProjects = async () => {
|
||||||
try {
|
try {
|
||||||
const projects = await recentlyViewed(organization, userId);
|
const projects = await recentlyViewed(organization, userId);
|
||||||
@@ -38,9 +38,7 @@ const DashboardHome: React.FC = () => {
|
|||||||
if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) {
|
if (JSON.stringify(projects) !== JSON.stringify(recentProjects)) {
|
||||||
setRecentProjects(projects);
|
setRecentProjects(projects);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {}
|
||||||
console.error("Error fetching recent projects:", error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRecentProjectSearch = async (inputValue: string) => {
|
const handleRecentProjectSearch = async (inputValue: string) => {
|
||||||
@@ -65,7 +63,7 @@ const DashboardHome: React.FC = () => {
|
|||||||
// userId,
|
// userId,
|
||||||
// organization
|
// organization
|
||||||
// );
|
// );
|
||||||
// console.log('deletedProject: ', deletedProject);
|
//
|
||||||
|
|
||||||
//socket for delete Project
|
//socket for delete Project
|
||||||
const deleteProject = {
|
const deleteProject = {
|
||||||
@@ -91,9 +89,7 @@ const DashboardHome: React.FC = () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
setIsSearchActive(false);
|
setIsSearchActive(false);
|
||||||
} catch (error) {
|
} catch (error) {}
|
||||||
console.error("Error deleting project:", error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDuplicateRecentProject = async (
|
const handleDuplicateRecentProject = async (
|
||||||
@@ -163,4 +159,4 @@ const DashboardHome: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardHome;
|
export default DashboardHome;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { deleteProject } from "../../services/dashboard/deleteProject";
|
|||||||
import ProjectSocketRes from "./socket/projectSocketRes.dev";
|
import ProjectSocketRes from "./socket/projectSocketRes.dev";
|
||||||
import { sharedWithMeProjects } from "../../services/dashboard/sharedWithMeProject";
|
import { sharedWithMeProjects } from "../../services/dashboard/sharedWithMeProject";
|
||||||
import { duplicateProject } from "../../services/dashboard/duplicateProject";
|
import { duplicateProject } from "../../services/dashboard/duplicateProject";
|
||||||
|
import { generateUniqueId } from "../../functions/generateUniqueId";
|
||||||
|
|
||||||
interface Project {
|
interface Project {
|
||||||
_id: string;
|
_id: string;
|
||||||
@@ -27,7 +28,7 @@ const DashboardProjects: React.FC = () => {
|
|||||||
const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>(
|
const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
const [sharedwithMeProject, setSharedWithMeProjects] = useState<any>([])
|
const [sharedwithMeProject, setSharedWithMeProjects] = useState<any>([]);
|
||||||
const [projectDuplicateData, setProjectDuplicateData] = useState<Object>({});
|
const [projectDuplicateData, setProjectDuplicateData] = useState<Object>({});
|
||||||
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
|
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
|
||||||
const [activeFolder, setActiveFolder] = useState<string>("myProjects");
|
const [activeFolder, setActiveFolder] = useState<string>("myProjects");
|
||||||
@@ -41,7 +42,11 @@ const DashboardProjects: React.FC = () => {
|
|||||||
}
|
}
|
||||||
if (!setWorkspaceProjects || !setIsSearchActive) return;
|
if (!setWorkspaceProjects || !setIsSearchActive) return;
|
||||||
|
|
||||||
const searchedProject = await searchProject(organization, userId, inputValue);
|
const searchedProject = await searchProject(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
inputValue
|
||||||
|
);
|
||||||
setIsSearchActive(true);
|
setIsSearchActive(true);
|
||||||
setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
|
setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
|
||||||
};
|
};
|
||||||
@@ -49,14 +54,13 @@ const DashboardProjects: React.FC = () => {
|
|||||||
const fetchAllProjects = async () => {
|
const fetchAllProjects = async () => {
|
||||||
try {
|
try {
|
||||||
const projects = await getAllProjects(userId, organization);
|
const projects = await getAllProjects(userId, organization);
|
||||||
|
|
||||||
if (!projects || !projects.Projects) return;
|
if (!projects || !projects.Projects) return;
|
||||||
|
|
||||||
if (JSON.stringify(projects) !== JSON.stringify(workspaceProjects)) {
|
if (JSON.stringify(projects) !== JSON.stringify(workspaceProjects)) {
|
||||||
setWorkspaceProjects(projects);
|
setWorkspaceProjects(projects);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {}
|
||||||
console.error("Error fetching projects:", error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteProject = async (projectId: any) => {
|
const handleDeleteProject = async (projectId: any) => {
|
||||||
@@ -66,7 +70,7 @@ const DashboardProjects: React.FC = () => {
|
|||||||
// userId,
|
// userId,
|
||||||
// organization
|
// organization
|
||||||
// );
|
// );
|
||||||
// console.log('deletedProject: ', deletedProject);
|
//
|
||||||
const deleteProjects = {
|
const deleteProjects = {
|
||||||
projectId,
|
projectId,
|
||||||
organization,
|
organization,
|
||||||
@@ -77,7 +81,6 @@ const DashboardProjects: React.FC = () => {
|
|||||||
if (projectSocket) {
|
if (projectSocket) {
|
||||||
projectSocket.emit("v1:project:delete", deleteProjects);
|
projectSocket.emit("v1:project:delete", deleteProjects);
|
||||||
} else {
|
} else {
|
||||||
console.error("Socket is not connected.");
|
|
||||||
}
|
}
|
||||||
setWorkspaceProjects((prevDiscardedProjects: WorkspaceProjects) => {
|
setWorkspaceProjects((prevDiscardedProjects: WorkspaceProjects) => {
|
||||||
if (!Array.isArray(prevDiscardedProjects?.Projects)) {
|
if (!Array.isArray(prevDiscardedProjects?.Projects)) {
|
||||||
@@ -92,16 +95,21 @@ const DashboardProjects: React.FC = () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
setIsSearchActive(false);
|
setIsSearchActive(false);
|
||||||
} catch (error) {
|
} catch (error) {}
|
||||||
console.error("Error deleting project:", error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDuplicateWorkspaceProject = async (
|
const handleDuplicateWorkspaceProject = async (
|
||||||
projectId: string,
|
projectId: string,
|
||||||
projectName: string,
|
projectName: string,
|
||||||
thumbnail: string,
|
thumbnail: string
|
||||||
) => {
|
) => {
|
||||||
|
const duplicatedProject = await duplicateProject(
|
||||||
|
projectId,
|
||||||
|
generateUniqueId(),
|
||||||
|
thumbnail,
|
||||||
|
projectName
|
||||||
|
);
|
||||||
|
console.log("duplicatedProject: ", duplicatedProject);
|
||||||
|
|
||||||
const duplicateProjectData = {
|
const duplicateProjectData = {
|
||||||
userId,
|
userId,
|
||||||
@@ -110,7 +118,7 @@ const DashboardProjects: React.FC = () => {
|
|||||||
projectUuid: projectId,
|
projectUuid: projectId,
|
||||||
projectName,
|
projectName,
|
||||||
};
|
};
|
||||||
projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
|
// projectSocket.emit("v1:project:Duplicate", duplicateProjectData);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderProjects = () => {
|
const renderProjects = () => {
|
||||||
@@ -153,16 +161,12 @@ const DashboardProjects: React.FC = () => {
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const sharedProject = async () => {
|
const sharedProject = async () => {
|
||||||
try {
|
try {
|
||||||
const sharedWithMe = await sharedWithMeProjects();
|
const sharedWithMe = await sharedWithMeProjects();
|
||||||
setSharedWithMeProjects(sharedWithMe)
|
setSharedWithMeProjects(sharedWithMe);
|
||||||
} catch {
|
} catch {}
|
||||||
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isSearchActive) {
|
if (!isSearchActive) {
|
||||||
@@ -172,10 +176,9 @@ const DashboardProjects: React.FC = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeFolder === "shared") {
|
if (activeFolder === "shared") {
|
||||||
sharedProject()
|
sharedProject();
|
||||||
}
|
}
|
||||||
}, [activeFolder])
|
}, [activeFolder]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dashboard-home-container">
|
<div className="dashboard-home-container">
|
||||||
@@ -184,7 +187,10 @@ const DashboardProjects: React.FC = () => {
|
|||||||
handleProjectsSearch={handleProjectsSearch}
|
handleProjectsSearch={handleProjectsSearch}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="dashboard-container" style={{ height: "calc(100% - 87px)" }}>
|
<div
|
||||||
|
className="dashboard-container"
|
||||||
|
style={{ height: "calc(100% - 87px)" }}
|
||||||
|
>
|
||||||
<div className="header-wrapper" style={{ display: "flex", gap: "7px" }}>
|
<div className="header-wrapper" style={{ display: "flex", gap: "7px" }}>
|
||||||
<button
|
<button
|
||||||
className={`header ${activeFolder === "myProjects" && "active"}`}
|
className={`header ${activeFolder === "myProjects" && "active"}`}
|
||||||
@@ -199,19 +205,22 @@ const DashboardProjects: React.FC = () => {
|
|||||||
Shared with me
|
Shared with me
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="cards-container">{activeFolder == "myProjects" ? renderProjects() : renderSharedProjects()}</div>
|
<div className="cards-container">
|
||||||
|
{activeFolder == "myProjects"
|
||||||
|
? renderProjects()
|
||||||
|
: renderSharedProjects()}
|
||||||
|
</div>
|
||||||
|
|
||||||
{projectDuplicateData && Object.keys(projectDuplicateData).length > 0 && (
|
{projectDuplicateData &&
|
||||||
<ProjectSocketRes
|
Object.keys(projectDuplicateData).length > 0 && (
|
||||||
setIsSearchActive={setIsSearchActive}
|
<ProjectSocketRes
|
||||||
setWorkspaceProjects={setWorkspaceProjects}
|
setIsSearchActive={setIsSearchActive}
|
||||||
/>
|
setWorkspaceProjects={setWorkspaceProjects}
|
||||||
)}
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardProjects;
|
export default DashboardProjects;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,100 +10,101 @@ import { updateProject } from "../../services/dashboard/updateProject";
|
|||||||
import { getUserData } from "../../functions/getUserData";
|
import { getUserData } from "../../functions/getUserData";
|
||||||
|
|
||||||
const FileMenu: React.FC = () => {
|
const FileMenu: React.FC = () => {
|
||||||
const [openMenu, setOpenMenu] = useState(false);
|
const [openMenu, setOpenMenu] = useState(false);
|
||||||
const containerRef = useRef<HTMLButtonElement>(null);
|
const containerRef = useRef<HTMLButtonElement>(null);
|
||||||
let clickTimeout: NodeJS.Timeout | null = null;
|
let clickTimeout: NodeJS.Timeout | null = null;
|
||||||
const { projectName, setProjectName } = useProjectName();
|
const { projectName, setProjectName } = useProjectName();
|
||||||
const { dashBoardSocket } = useSocketStore();
|
const { dashBoardSocket } = useSocketStore();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const { userId, organization, email } = getUserData();
|
const { userId, organization, email } = getUserData();
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
if (clickTimeout) return;
|
if (clickTimeout) return;
|
||||||
setOpenMenu((prev) => !prev);
|
setOpenMenu((prev) => !prev);
|
||||||
clickTimeout = setTimeout(() => {
|
clickTimeout = setTimeout(() => {
|
||||||
clickTimeout = null;
|
clickTimeout = null;
|
||||||
}, 800);
|
}, 800);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (
|
||||||
|
containerRef.current &&
|
||||||
|
!containerRef.current.contains(event.target as Node)
|
||||||
|
) {
|
||||||
|
setOpenMenu(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
||||||
if (
|
}, []);
|
||||||
containerRef.current &&
|
|
||||||
!containerRef.current.contains(event.target as Node)
|
|
||||||
) {
|
|
||||||
setOpenMenu(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener("mousedown", handleClickOutside);
|
const handleProjectRename = async (projectName: string) => {
|
||||||
return () => document.removeEventListener("mousedown", handleClickOutside);
|
setProjectName(projectName);
|
||||||
}, []);
|
if (!projectId) return;
|
||||||
|
|
||||||
const handleProjectRename = async (projectName: string) => {
|
// localStorage.setItem("projectName", newName);
|
||||||
setProjectName(projectName);
|
|
||||||
if (!projectId) return
|
|
||||||
|
|
||||||
// localStorage.setItem("projectName", newName);
|
try {
|
||||||
|
if (!email || !userId) return;
|
||||||
|
|
||||||
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
|
||||||
|
);
|
||||||
|
|
||||||
if (!email || !userId) return;
|
const updateProjects = {
|
||||||
|
projectId: projectUuid?._id,
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
projectName,
|
||||||
|
thumbnail: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
const projects = await getAllProjects(userId, organization);
|
// if (dashBoardSocket) {
|
||||||
if (!projects || !projects.Projects) return;
|
// const handleResponse = (data: any) => {
|
||||||
// console.log('projects: ', projects);
|
// console.log('Project update response:', data);
|
||||||
let projectUuid = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId)
|
// dashBoardSocket.off("v1-project:response:update", handleResponse); // Clean up
|
||||||
|
// };
|
||||||
|
// dashBoardSocket.on("v1-project:response:update", handleResponse);
|
||||||
|
// dashBoardSocket.emit("v1:project:update", updateProjects);
|
||||||
|
// }
|
||||||
|
|
||||||
const updateProjects = {
|
//API for projects rename
|
||||||
projectId: projectUuid,
|
const updatedProjectName = await updateProject(
|
||||||
organization,
|
projectId,
|
||||||
userId,
|
userId,
|
||||||
projectName,
|
organization,
|
||||||
thumbnail: undefined
|
undefined,
|
||||||
}
|
projectName
|
||||||
|
);
|
||||||
// if (dashBoardSocket) {
|
console.log("updatedProjectName: ", updatedProjectName, projectId);
|
||||||
// const handleResponse = (data: any) => {
|
} catch (error) {
|
||||||
// console.log('Project update response:', data);
|
console.error("Error updating project name:", error);
|
||||||
// dashBoardSocket.off("v1-project:response:update", handleResponse); // Clean up
|
}
|
||||||
// };
|
};
|
||||||
// dashBoardSocket.on("v1-project:response:update", handleResponse);
|
return (
|
||||||
// dashBoardSocket.emit("v1:project:update", updateProjects);
|
<button
|
||||||
// }
|
id="project-dropdown-button"
|
||||||
|
className="project-dropdowm-container"
|
||||||
//API for projects rename
|
ref={containerRef}
|
||||||
const updatedProjectName = await updateProject(
|
onClick={handleClick}
|
||||||
projectId,
|
>
|
||||||
userId,
|
<div className="project-name">
|
||||||
organization,
|
<div className="icon">
|
||||||
undefined,
|
<ProjectIcon />
|
||||||
projectName
|
</div>
|
||||||
);
|
<RenameInput value={projectName} onRename={handleProjectRename} />
|
||||||
//
|
</div>
|
||||||
} catch (error) {
|
<div className="more-options-button">
|
||||||
console.error("Error updating project name:", error);
|
<ArrowIcon />
|
||||||
}
|
{openMenu && <MenuBar setOpenMenu={setOpenMenu} />}
|
||||||
};
|
</div>
|
||||||
return (
|
</button>
|
||||||
<button
|
);
|
||||||
id="project-dropdown-button"
|
|
||||||
className="project-dropdowm-container"
|
|
||||||
ref={containerRef}
|
|
||||||
onClick={handleClick}
|
|
||||||
>
|
|
||||||
<div className="project-name">
|
|
||||||
<div className="icon">
|
|
||||||
<ProjectIcon />
|
|
||||||
</div>
|
|
||||||
<RenameInput value={projectName} onRename={handleProjectRename} />
|
|
||||||
</div>
|
|
||||||
<div className="more-options-button">
|
|
||||||
<ArrowIcon />
|
|
||||||
{openMenu && <MenuBar setOpenMenu={setOpenMenu} />}
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FileMenu;
|
export default FileMenu;
|
||||||
|
|||||||
@@ -16,69 +16,89 @@ import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
|
|||||||
import { Color, SRGBColorSpace } from "three";
|
import { Color, SRGBColorSpace } from "three";
|
||||||
import StatsHelper from "./helpers/StatsHelper";
|
import StatsHelper from "./helpers/StatsHelper";
|
||||||
|
|
||||||
export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Comparison Layout' }) {
|
export default function Scene({
|
||||||
const map = useMemo(() => [
|
layout,
|
||||||
{ name: "forward", keys: ["ArrowUp", "w", "W"] },
|
}: {
|
||||||
{ name: "backward", keys: ["ArrowDown", "s", "S"] },
|
readonly layout: "Main Layout" | "Comparison Layout";
|
||||||
{ name: "left", keys: ["ArrowLeft", "a", "A"] },
|
}) {
|
||||||
{ name: "right", keys: ["ArrowRight", "d", "D"] },
|
const map = useMemo(
|
||||||
], []);
|
() => [
|
||||||
const { assetStore } = useSceneContext();
|
{ name: "forward", keys: ["ArrowUp", "w", "W"] },
|
||||||
const { assets } = assetStore();
|
{ name: "backward", keys: ["ArrowDown", "s", "S"] },
|
||||||
const { userId, organization } = getUserData();
|
{ name: "left", keys: ["ArrowLeft", "a", "A"] },
|
||||||
const { projectId } = useParams();
|
{ name: "right", keys: ["ArrowRight", "d", "D"] },
|
||||||
const { projectSocket } = useSocketStore();
|
],
|
||||||
const { activeModule } = useModuleStore();
|
[]
|
||||||
const { loadingProgress } = useLoadingProgress();
|
);
|
||||||
|
const { assetStore } = useSceneContext();
|
||||||
|
const { assets } = assetStore();
|
||||||
|
const { userId, organization } = getUserData();
|
||||||
|
const { projectId } = useParams();
|
||||||
|
const { projectSocket } = useSocketStore();
|
||||||
|
const { activeModule } = useModuleStore();
|
||||||
|
const { loadingProgress } = useLoadingProgress();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!projectId && loadingProgress > 1) return;
|
if (!projectId && loadingProgress > 1) return;
|
||||||
getAllProjects(userId, organization)
|
getAllProjects(userId, organization)
|
||||||
.then((projects) => {
|
.then((projects) => {
|
||||||
if (!projects || !projects.Projects) return;
|
if (!projects || !projects.Projects) return;
|
||||||
let project = projects.Projects.find((val: any) => val.projectUuid === projectId || val._id === projectId);
|
let project = projects.Projects.find(
|
||||||
const canvas = document.getElementById("sceneCanvas")?.getElementsByTagName('canvas')[0];
|
(val: any) => val.projectUuid === projectId || val._id === projectId
|
||||||
if (!canvas) return;
|
);
|
||||||
const screenshotDataUrl = (canvas as HTMLCanvasElement)?.toDataURL("image/png");
|
const canvas = document
|
||||||
const updateProjects = {
|
.getElementById("sceneCanvas")
|
||||||
projectId: project?.projectUuid,
|
?.getElementsByTagName("canvas")[0];
|
||||||
organization,
|
if (!canvas) return;
|
||||||
userId,
|
const screenshotDataUrl = (canvas as HTMLCanvasElement)?.toDataURL(
|
||||||
projectName: project?.projectName,
|
"image/png"
|
||||||
thumbnail: screenshotDataUrl,
|
);
|
||||||
};
|
const updateProjects = {
|
||||||
if (projectSocket) {
|
projectId: project?._id,
|
||||||
projectSocket.emit("v1:project:update", updateProjects);
|
organization,
|
||||||
}
|
userId,
|
||||||
}).catch((err) => {
|
projectName: project?.projectName,
|
||||||
console.error(err);
|
thumbnail: screenshotDataUrl,
|
||||||
});
|
};
|
||||||
// eslint-disable-next-line
|
if (projectSocket) {
|
||||||
}, [activeModule, assets, loadingProgress])
|
projectSocket.emit("v1:project:update", updateProjects);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [activeModule, assets, loadingProgress]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyboardControls map={map}>
|
<KeyboardControls map={map}>
|
||||||
<Canvas
|
<Canvas
|
||||||
id="sceneCanvas"
|
id="sceneCanvas"
|
||||||
shadows
|
shadows
|
||||||
color="#aaaa"
|
color="#aaaa"
|
||||||
eventPrefix="client"
|
eventPrefix="client"
|
||||||
onContextMenu={(e) => {
|
onContextMenu={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}}
|
||||||
performance={{ min: 0.9, max: 1.0 }}
|
performance={{ min: 0.9, max: 1.0 }}
|
||||||
onCreated={(e) => {
|
onCreated={(e) => {
|
||||||
e.scene.background = layout === 'Main Layout' ? null : new Color(0x19191d);
|
e.scene.background =
|
||||||
}}
|
layout === "Main Layout" ? null : new Color(0x19191d);
|
||||||
gl={{ outputColorSpace: SRGBColorSpace, powerPreference: "high-performance", antialias: true, preserveDrawingBuffer: true }}
|
}}
|
||||||
>
|
gl={{
|
||||||
<Setup />
|
outputColorSpace: SRGBColorSpace,
|
||||||
<Collaboration />
|
powerPreference: "high-performance",
|
||||||
<Builder />
|
antialias: true,
|
||||||
<Simulation />
|
preserveDrawingBuffer: true,
|
||||||
<Visualization />
|
}}
|
||||||
<StatsHelper />
|
>
|
||||||
</Canvas>
|
<Setup />
|
||||||
</KeyboardControls>
|
<Collaboration />
|
||||||
);
|
<Builder />
|
||||||
|
<Simulation />
|
||||||
|
<Visualization />
|
||||||
|
<StatsHelper />
|
||||||
|
</Canvas>
|
||||||
|
</KeyboardControls>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ const Project: React.FC = () => {
|
|||||||
const { setUserName } = useUserName();
|
const { setUserName } = useUserName();
|
||||||
const { setOrganization } = useOrganization();
|
const { setOrganization } = useOrganization();
|
||||||
const { projectId } = useParams();
|
const { projectId } = useParams();
|
||||||
const { setProjectName } = useProjectName();
|
const { projectName, setProjectName } = useProjectName();
|
||||||
|
console.log("projectName: ", projectName);
|
||||||
const { userId, email, organization, userName } = getUserData();
|
const { userId, email, organization, userName } = getUserData();
|
||||||
const { selectedUser } = useSelectedUserStore();
|
const { selectedUser } = useSelectedUserStore();
|
||||||
const { isLogListVisible } = useLogger();
|
const { isLogListVisible } = useLogger();
|
||||||
@@ -49,6 +50,7 @@ const Project: React.FC = () => {
|
|||||||
const fetchProjects = async () => {
|
const fetchProjects = async () => {
|
||||||
try {
|
try {
|
||||||
const projects = await getAllProjects(userId, organization);
|
const projects = await getAllProjects(userId, organization);
|
||||||
|
console.log("projects: ", projects);
|
||||||
const shared = await sharedWithMeProjects();
|
const shared = await sharedWithMeProjects();
|
||||||
|
|
||||||
const allProjects = [...(projects?.Projects || []), ...(shared || [])];
|
const allProjects = [...(projects?.Projects || []), ...(shared || [])];
|
||||||
@@ -56,7 +58,6 @@ const Project: React.FC = () => {
|
|||||||
const matchedProject = allProjects.find(
|
const matchedProject = allProjects.find(
|
||||||
(val: any) => val.projectUuid === projectId || val._id === projectId
|
(val: any) => val.projectUuid === projectId || val._id === projectId
|
||||||
);
|
);
|
||||||
|
|
||||||
if (matchedProject) {
|
if (matchedProject) {
|
||||||
setProjectName(matchedProject.projectName);
|
setProjectName(matchedProject.projectName);
|
||||||
await viewProject(organization, matchedProject._id, userId);
|
await viewProject(organization, matchedProject._id, userId);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||||
|
|
||||||
export const duplicateProject = async (
|
export const duplicateProject = async (
|
||||||
|
refProjectID: string,
|
||||||
projectUuid: string,
|
projectUuid: string,
|
||||||
thumbnail: string,
|
thumbnail: string,
|
||||||
projectName: string
|
projectName: string
|
||||||
@@ -16,7 +17,12 @@ export const duplicateProject = async (
|
|||||||
token: localStorage.getItem("token") || "", // Coerce null to empty string
|
token: localStorage.getItem("token") || "", // Coerce null to empty string
|
||||||
refresh_token: localStorage.getItem("refreshToken") || "",
|
refresh_token: localStorage.getItem("refreshToken") || "",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ projectUuid, thumbnail, projectName }),
|
body: JSON.stringify({
|
||||||
|
refProjectID,
|
||||||
|
projectUuid,
|
||||||
|
thumbnail,
|
||||||
|
projectName,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const newAccessToken = response.headers.get("x-access-token");
|
const newAccessToken = response.headers.get("x-access-token");
|
||||||
@@ -24,7 +30,7 @@ export const duplicateProject = async (
|
|||||||
//console.log("New token received:", newAccessToken);
|
//console.log("New token received:", newAccessToken);
|
||||||
localStorage.setItem("token", newAccessToken);
|
localStorage.setItem("token", newAccessToken);
|
||||||
}
|
}
|
||||||
// console.log("response: ", response);
|
console.log("response: ", response);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error("Failed to add project");
|
console.error("Failed to add project");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export const updateProject = async (
|
|||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
console.log('body: ', body);
|
||||||
|
|
||||||
const newAccessToken = response.headers.get("x-access-token");
|
const newAccessToken = response.headers.get("x-access-token");
|
||||||
if (newAccessToken) {
|
if (newAccessToken) {
|
||||||
@@ -41,6 +42,7 @@ export const updateProject = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
console.log('result: ', result);
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof Error) {
|
if (error instanceof Error) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user