fix: new auth layer (#740)

* chore: made workspace authorization wrapper component

* chore: added todos

* chore: workspace pages new layout

* chore: project authorization wrapper

* chore: new project authorization wrapper

* fix: authorization for member roles

* chore: new auth screens ui

---------

Co-authored-by: Dakshesh Jain <dakshesh.jain14@gmail.com>
This commit is contained in:
Aaryan Khandelwal 2023-04-08 13:46:46 +05:30 committed by GitHub
parent beedd57ee1
commit 3947a86fa7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 997 additions and 1284 deletions

View file

@ -0,0 +1,3 @@
export * from "./project";
export * from "./workspace";
export * from "./not-authorized-view";

View file

@ -0,0 +1,67 @@
import React from "react";
// next
import Link from "next/link";
import Image from "next/image";
import { useRouter } from "next/router";
// layouts
import DefaultLayout from "layouts/default-layout";
// hooks
import useUser from "hooks/use-user";
// images
import ProjectNotAuthorizedImg from "public/auth/project-not-authorized.svg";
import WorkspaceNotAuthorizedImg from "public/auth/workspace-not-authorized.svg";
type Props = {
actionButton?: React.ReactNode;
type: "project" | "workspace";
};
export const NotAuthorizedView: React.FC<Props> = ({ actionButton, type }) => {
const { user } = useUser();
const { asPath: currentPath } = useRouter();
return (
<DefaultLayout
meta={{
title: "Plane - Not Authorized",
description: "You are not authorized to view this page",
}}
>
<div className="flex h-full w-full flex-col items-center justify-center gap-y-5 text-center">
<div className="h-44 w-72">
<Image
src={type === "project" ? ProjectNotAuthorizedImg : WorkspaceNotAuthorizedImg}
height="176"
width="288"
alt="ProjectSettingImg"
/>
</div>
<h1 className="text-xl font-medium text-gray-900">
Oops! You are not authorized to view this page
</h1>
<div className="w-full text-base text-gray-500 max-w-md ">
{user ? (
<p className="">
You have signed in as {user.email}. <br />
<Link href={`/signin?next=${currentPath}`}>
<a className="text-gray-900 font-medium">Sign in</a>
</Link>{" "}
with different account that has access to this page.
</p>
) : (
<p className="">
You need to{" "}
<Link href={`/signin?next=${currentPath}`}>
<a className="text-gray-900 font-medium">Sign in</a>
</Link>{" "}
with an account that has access to this page.
</p>
)}
</div>
{actionButton}
</div>
</DefaultLayout>
);
};

View file

@ -0,0 +1 @@
export * from "./join-project";

View file

@ -0,0 +1,64 @@
import { useState } from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import { mutate } from "swr";
// ui
import { PrimaryButton } from "components/ui";
// icon
import { AssignmentClipboardIcon } from "components/icons";
// img
import JoinProjectImg from "public/auth/project-not-authorized.svg";
import projectService from "services/project.service";
// fetch-keys
import { PROJECT_MEMBERS } from "constants/fetch-keys";
export const JoinProject: React.FC = () => {
const [isJoiningProject, setIsJoiningProject] = useState(false);
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
const handleJoin = () => {
setIsJoiningProject(true);
projectService
.joinProject(workspaceSlug as string, {
project_ids: [projectId as string],
})
.then(() => {
setIsJoiningProject(false);
mutate(PROJECT_MEMBERS(projectId as string));
})
.catch((err) => {
console.error(err);
});
};
return (
<div className="flex h-full w-full flex-col items-center justify-center gap-y-5 text-center">
<div className="h-44 w-72">
<Image src={JoinProjectImg} height="176" width="288" alt="JoinProject" />
</div>
<h1 className="text-xl font-medium text-gray-900">You are not a member of this project</h1>
<div className="w-full max-w-md text-base text-gray-500 ">
<p className="mx-auto w-full text-sm md:w-3/4">
You are not a member of this project, but you can join this project by clicking the button
below.
</p>
</div>
<div>
<PrimaryButton
className="flex items-center gap-1"
loading={isJoiningProject}
onClick={handleJoin}
>
<AssignmentClipboardIcon height={16} width={16} color="white" />
{isJoiningProject ? "Joining..." : "Click to join"}
</PrimaryButton>
</div>
</div>
);
};

View file

@ -0,0 +1 @@
export * from "./not-a-member";

View file

@ -0,0 +1,46 @@
import Link from "next/link";
import { useRouter } from "next/router";
// layouts
import DefaultLayout from "layouts/default-layout";
// ui
import { PrimaryButton, SecondaryButton } from "components/ui";
export const NotAWorkspaceMember = () => {
const router = useRouter();
return (
<DefaultLayout
meta={{
title: "Plane - Unauthorized User",
description: "Unauthorized user",
}}
>
<div className="grid h-full place-items-center p-4">
<div className="space-y-8 text-center">
<div className="space-y-2">
<h3 className="text-lg font-semibold">Not Authorized!</h3>
<p className="text-sm text-gray-500 w-1/2 mx-auto">
You{"'"}re not a member of this workspace. Please contact the workspace admin to get
an invitation or check your pending invitations.
</p>
</div>
<div className="flex items-center gap-2 justify-center">
<Link href="/invitations">
<a>
<SecondaryButton onClick={() => router.back()}>
Check pending invites
</SecondaryButton>
</a>
</Link>
<Link href="/create-workspace">
<a>
<PrimaryButton>Create new workspace</PrimaryButton>
</a>
</Link>
</div>
</div>
</div>
</DefaultLayout>
);
};