Refactor Dashboard components and styles for improved functionality and UI consistency
This commit is contained in:
parent
0ecb85a211
commit
8af4442a28
|
@ -1,10 +1,11 @@
|
||||||
import React from "react";
|
import React, { useState, useRef } from "react";
|
||||||
import { KebabIcon } from "../../icons/ExportCommonIcons";
|
import { KebabIcon } from "../../icons/ExportCommonIcons";
|
||||||
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 { useProjectName } from "../../../store/builder/store";
|
import { useProjectName } from "../../../store/builder/store";
|
||||||
import { viewProject } from "../../../services/dashboard/viewProject";
|
import { viewProject } from "../../../services/dashboard/viewProject";
|
||||||
import { getUserData } from "./functions/getUserData";
|
import { getUserData } from "./functions/getUserData";
|
||||||
|
import OuterClick from "../../../utils/outerClick";
|
||||||
|
|
||||||
interface DashBoardCardProps {
|
interface DashBoardCardProps {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
|
@ -21,58 +22,113 @@ const DashboardCard: React.FC<DashBoardCardProps> = ({
|
||||||
projectId,
|
projectId,
|
||||||
handleRestoreProject,
|
handleRestoreProject,
|
||||||
}) => {
|
}) => {
|
||||||
let 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 handleKebabIconClick = async () => {
|
const kebabRef = useRef<HTMLDivElement>(null);
|
||||||
try {
|
|
||||||
if (handleRestoreProject) {
|
|
||||||
await handleRestoreProject(projectId);
|
|
||||||
} else if (handleDeleteProject) {
|
|
||||||
await handleDeleteProject(projectId);
|
|
||||||
}
|
|
||||||
} catch { }
|
|
||||||
};
|
|
||||||
|
|
||||||
const navigateToProject = async () => {
|
const navigateToProject = async () => {
|
||||||
try {
|
try {
|
||||||
const viewedProject = await viewProject(organization, projectId, userId);
|
const viewedProject = await viewProject(organization, projectId, userId);
|
||||||
console.log("Saved viewwdProject:", viewedProject);
|
console.log("Viewed project:", viewedProject);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error deleting project:", error);
|
console.error("Error opening project:", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
setProjectName(projectName);
|
setProjectName(projectName);
|
||||||
navigate(`/${projectId}`);
|
navigate(`/${projectId}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOptionClick = async (option: string) => {
|
||||||
|
switch (option) {
|
||||||
|
case "delete":
|
||||||
|
if (handleDeleteProject) {
|
||||||
|
await handleDeleteProject(projectId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "restore":
|
||||||
|
if (handleRestoreProject) {
|
||||||
|
await handleRestoreProject(projectId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "openInNewTab":
|
||||||
|
window.open(`/${projectId}`, "_blank");
|
||||||
|
break;
|
||||||
|
case "rename":
|
||||||
|
// Add rename logic here
|
||||||
|
break;
|
||||||
|
case "duplicate":
|
||||||
|
// Add duplication logic here
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setIsKebabOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
OuterClick({
|
||||||
|
contextClassName: ["kebab-wrapper", "kebab-options-wrapper"],
|
||||||
|
setMenuVisible: () => setIsKebabOpen(false),
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div className="dashboard-card-container" onClick={navigateToProject} title={projectName}>
|
<button
|
||||||
<div className="preview-container">
|
className="dashboard-card-container"
|
||||||
{thumbnail ? <img src={thumbnail} alt="" /> : <img src={img} alt="" />}
|
onClick={navigateToProject}
|
||||||
</div>
|
title={projectName}
|
||||||
<div className="project-details-container">
|
>
|
||||||
<div className="project-details">
|
<div className="dashboard-card-wrapper">
|
||||||
<div className="project-name">{projectName}</div>
|
<div className="preview-container">
|
||||||
<div className="project-data">24-12-2025</div>
|
{thumbnail ? (
|
||||||
|
<img src={thumbnail} alt="" />
|
||||||
|
) : (
|
||||||
|
<img src={img} alt="" />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="users-list-container">
|
<div className="project-details-container">
|
||||||
<div className="user-profile">
|
<div className="project-details">
|
||||||
{userName ? userName.charAt(0).toUpperCase() : "Anonymous"}
|
<div className="project-name">{projectName}</div>
|
||||||
|
<div className="project-data">24-12-2025</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="users-list-container" ref={kebabRef}>
|
||||||
onClick={(e) => {
|
<div className="user-profile">
|
||||||
e.stopPropagation();
|
{userName ? userName.charAt(0).toUpperCase() : "A"}
|
||||||
handleKebabIconClick();
|
</div>
|
||||||
}}
|
|
||||||
>
|
<button
|
||||||
<KebabIcon />
|
className="kebab-wrapper"
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation(); // Prevents click from bubbling up
|
||||||
|
console.log("Kebab menu clicked");
|
||||||
|
setIsKebabOpen((prev) => !prev);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<KebabIcon />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
{isKebabOpen && (
|
||||||
|
<div className="kebab-options-wrapper">
|
||||||
|
{["rename", "delete", "duplicate", "open in new tab"].map((option) => (
|
||||||
|
<button
|
||||||
|
key={option}
|
||||||
|
className="option"
|
||||||
|
onClick={(e) => {
|
||||||
|
console.log(option);
|
||||||
|
e.stopPropagation();
|
||||||
|
handleOptionClick(option);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardCard;
|
export default DashboardCard;
|
||||||
|
|
|
@ -43,7 +43,11 @@ const DashboardHome: React.FC = () => {
|
||||||
setIsSearchActive(false);
|
setIsSearchActive(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const filterRecentProcess = await searchProject(organization, userId, inputValue);
|
const filterRecentProcess = await searchProject(
|
||||||
|
organization,
|
||||||
|
userId,
|
||||||
|
inputValue
|
||||||
|
);
|
||||||
setIsSearchActive(true);
|
setIsSearchActive(true);
|
||||||
setRecentProjects(filterRecentProcess.message ? {} : filterRecentProcess);
|
setRecentProjects(filterRecentProcess.message ? {} : filterRecentProcess);
|
||||||
};
|
};
|
||||||
|
@ -127,11 +131,13 @@ const DashboardHome: React.FC = () => {
|
||||||
<MarketPlaceBanner />
|
<MarketPlaceBanner />
|
||||||
|
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<h2 className="section-header">Recent Projects</h2>
|
<h2 className="section-header">Recents</h2>
|
||||||
<div className="cards-container">{renderProjects()}</div>
|
<div className="cards-container">{renderProjects()}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardHome;
|
export default DashboardHome;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,155 +1,154 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import DashboardNavBar from './DashboardNavBar';
|
import DashboardNavBar from "./DashboardNavBar";
|
||||||
import DashboardCard from './DashboardCard';
|
import DashboardCard from "./DashboardCard";
|
||||||
import { getAllProjects } from '../../../services/dashboard/getAllProjects';
|
import { getAllProjects } from "../../../services/dashboard/getAllProjects";
|
||||||
import { getUserData } from './functions/getUserData';
|
import { getUserData } from "./functions/getUserData";
|
||||||
import { searchProject } from '../../../services/dashboard/searchProjects';
|
import { searchProject } from "../../../services/dashboard/searchProjects";
|
||||||
import { deleteProject } from '../../../services/dashboard/deleteProject';
|
import { deleteProject } from "../../../services/dashboard/deleteProject";
|
||||||
import { useSocketStore } from '../../../store/builder/store';
|
import { useSocketStore } from "../../../store/builder/store";
|
||||||
|
|
||||||
interface Project {
|
interface Project {
|
||||||
_id: string;
|
_id: string;
|
||||||
projectName: string;
|
projectName: string;
|
||||||
thumbnail: string;
|
thumbnail: string;
|
||||||
createdBy: string;
|
createdBy: string;
|
||||||
projectUuid?: string;
|
projectUuid?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WorkspaceProjects {
|
interface WorkspaceProjects {
|
||||||
[key: string]: Project[];
|
[key: string]: Project[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DashboardProjects: React.FC = () => {
|
const DashboardProjects: React.FC = () => {
|
||||||
const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>({});
|
const [workspaceProjects, setWorkspaceProjects] = useState<WorkspaceProjects>(
|
||||||
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
|
{}
|
||||||
const [activeFolder, setActiveFolder] = useState<string>("myProjects");
|
);
|
||||||
const { dashBoardSocket } = useSocketStore();
|
const [isSearchActive, setIsSearchActive] = useState<boolean>(false);
|
||||||
const { userId, organization } = getUserData();
|
const [activeFolder, setActiveFolder] = useState<string>("myProjects");
|
||||||
|
const { dashBoardSocket } = useSocketStore();
|
||||||
|
const { userId, organization } = getUserData();
|
||||||
|
|
||||||
const fetchAllProjects = async () => {
|
const fetchAllProjects = async () => {
|
||||||
try {
|
try {
|
||||||
const projects = await getAllProjects(userId, organization);
|
const projects = await getAllProjects(userId, organization);
|
||||||
|
|
||||||
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);
|
console.error("Error fetching projects:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleProjectsSearch = async (
|
const handleProjectsSearch = async (inputValue: string) => {
|
||||||
inputValue: string
|
if (!inputValue.trim()) {
|
||||||
) => {
|
setIsSearchActive(false);
|
||||||
if (!inputValue.trim()) {
|
return;
|
||||||
setIsSearchActive(false);
|
}
|
||||||
return;
|
if (!setWorkspaceProjects || !setIsSearchActive) return;
|
||||||
}
|
|
||||||
if (!setWorkspaceProjects || !setIsSearchActive) return;
|
|
||||||
|
|
||||||
const searchedProject = await searchProject(organization, userId, inputValue);
|
const searchedProject = await searchProject(
|
||||||
setIsSearchActive(true);
|
organization,
|
||||||
setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
|
userId,
|
||||||
};
|
inputValue
|
||||||
const handleDeleteProject = async (projectId: any) => {
|
|
||||||
try {
|
|
||||||
|
|
||||||
const Organization = organization
|
|
||||||
// const deletedProject = await deleteProject(
|
|
||||||
// projectId,
|
|
||||||
// userId,
|
|
||||||
// Organization
|
|
||||||
// );
|
|
||||||
const deleteProject = {
|
|
||||||
projectId,
|
|
||||||
organization: organization,
|
|
||||||
userId
|
|
||||||
}
|
|
||||||
if (dashBoardSocket) {
|
|
||||||
const handleResponse = (data: any) => {
|
|
||||||
console.log('Project add response:', data);
|
|
||||||
dashBoardSocket.off("v1-project:response:delete", handleResponse); // Clean up
|
|
||||||
};
|
|
||||||
|
|
||||||
dashBoardSocket.on("v1-project:response:delete", handleResponse);
|
|
||||||
|
|
||||||
dashBoardSocket.emit("v1:project:delete", deleteProject);
|
|
||||||
} else {
|
|
||||||
console.error("Socket is not connected.");
|
|
||||||
}
|
|
||||||
setWorkspaceProjects((prevDiscardedProjects: WorkspaceProjects) => {
|
|
||||||
if (!Array.isArray(prevDiscardedProjects?.Projects)) {
|
|
||||||
return prevDiscardedProjects;
|
|
||||||
}
|
|
||||||
const updatedProjectDatas = prevDiscardedProjects.Projects.filter(
|
|
||||||
(project) => project._id !== projectId
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
...prevDiscardedProjects,
|
|
||||||
Projects: updatedProjectDatas
|
|
||||||
};
|
|
||||||
});
|
|
||||||
setIsSearchActive(false)
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error deleting project:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const renderProjects = () => {
|
|
||||||
if (activeFolder !== "myProjects") return null;
|
|
||||||
|
|
||||||
const projectList = workspaceProjects[Object.keys(workspaceProjects)[0]];
|
|
||||||
|
|
||||||
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}
|
|
||||||
handleDeleteProject={handleDeleteProject}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isSearchActive) {
|
|
||||||
fetchAllProjects();
|
|
||||||
}
|
|
||||||
}, [isSearchActive]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="dashboard-home-container">
|
|
||||||
<DashboardNavBar
|
|
||||||
page="projects"
|
|
||||||
handleProjectsSearch={handleProjectsSearch}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="container">
|
|
||||||
<div className="header" style={{ display: "flex", gap: "7px" }}>
|
|
||||||
<div
|
|
||||||
style={{ color: activeFolder === "myProjects" ? "#c4abf1" : "black" }}
|
|
||||||
onClick={() => setActiveFolder("myProjects")}
|
|
||||||
>
|
|
||||||
My Projects
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{ color: activeFolder === "shared" ? "#c4abf1" : "black" }}
|
|
||||||
onClick={() => setActiveFolder("shared")}
|
|
||||||
>
|
|
||||||
Shared with me
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="cards-container">
|
|
||||||
{renderProjects()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
setIsSearchActive(true);
|
||||||
|
setWorkspaceProjects(searchedProject.message ? {} : searchedProject);
|
||||||
|
};
|
||||||
|
const handleDeleteProject = async (projectId: any) => {
|
||||||
|
try {
|
||||||
|
const Organization = organization;
|
||||||
|
// const deletedProject = await deleteProject(
|
||||||
|
// projectId,
|
||||||
|
// userId,
|
||||||
|
// Organization
|
||||||
|
// );
|
||||||
|
const deleteProject = {
|
||||||
|
projectId,
|
||||||
|
organization: organization,
|
||||||
|
userId,
|
||||||
|
};
|
||||||
|
if (dashBoardSocket) {
|
||||||
|
const handleResponse = (data: any) => {
|
||||||
|
console.log("Project add response:", data);
|
||||||
|
dashBoardSocket.off("v1-project:response:delete", handleResponse); // Clean up
|
||||||
|
};
|
||||||
|
|
||||||
|
dashBoardSocket.on("v1-project:response:delete", handleResponse);
|
||||||
|
|
||||||
|
dashBoardSocket.emit("v1:project:delete", deleteProject);
|
||||||
|
} else {
|
||||||
|
console.error("Socket is not connected.");
|
||||||
|
}
|
||||||
|
setWorkspaceProjects((prevDiscardedProjects: WorkspaceProjects) => {
|
||||||
|
if (!Array.isArray(prevDiscardedProjects?.Projects)) {
|
||||||
|
return prevDiscardedProjects;
|
||||||
|
}
|
||||||
|
const updatedProjectDatas = prevDiscardedProjects.Projects.filter(
|
||||||
|
(project) => project._id !== projectId
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...prevDiscardedProjects,
|
||||||
|
Projects: updatedProjectDatas,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
setIsSearchActive(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting project:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderProjects = () => {
|
||||||
|
if (activeFolder !== "myProjects") return null;
|
||||||
|
|
||||||
|
const projectList = workspaceProjects[Object.keys(workspaceProjects)[0]];
|
||||||
|
|
||||||
|
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}
|
||||||
|
handleDeleteProject={handleDeleteProject}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isSearchActive) {
|
||||||
|
fetchAllProjects();
|
||||||
|
}
|
||||||
|
}, [isSearchActive]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="dashboard-home-container">
|
||||||
|
<DashboardNavBar
|
||||||
|
page="projects"
|
||||||
|
handleProjectsSearch={handleProjectsSearch}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="container" style={{ height: "calc(100% - 87px)" }}>
|
||||||
|
<div className="header-wrapper" style={{ display: "flex", gap: "7px" }}>
|
||||||
|
<button
|
||||||
|
className={`header ${activeFolder === "myProjects" && "active"}`}
|
||||||
|
onClick={() => setActiveFolder("myProjects")}
|
||||||
|
>
|
||||||
|
My Projects
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`header ${activeFolder === "shared" && "active"}`}
|
||||||
|
onClick={() => setActiveFolder("shared")}
|
||||||
|
>
|
||||||
|
Shared with me
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="cards-container">{renderProjects()}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardProjects;
|
export default DashboardProjects;
|
||||||
|
|
|
@ -1,122 +1,120 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import { getTrash } from '../../../services/dashboard/getTrash';
|
import { getTrash } from "../../../services/dashboard/getTrash";
|
||||||
import DashboardCard from './DashboardCard';
|
import DashboardCard from "./DashboardCard";
|
||||||
import DashboardNavBar from './DashboardNavBar';
|
import DashboardNavBar from "./DashboardNavBar";
|
||||||
import { getUserData } from './functions/getUserData';
|
import { getUserData } from "./functions/getUserData";
|
||||||
import { trashSearchProject } from '../../../services/dashboard/trashSearchProject';
|
import { trashSearchProject } from "../../../services/dashboard/trashSearchProject";
|
||||||
import { restoreTrash } from '../../../services/dashboard/restoreTrash';
|
import { restoreTrash } from "../../../services/dashboard/restoreTrash";
|
||||||
|
|
||||||
interface Project {
|
interface Project {
|
||||||
_id: string;
|
_id: string;
|
||||||
projectName: string;
|
projectName: string;
|
||||||
thumbnail: string;
|
thumbnail: string;
|
||||||
createdBy: string;
|
createdBy: string;
|
||||||
projectUuid?: string;
|
projectUuid?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DiscardedProjects {
|
interface DiscardedProjects {
|
||||||
[key: string]: Project[];
|
[key: string]: Project[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DashboardTrash: React.FC = () => {
|
const DashboardTrash: React.FC = () => {
|
||||||
const [discardedProjects, setDiscardedProjects] = useState<DiscardedProjects>({});
|
const [discardedProjects, setDiscardedProjects] = useState<DiscardedProjects>(
|
||||||
console.log('discardedProjects: ', discardedProjects);
|
{}
|
||||||
const [isSearchActive, setIsSearchActive] = useState(false);
|
);
|
||||||
const { userId, organization } = getUserData();
|
console.log("discardedProjects: ", discardedProjects);
|
||||||
|
const [isSearchActive, setIsSearchActive] = useState(false);
|
||||||
|
const { userId, organization } = getUserData();
|
||||||
|
|
||||||
const fetchTrashProjects = async () => {
|
const fetchTrashProjects = async () => {
|
||||||
try {
|
try {
|
||||||
const projects = await getTrash(organization);
|
const projects = await getTrash(organization);
|
||||||
console.log('organization: ', organization);
|
console.log("organization: ", organization);
|
||||||
console.log('trashedprojects: ', projects);
|
console.log("trashedprojects: ", projects);
|
||||||
|
|
||||||
if (JSON.stringify(projects) !== JSON.stringify(discardedProjects)) {
|
if (JSON.stringify(projects) !== JSON.stringify(discardedProjects)) {
|
||||||
setDiscardedProjects(projects);
|
setDiscardedProjects(projects);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching trash projects:', error);
|
console.error("Error fetching trash projects:", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleTrashSearch = async (
|
const handleTrashSearch = async (inputValue: string) => {
|
||||||
inputValue: string
|
if (!inputValue.trim()) {
|
||||||
) => {
|
setIsSearchActive(false);
|
||||||
if (!inputValue.trim()) {
|
return;
|
||||||
setIsSearchActive(false);
|
}
|
||||||
return;
|
if (!setDiscardedProjects || !setIsSearchActive) return;
|
||||||
}
|
|
||||||
if (!setDiscardedProjects || !setIsSearchActive) return;
|
|
||||||
|
|
||||||
const filterTrashedProcess = await trashSearchProject(organization, userId, inputValue);
|
const filterTrashedProcess = await trashSearchProject(
|
||||||
setIsSearchActive(true);
|
organization,
|
||||||
setDiscardedProjects(filterTrashedProcess.message ? {} : filterTrashedProcess);
|
userId,
|
||||||
};
|
inputValue
|
||||||
const handleRestoreProject = async (projectId: any) => {
|
|
||||||
try {
|
|
||||||
const Organization = organization;
|
|
||||||
const restoreProject = await restoreTrash(
|
|
||||||
Organization,
|
|
||||||
projectId
|
|
||||||
);
|
|
||||||
|
|
||||||
setDiscardedProjects((prevDiscardedProjects: DiscardedProjects) => {
|
|
||||||
// Check if TrashDatas exists and is an array
|
|
||||||
if (!Array.isArray(prevDiscardedProjects?.TrashDatas)) {
|
|
||||||
console.error('TrashDatas is not an array', prevDiscardedProjects);
|
|
||||||
return prevDiscardedProjects;
|
|
||||||
}
|
|
||||||
const updatedTrashDatas = prevDiscardedProjects.TrashDatas.filter(
|
|
||||||
(project) => project._id !== projectId
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
...prevDiscardedProjects,
|
|
||||||
TrashDatas: updatedTrashDatas
|
|
||||||
};
|
|
||||||
});
|
|
||||||
setIsSearchActive(false)
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error deleting project:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const renderTrashProjects = () => {
|
|
||||||
const projectList = discardedProjects[Object.keys(discardedProjects)[0]];
|
|
||||||
|
|
||||||
if (!projectList?.length) {
|
|
||||||
return <div className="empty-state">No deleted projects found</div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectList.map((project) => (
|
|
||||||
<DashboardCard
|
|
||||||
key={project._id}
|
|
||||||
projectName={project.projectName}
|
|
||||||
thumbnail={project.thumbnail}
|
|
||||||
projectId={project._id}
|
|
||||||
handleRestoreProject={handleRestoreProject}
|
|
||||||
/>
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
console.log('isSearchActive:trash ', isSearchActive);
|
|
||||||
if (!isSearchActive) {
|
|
||||||
fetchTrashProjects();
|
|
||||||
}
|
|
||||||
}, [isSearchActive]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="dashboard-home-container">
|
|
||||||
<DashboardNavBar
|
|
||||||
page="trash"
|
|
||||||
handleTrashSearch={handleTrashSearch}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="container">
|
|
||||||
<div className="header" style={{ display: 'flex', gap: '7px' }}></div>
|
|
||||||
<div className="cards-container">
|
|
||||||
{renderTrashProjects()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
setIsSearchActive(true);
|
||||||
|
setDiscardedProjects(
|
||||||
|
filterTrashedProcess.message ? {} : filterTrashedProcess
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const handleRestoreProject = async (projectId: any) => {
|
||||||
|
try {
|
||||||
|
const Organization = organization;
|
||||||
|
const restoreProject = await restoreTrash(Organization, projectId);
|
||||||
|
|
||||||
|
setDiscardedProjects((prevDiscardedProjects: DiscardedProjects) => {
|
||||||
|
// Check if TrashDatas exists and is an array
|
||||||
|
if (!Array.isArray(prevDiscardedProjects?.TrashDatas)) {
|
||||||
|
console.error("TrashDatas is not an array", prevDiscardedProjects);
|
||||||
|
return prevDiscardedProjects;
|
||||||
|
}
|
||||||
|
const updatedTrashDatas = prevDiscardedProjects.TrashDatas.filter(
|
||||||
|
(project) => project._id !== projectId
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...prevDiscardedProjects,
|
||||||
|
TrashDatas: updatedTrashDatas,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
setIsSearchActive(false);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error deleting project:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const renderTrashProjects = () => {
|
||||||
|
const projectList = discardedProjects[Object.keys(discardedProjects)[0]];
|
||||||
|
|
||||||
|
if (!projectList?.length) {
|
||||||
|
return <div className="empty-state">No deleted projects found</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectList.map((project) => (
|
||||||
|
<DashboardCard
|
||||||
|
key={project._id}
|
||||||
|
projectName={project.projectName}
|
||||||
|
thumbnail={project.thumbnail}
|
||||||
|
projectId={project._id}
|
||||||
|
handleRestoreProject={handleRestoreProject}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("isSearchActive:trash ", isSearchActive);
|
||||||
|
if (!isSearchActive) {
|
||||||
|
fetchTrashProjects();
|
||||||
|
}
|
||||||
|
}, [isSearchActive]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="dashboard-home-container">
|
||||||
|
<DashboardNavBar page="trash" handleTrashSearch={handleTrashSearch} />
|
||||||
|
|
||||||
|
<div className="container" style={{ height: "calc(100% - 87px)" }}>
|
||||||
|
<div className="header" style={{ display: "flex", gap: "7px" }}></div>
|
||||||
|
<div className="cards-container">{renderTrashProjects()}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DashboardTrash;
|
export default DashboardTrash;
|
||||||
|
|
|
@ -49,7 +49,7 @@ const DashboardTutorial = () => {
|
||||||
page="tutorial"
|
page="tutorial"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="container">
|
<div className="container" style={{ height: "calc(100% - 87px)" }}>
|
||||||
<div className="header" style={{ display: 'flex', gap: '7px' }}></div>
|
<div className="header" style={{ display: 'flex', gap: '7px' }}></div>
|
||||||
<div className="cards-container">
|
<div className="cards-container">
|
||||||
{renderTrashProjects()}
|
{renderTrashProjects()}
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import SidePannel from '../components/layout/Dashboard/SidePannel';
|
import SidePannel from "../components/layout/Dashboard/SidePannel";
|
||||||
import DashboardHome from '../components/layout/Dashboard/DashboardHome';
|
import DashboardHome from "../components/layout/Dashboard/DashboardHome";
|
||||||
import DashboardProjects from '../components/layout/Dashboard/DashboardProjects';
|
import DashboardProjects from "../components/layout/Dashboard/DashboardProjects";
|
||||||
import DashboardTrash from '../components/layout/Dashboard/DashboardTrash';
|
import DashboardTrash from "../components/layout/Dashboard/DashboardTrash";
|
||||||
import { useOrganization, useSocketStore, useUserName, useZones } from '../store/builder/store';
|
import {
|
||||||
import { getUserData } from '../components/layout/Dashboard/functions/getUserData';
|
useOrganization,
|
||||||
import DashboardTutorial from '../components/layout/Dashboard/DashboardTutorial';
|
useSocketStore,
|
||||||
|
useUserName,
|
||||||
|
} from "../store/builder/store";
|
||||||
|
import { getUserData } from "../components/layout/Dashboard/functions/getUserData";
|
||||||
|
import DashboardTutorial from "../components/layout/Dashboard/DashboardTutorial";
|
||||||
|
|
||||||
const Dashboard: React.FC = () => {
|
const Dashboard: React.FC = () => {
|
||||||
const [activeTab, setActiveTab] = useState<string>('Home');
|
const [activeTab, setActiveTab] = useState<string>("Home");
|
||||||
const { setUserName } = useUserName();
|
const { setUserName } = useUserName();
|
||||||
const { setOrganization } = useOrganization();
|
const { setOrganization } = useOrganization();
|
||||||
const { userId, organization, email, userName } = getUserData();
|
const { userId, organization, email, userName } = getUserData();
|
||||||
|
@ -21,16 +24,16 @@ const Dashboard: React.FC = () => {
|
||||||
setUserName(userName);
|
setUserName(userName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [])
|
}, []);
|
||||||
return (
|
return (
|
||||||
<div className="dashboard-main">
|
<div className="dashboard-main">
|
||||||
<SidePannel setActiveTab={setActiveTab} activeTab={activeTab} />
|
<SidePannel setActiveTab={setActiveTab} activeTab={activeTab} />
|
||||||
{activeTab == 'Home' && <DashboardHome />}
|
{activeTab == "Home" && <DashboardHome />}
|
||||||
{activeTab == 'Projects' && <DashboardProjects />}
|
{activeTab == "Projects" && <DashboardProjects />}
|
||||||
{activeTab == 'Trash' && <DashboardTrash />}
|
{activeTab == "Trash" && <DashboardTrash />}
|
||||||
{activeTab == 'Tutorials' && <DashboardTutorial />}
|
{activeTab == "Tutorials" && <DashboardTutorial />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Dashboard;
|
export default Dashboard;
|
||||||
|
|
|
@ -192,4 +192,4 @@ $border-radius-large: 12px;
|
||||||
$border-radius-circle: 50%;
|
$border-radius-circle: 50%;
|
||||||
$border-radius-xlarge: 16px;
|
$border-radius-xlarge: 16px;
|
||||||
$border-radius-extra-large: 20px;
|
$border-radius-extra-large: 20px;
|
||||||
$border-radius-xxx: 30px;
|
$border-radius-xxx: 30px;
|
|
@ -5,19 +5,28 @@
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
padding: 27px 17px;
|
||||||
|
|
||||||
.side-pannel-container {
|
.side-pannel-container {
|
||||||
padding: 32px;
|
padding: 32px;
|
||||||
min-width: 240px;
|
min-width: 280px;
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
border-right: 1px solid var(--border-color);
|
// border-right: 1px solid var(--border-color);
|
||||||
|
background: var(--background-color);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
border-radius: 30px;
|
||||||
|
box-shadow: var(--box-shadow-medium);
|
||||||
|
|
||||||
.side-pannel-header {
|
.side-pannel-header {
|
||||||
@include flex-space-between;
|
@include flex-space-between;
|
||||||
|
|
||||||
.user-container {
|
.user-container {
|
||||||
@include flex-center;
|
@include flex-center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
|
||||||
.user-profile {
|
.user-profile {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
width: 32px;
|
width: 32px;
|
||||||
|
@ -28,10 +37,12 @@
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
border-radius: #{$border-radius-circle};
|
border-radius: #{$border-radius-circle};
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-name {
|
.user-name {
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.notifications-container {
|
.notifications-container {
|
||||||
@include flex-center;
|
@include flex-center;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
@ -39,82 +50,117 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.new-project-button {
|
.new-project-button {
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
color: var(--accent-color);
|
color: var(--text-color);
|
||||||
background: var(--background-color-secondary);
|
background: var(--background-color-secondary);
|
||||||
border-radius: #{$border-radius-large};
|
border-radius: #{$border-radius-xxx};
|
||||||
}
|
}
|
||||||
|
|
||||||
.side-bar-content-container {
|
.side-bar-content-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.side-bar-options-container {
|
.side-bar-options-container {
|
||||||
.option-list {
|
.option-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 6px 10px;
|
padding: 8px 10px;
|
||||||
margin: 4px 0;
|
margin: 4px 0;
|
||||||
border-radius: #{$border-radius-medium};
|
border-radius: #{$border-radius-extra-large};
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--background-color-secondary);
|
background: var(--background-color-secondary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
color: var(--accent-color);
|
color: var(--text-button-color);
|
||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
background: var(--highlight-accent-color);
|
background: var(--background-color-button);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--highlight-accent-color);
|
background: var(--background-color-button);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-home-container {
|
.dashboard-home-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding-left: 18px;
|
||||||
|
|
||||||
.dashboard-navbar-container {
|
.dashboard-navbar-container {
|
||||||
margin-top: 28px;
|
margin-top: 28px;
|
||||||
padding: 8px 34px 8px 12px;
|
margin-bottom: 22px;
|
||||||
@include flex-center;
|
@include flex-center;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
font-size: var(--font-size-large);
|
font-size: var(--font-size-large);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.market-place-button {
|
.market-place-button {
|
||||||
@include flex-center;
|
@include flex-center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 8px 14px;
|
padding: 8px 14px;
|
||||||
background: var(--accent-gradient-color);
|
background: var(--background-color-button);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-radius: #{$border-radius-large};
|
border-radius: #{$border-radius-extra-large};
|
||||||
color: var(--primary-color);
|
|
||||||
|
color: var(--text-button-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-wrapper {
|
.search-wrapper {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
margin: 22px 0;
|
margin: 22px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 12px;
|
height: calc(100% - 357px);
|
||||||
.header {
|
|
||||||
|
|
||||||
|
.header-wrapper {
|
||||||
font-size: var(--font-size-large);
|
font-size: var(--font-size-large);
|
||||||
|
|
||||||
|
.header {
|
||||||
|
color: var(--input-text-color);
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-radius: #{$border-radius-extra-large};
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
|
||||||
|
background: var(--background-color-button);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cards-container {
|
.cards-container {
|
||||||
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px;
|
padding-top: 18px;
|
||||||
gap: 18px;
|
gap: 18px;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-card-container {
|
.dashboard-card-container {
|
||||||
|
@ -123,11 +169,23 @@
|
||||||
min-width: 260px;
|
min-width: 260px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: #{$border-radius-large};
|
border-radius: #{$border-radius-extra-large};
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: visible;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.dashboard-card-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.preview-container {
|
.preview-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -135,27 +193,38 @@
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
border-radius: #{$border-radius-extra-large};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-details-container {
|
.project-details-container {
|
||||||
@include flex-space-between;
|
@include flex-space-between;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px 16px;
|
padding: 13px 16px;
|
||||||
background: var(--primary-color);
|
background: var(--background-color);
|
||||||
border-radius: #{$border-radius-large};
|
// backdrop-filter: blur(18px);
|
||||||
|
|
||||||
|
border-radius: #{$border-radius-xlarge};
|
||||||
|
transform: translateY(100%);
|
||||||
|
transition: transform 0.25s linear;
|
||||||
|
|
||||||
.project-details {
|
.project-details {
|
||||||
.project-name {
|
.project-name {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-data {
|
.project-data {
|
||||||
color: var(--accent-color);
|
color: var(--input-text-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.users-list-container {
|
.users-list-container {
|
||||||
@include flex-center;
|
@include flex-center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
|
position: relative; // Needed for absolute positioning of kebab-options-wrapper
|
||||||
|
|
||||||
.user-profile {
|
.user-profile {
|
||||||
height: 26px;
|
height: 26px;
|
||||||
width: 26px;
|
width: 26px;
|
||||||
|
@ -165,8 +234,65 @@
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
border-radius: #{$border-radius-circle};
|
border-radius: #{$border-radius-circle};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kebab {
|
||||||
|
padding: 10px;
|
||||||
|
@include flex-center;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.kebab-options-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 40px;
|
||||||
|
right: 40px;
|
||||||
|
background: var(--background-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
transform: translate(100%, 100%);
|
||||||
|
overflow: hidden;
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.option {
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: left;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-color);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
text-transform: capitalize;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--background-color-secondary);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
|
||||||
|
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
.kebab-options-wrapper {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-details-container {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.market-place-banner-container {
|
.market-place-banner-container {
|
||||||
|
@ -174,13 +300,14 @@
|
||||||
height: 230px;
|
height: 230px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 24px;
|
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
border-radius: #{$border-radius-xxx};
|
border-radius: #{$border-radius-xxx};
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-text {
|
.hero-text {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 52px;
|
left: 52px;
|
||||||
|
@ -191,6 +318,7 @@
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.context {
|
.context {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
|
@ -201,11 +329,13 @@
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font-family: #{$font-roboto};
|
font-family: #{$font-roboto};
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow-context {
|
.arrow-context {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 27px;
|
bottom: 27px;
|
||||||
right: 300px;
|
right: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.explore-button {
|
.explore-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 95px;
|
top: 95px;
|
||||||
|
@ -218,4 +348,4 @@
|
||||||
font-family: #{$font-roboto};
|
font-family: #{$font-roboto};
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue