style: auth screens (#478)

* style: sign in page

* style: github and google sign

* style: sign with code and password

* style: not a member and not authorized for project setting

* style: join project icon

* chore: comment removed
This commit is contained in:
Anmol Singh Bhatia 2023-03-21 12:46:12 +05:30 committed by GitHub
parent 68150a9d2b
commit b96d40f106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 178 additions and 85 deletions

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
// ui
import { CheckCircleIcon } from "@heroicons/react/20/solid";
import { Input, SecondaryButton } from "components/ui";
import { Input, PrimaryButton, SecondaryButton } from "components/ui";
// services
import authenticationService from "services/authentication.service";
import useToast from "hooks/use-toast";
@ -90,7 +90,7 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
return (
<>
<form className="mt-5 space-y-5">
<form className="space-y-5 py-5 px-5">
{(codeSent || codeResent) && (
<div className="rounded-md bg-green-50 p-4">
<div className="flex">
@ -121,7 +121,7 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
) || "Email ID is not valid",
}}
error={errors.email}
placeholder="Enter your Email ID"
placeholder="Enter you email Id"
/>
</div>
@ -169,18 +169,20 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
)}
<div>
{codeSent ? (
<SecondaryButton
<PrimaryButton
type="submit"
className="w-full text-center"
size="md"
onClick={handleSubmit(handleSignin)}
loading={isSubmitting || (!isValid && isDirty)}
>
{isSubmitting ? "Signing in..." : "Sign in"}
</SecondaryButton>
</PrimaryButton>
) : (
<SecondaryButton
<PrimaryButton
type="submit"
className="w-full text-center"
size="md"
onClick={() => {
handleSubmit(onSubmit)().then(() => {
setResendCodeTimer(30);
@ -189,7 +191,7 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
loading={isSubmitting || (!isValid && isDirty)}
>
{isSubmitting ? "Sending code..." : "Send code"}
</SecondaryButton>
</PrimaryButton>
)}
</div>
</form>

View File

@ -60,7 +60,7 @@ export const EmailPasswordForm = ({ onSuccess }: any) => {
};
return (
<>
<form className="mt-5" onSubmit={handleSubmit(onSubmit)}>
<form className="mt-5 py-5 px-5" onSubmit={handleSubmit(onSubmit)}>
<div>
<Input
id="email"

View File

@ -19,28 +19,6 @@ export const EmailSignInForm: FC<EmailSignInFormProps> = (props) => {
) : (
<EmailPasswordForm onSuccess={handleSuccess} />
)}
<div className="mt-6">
<div className="relative">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center text-sm">
<span className="bg-white px-2 text-gray-500">or</span>
</div>
</div>
{/* <div className="mt-6 flex w-full flex-col items-stretch gap-y-2">
<button
type="button"
className="flex w-full items-center rounded border border-gray-300 px-3 py-2 text-sm duration-300 hover:bg-gray-100"
onClick={() => setUseCode((prev) => !prev)}
>
<KeyIcon className="h-[25px] w-[25px]" />
<span className="w-full text-center font-medium">
{useCode ? "Continue with Password" : "Continue with Code"}
</span>
</button>
</div> */}
</div>
</>
);
};

View File

@ -3,7 +3,7 @@ import Link from "next/link";
import Image from "next/image";
import { useRouter } from "next/router";
// images
import githubImage from "/public/logos/github.png";
import githubImage from "/public/logos/github-black.png";
const { NEXT_PUBLIC_GITHUB_ID } = process.env;
@ -33,19 +33,15 @@ export const GithubLoginButton: FC<GithubLoginButtonProps> = (props) => {
}, []);
return (
<div className="px-1 w-full">
<Link
href={`https://github.com/login/oauth/authorize?client_id=${NEXT_PUBLIC_GITHUB_ID}&redirect_uri=${loginCallBackURL}&scope=read:user,user:email`}
>
<button className="flex w-full items-center rounded bg-black px-3 py-2 text-sm text-white opacity-90 duration-300 hover:opacity-100">
<Image
src={githubImage}
height={25}
width={25}
className="flex-shrink-0"
alt="GitHub Logo"
/>
<span className="w-full text-center font-medium">Continue with GitHub</span>
<button className="flex w-full items-center justify-center gap-3 rounded-md border border-gray-200 p-2 text-sm font-medium text-gray-600 duration-300 hover:bg-gray-50">
<Image src={githubImage} height={22} width={22} color="#000" alt="GitHub Logo" />
<span>Sign In with Github</span>
</button>
</Link>
</div>
);
};

View File

@ -27,7 +27,7 @@ export const GoogleLoginButton: FC<IGoogleLoginButton> = (props) => {
theme: "outline",
size: "large",
logo_alignment: "center",
width: document.getElementById("googleSignInButton")?.offsetWidth,
width: "410",
text: "continue_with",
} as GsiButtonConfiguration // customization attributes
);
@ -47,7 +47,7 @@ export const GoogleLoginButton: FC<IGoogleLoginButton> = (props) => {
return (
<>
<Script src="https://accounts.google.com/gsi/client" async defer onLoad={loadScript} />
<div className="w-full" id="googleSignInButton" ref={googleSignInButton} />
<div className="h-12" id="googleSignInButton" ref={googleSignInButton} />
</>
);
};

View File

@ -1,13 +1,14 @@
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";
// icons
import { LockIcon } from "components/icons";
// img
import ProjectSettingImg from "public/project-setting.svg";
type TNotAuthorizedViewProps = {
actionButton?: React.ReactNode;
@ -27,25 +28,27 @@ export const NotAuthorizedView: React.FC<TNotAuthorizedViewProps> = (props) => {
}}
>
<div className="flex h-full w-full flex-col items-center justify-center gap-y-5 text-center">
<LockIcon className="h-16 w-16 text-gray-400" />
<div className="h-44 w-72">
<Image src={ProjectSettingImg} 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 md:w-1/3">
<div className="w-full text-base text-gray-500 max-w-md ">
{user ? (
<p className="text-base font-light">
You have signed in as <span className="font-medium">{user.email}</span>.{" "}
<p className="">
You have signed in as {user.email}.{" "}
<Link href={`/signin?next=${currentPath}`}>
<a className="font-medium">Sign in</a>
<a className="text-gray-900 font-medium">Sign in</a>
</Link>{" "}
with different account that has access to this page.
</p>
) : (
<p className="text-base font-light">
<p className="">
You need to{" "}
<Link href={`/signin?next=${currentPath}`}>
<a className="font-medium">Sign in</a>
<a className="text-gray-900 font-medium">Sign in</a>
</Link>{" "}
with an account that has access to this page.
</p>

View File

@ -1,7 +1,13 @@
import { FC } from "react";
// next
import Image from "next/image";
// ui
import { SecondaryButton } from "components/ui";
import { PrimaryButton } from "components/ui";
// icon
import { AssignmentClipboardIcon } from "components/icons";
// img
import JoinProjectImg from "public/join-project.svg";
export interface JoinProjectProps {
isJoiningProject: boolean;
@ -9,18 +15,27 @@ export interface JoinProjectProps {
}
export const JoinProject: FC<JoinProjectProps> = ({ isJoiningProject, handleJoin }) => (
<div className="flex h-full w-full items-center justify-center">
<div className="space-y-4 text-center">
<h1 className="text-2xl font-bold">You are not a member of this project</h1>
<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>
<SecondaryButton loading={isJoiningProject} onClick={handleJoin}>
{isJoiningProject ? "Joining..." : "Click to join"}
</SecondaryButton>
</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

@ -10,7 +10,9 @@ import projectService from "services/project.service";
// hooks
import useUser from "hooks/use-user";
// ui
import { SecondaryButton, Spinner } from "components/ui";
import { PrimaryButton, Spinner } from "components/ui";
// icon
import { LayerDiagonalIcon } from "components/icons";
// components
import { NotAuthorizedView } from "components/core";
import { CommandPalette } from "components/command-palette";
@ -103,13 +105,17 @@ const AppLayout: FC<AppLayoutProps> = ({
actionButton={
(memberType?.isViewer || memberType?.isGuest) && projectId ? (
<Link href={`/${workspaceSlug}/projects/${projectId}/issues`}>
<SecondaryButton>Go to Issues</SecondaryButton>
<PrimaryButton className="flex items-center gap-1">
<LayerDiagonalIcon height={16} width={16} color="white" /> Go to Issues
</PrimaryButton>
</Link>
) : (
(memberType?.isViewer || memberType?.isGuest) &&
workspaceSlug && (
<Link href={`/${workspaceSlug}`}>
<SecondaryButton>Go to workspace</SecondaryButton>
<PrimaryButton className="flex items-center gap-1">
<LayerDiagonalIcon height={16} width={16} color="white" /> Go to workspace
</PrimaryButton>
</Link>
)
)

View File

@ -20,7 +20,7 @@ import {
// ui
import { Spinner } from "components/ui";
// icons
import Logo from "public/logo-with-text.png";
import Logo from "public/logo.png";
// types
import type { NextPage } from "next";
@ -105,31 +105,28 @@ const SignInPage: NextPage = () => {
)}
<div className="flex h-screen w-full items-center justify-center overflow-auto bg-gray-50">
<div className="flex min-h-full w-full flex-col justify-center py-12 px-6 lg:px-8">
<div className="sm:mx-auto sm:w-full sm:max-w-md">
<div className="text-center">
<Image src={Logo} height={40} width={179} alt="Plane Web Logo" />
</div>
<h2 className="mt-3 text-center text-3xl font-bold text-gray-900">
Sign in to your account
<div className="flex flex-col gap-10 sm:mx-auto sm:w-full sm:max-w-md">
<div className="flex flex-col items-center justify-center gap-10">
<Image src={Logo} height={80} width={80} alt="Plane Web Logo" />
<h2 className="text-center text-xl font-medium text-black">
Sign In to your Plane Account
</h2>
<div className="mt-16 bg-white py-8 px-4 sm:rounded-lg sm:px-10">
</div>
<div className="flex flex-col rounded-[10px] bg-white shadow-md">
{parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
<>
<div className="mb-4">
<EmailSignInForm handleSuccess={onSignInSuccess} />
</div>
<div className="mb-4">
<div className="flex flex-col gap-3 py-5 px-5 border-t items-center justify-center border-gray-300 ">
<GoogleLoginButton handleSignIn={handleGoogleSignIn} />
</div>
<div className="mb-4">
<GithubLoginButton handleSignIn={handleGithubSignIn} />
</div>
</>
) : (
<>
<div className="mb-4">
<EmailPasswordForm onSuccess={onSignInSuccess} />
</div>
</>
)}
</div>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 33 KiB