From 6afcf1f0e355f45a77de8d422af763bb2692cbc6 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Wed, 1 Mar 2023 14:11:27 +0530 Subject: [PATCH] style: projects list page --- .../components/project/join-project-modal.tsx | 12 +- .../project/single-project-card.tsx | 224 +++++++++++++----- apps/app/components/ui/tooltip.tsx | 16 +- apps/app/hooks/use-project-members.tsx | 18 +- apps/app/hooks/use-projects.tsx | 6 +- apps/app/next.config.js | 1 + .../pages/[workspaceSlug]/projects/index.tsx | 1 + apps/app/services/project.service.ts | 25 +- apps/app/types/projects.d.ts | 1 + 9 files changed, 214 insertions(+), 90 deletions(-) diff --git a/apps/app/components/project/join-project-modal.tsx b/apps/app/components/project/join-project-modal.tsx index df05f1309..60530e8a7 100644 --- a/apps/app/components/project/join-project-modal.tsx +++ b/apps/app/components/project/join-project-modal.tsx @@ -13,9 +13,7 @@ type TJoinProjectModalProps = { onJoin: () => Promise; }; -export const JoinProjectModal: React.FC = (props) => { - const { onClose, onJoin, data } = props; - +export const JoinProjectModal: React.FC = ({ onClose, onJoin, data }) => { const [isJoiningLoading, setIsJoiningLoading] = useState(false); const handleJoin = () => { @@ -36,7 +34,7 @@ export const JoinProjectModal: React.FC = (props) => { return ( - + = (props) => {
-
+
= (props) => {

-
- - ) : ( - Member - )} - - - + -
-
-
{project.name}
-
-

{project.description}

-
+ + +
+ + +
+

{project.name}

+ {project.icon && ( + + {String.fromCodePoint(parseInt(project.icon))} + + )} +
+

{truncateText(project.description ?? "", 100)}

+
+ +
+
{renderShortNumericDateFormat(project.created_at)}
- {isMember ? ( -
- {canEdit && ( - - - - - + + {hasJoined ? ( +
+ {(isOwner || isMember) && ( + + + + + + )} + + {isOwner && ( + setDeleteProject(project.id)}> + Delete project + )} - {canDelete && ( - - setDeleteProject(project.id)}> - Delete project - - - Copy project link - - + {project.is_favourite ? ( + + Remove from favourites + + ) : ( + + Add to favourites + )} -
- ) : null} -
+ + Copy project link + + +
+ ) : null}
- - +
+
) : ( diff --git a/apps/app/components/ui/tooltip.tsx b/apps/app/components/ui/tooltip.tsx index 1b7f40fea..f6a32a563 100644 --- a/apps/app/components/ui/tooltip.tsx +++ b/apps/app/components/ui/tooltip.tsx @@ -24,6 +24,7 @@ type Props = { children: JSX.Element; disabled?: boolean; className?: string; + theme?: "light" | "dark"; }; export const Tooltip: React.FC = ({ @@ -33,21 +34,18 @@ export const Tooltip: React.FC = ({ children, disabled = false, className = "", + theme = "light", }) => ( - {tooltipHeading ? ( - <> -
{tooltipHeading}
-

{tooltipContent}

- - ) : ( -

{tooltipContent}

- )} + {tooltipHeading &&
{tooltipHeading}
} +

{tooltipContent}

} position={position} diff --git a/apps/app/hooks/use-project-members.tsx b/apps/app/hooks/use-project-members.tsx index 5f3519610..9764ade75 100644 --- a/apps/app/hooks/use-project-members.tsx +++ b/apps/app/hooks/use-project-members.tsx @@ -13,20 +13,24 @@ const useProjectMembers = (workspaceSlug: string, projectId: string) => { projectService.projectMembers(workspaceSlug, projectId) ); - const isMember = members?.some((item: any) => item.member.id === (user as any)?.id); + const hasJoined = members?.some((item: any) => item.member.id === (user as any)?.id); - const canEdit = members?.some( - (item) => (item.member.id === (user as any)?.id && item.role === 20) || item.role === 15 + const isOwner = members?.some((item) => item.member.id === (user as any)?.id && item.role === 20); + const isMember = members?.some( + (item) => item.member.id === (user as any)?.id && item.role === 15 ); - const canDelete = members?.some( - (item) => item.member.id === (user as any)?.id && item.role === 20 + const isViewer = members?.some( + (item) => item.member.id === (user as any)?.id && item.role === 10 ); + const isGuest = members?.some((item) => item.member.id === (user as any)?.id && item.role === 5); return { members, + hasJoined, + isOwner, isMember, - canEdit, - canDelete, + isViewer, + isGuest, }; }; diff --git a/apps/app/hooks/use-projects.tsx b/apps/app/hooks/use-projects.tsx index f9583eea8..6b4a8b413 100644 --- a/apps/app/hooks/use-projects.tsx +++ b/apps/app/hooks/use-projects.tsx @@ -1,10 +1,8 @@ import useSWR from "swr"; import { useRouter } from "next/router"; -// types -import { IProject } from "types"; // services import projectService from "services/project.service"; -// constants +// fetch-keys import { PROJECTS_LIST } from "constants/fetch-keys"; const useProjects = () => { @@ -12,7 +10,7 @@ const useProjects = () => { const router = useRouter(); const { workspaceSlug } = router.query; // api fetching - const { data: projects, mutate: mutateProjects } = useSWR( + const { data: projects, mutate: mutateProjects } = useSWR( workspaceSlug ? PROJECTS_LIST(workspaceSlug as string) : null, workspaceSlug ? () => projectService.getProjects(workspaceSlug as string) : null ); diff --git a/apps/app/next.config.js b/apps/app/next.config.js index ed883e597..2b3583fa4 100644 --- a/apps/app/next.config.js +++ b/apps/app/next.config.js @@ -9,6 +9,7 @@ const nextConfig = { "vinci-web.s3.amazonaws.com", "planefs-staging.s3.ap-south-1.amazonaws.com", "planefs.s3.amazonaws.com", + "images.unsplash.com", ], }, output: "standalone", diff --git a/apps/app/pages/[workspaceSlug]/projects/index.tsx b/apps/app/pages/[workspaceSlug]/projects/index.tsx index adcce39a2..4569552ac 100644 --- a/apps/app/pages/[workspaceSlug]/projects/index.tsx +++ b/apps/app/pages/[workspaceSlug]/projects/index.tsx @@ -57,6 +57,7 @@ const ProjectsPage: NextPage = () => { onJoin={async () => { const project = projects?.find((item) => item.id === selectedProjectToJoin); if (!project) return; + await projectService .joinProject(workspaceSlug as string, { project_ids: [project.id], diff --git a/apps/app/services/project.service.ts b/apps/app/services/project.service.ts index 1172f8823..702298880 100644 --- a/apps/app/services/project.service.ts +++ b/apps/app/services/project.service.ts @@ -222,7 +222,7 @@ class ProjectServices extends APIService { } async syncGiuthubRepository( - slug: string, + workspaceSlug: string, projectId: string, workspaceIntegrationId: string, data: { @@ -233,7 +233,7 @@ class ProjectServices extends APIService { } ): Promise { return this.post( - `/api/workspaces/${slug}/projects/${projectId}/workspace-integrations/${workspaceIntegrationId}/github-repository-sync/`, + `/api/workspaces/${workspaceSlug}/projects/${projectId}/workspace-integrations/${workspaceIntegrationId}/github-repository-sync/`, data ) .then((response) => response?.data) @@ -255,6 +255,27 @@ class ProjectServices extends APIService { throw error?.response?.data; }); } + + async addProjectToFavourites( + workspaceSlug: string, + data: { + project: string; + } + ): Promise { + return this.post(`/api/workspaces/${workspaceSlug}/user-favourite-projects/`, data) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } + + async removeProjectFromFavourites(workspaceSlug: string, projectId: string): Promise { + return this.delete(`/api/workspaces/${workspaceSlug}/user-favourite-projects/${projectId}/`) + .then((response) => response?.data) + .catch((error) => { + throw error?.response?.data; + }); + } } export default new ProjectServices(); diff --git a/apps/app/types/projects.d.ts b/apps/app/types/projects.d.ts index 7364682a8..af5012f2c 100644 --- a/apps/app/types/projects.d.ts +++ b/apps/app/types/projects.d.ts @@ -10,6 +10,7 @@ export interface IProject { icon: string; id: string; identifier: string; + is_favourite: boolean; module_view: boolean; name: string; network: number;