style: auth screens (#1531)

* chore: invitations empty state

* style: new auth screens

* chore: update typography

* chore: update border colors

* chore: resend code text
This commit is contained in:
Aaryan Khandelwal 2023-07-17 13:00:44 +05:30 committed by GitHub
parent da6ecd439c
commit 5fadf53580
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
181 changed files with 682 additions and 645 deletions

View file

@ -32,6 +32,7 @@ export const EmailCodeForm = ({ handleSignIn }: any) => {
setError,
setValue,
getValues,
watch,
formState: { errors, isSubmitting, isValid, isDirty },
} = useForm<EmailCodeFormValues>({
defaultValues: {
@ -112,43 +113,34 @@ export const EmailCodeForm = ({ handleSignIn }: any) => {
return (
<>
<form className="space-y-5 py-5 px-5">
{(codeSent || codeResent) && (
<div className="rounded-md bg-green-500/20 p-4">
<div className="flex">
<div className="flex-shrink-0">
<CheckCircleIcon className="h-5 w-5 text-green-500" aria-hidden="true" />
</div>
<div className="ml-3">
<p className="text-sm font-medium text-green-500">
{codeResent
? "Please check your mail for new code."
: "Please check your mail for code."}
</p>
</div>
</div>
</div>
)}
<div>
{(codeSent || codeResent) && (
<p className="text-center mt-4">
We have sent the sign in code.
<br />
Please check your inbox at <span className="font-medium">{watch("email")}</span>
</p>
)}
<form className="space-y-4 mt-10 w-full sm:w-[360px] mx-auto">
<div className="space-y-1">
<Input
id="email"
type="email"
name="email"
register={register}
validations={{
required: "Email ID is required",
required: "Email address is required",
validate: (value) =>
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
value
) || "Email ID is not valid",
) || "Email address is not valid",
}}
error={errors.email}
placeholder="Enter your Email ID"
placeholder="Enter your email address..."
/>
</div>
{codeSent && (
<div>
<>
<Input
id="token"
type="token"
@ -158,14 +150,14 @@ export const EmailCodeForm = ({ handleSignIn }: any) => {
required: "Code is required",
}}
error={errors.token}
placeholder="Enter code"
placeholder="Enter code..."
/>
<button
type="button"
className={`mt-5 flex w-full justify-end text-xs outline-none ${
className={`flex w-full justify-end text-xs outline-none ${
isResendDisabled
? "cursor-default text-custom-text-200"
: "cursor-pointer text-custom-primary"
: "cursor-pointer text-custom-primary-100"
} `}
onClick={() => {
setIsCodeResending(true);
@ -178,46 +170,43 @@ export const EmailCodeForm = ({ handleSignIn }: any) => {
disabled={isResendDisabled}
>
{resendCodeTimer > 0 ? (
<p className="text-right">
Didn{"'"}t receive code? Get new code in {resendCodeTimer} seconds.
</p>
<span className="text-right">Request new code in {resendCodeTimer} seconds</span>
) : isCodeResending ? (
"Sending code..."
"Sending new code..."
) : errorResendingCode ? (
"Please try again later"
) : (
"Resend code"
)}
</button>
</div>
</>
)}
{codeSent ? (
<PrimaryButton
type="submit"
className="w-full text-center"
size="md"
onClick={handleSubmit(handleSignin)}
disabled={!isValid && isDirty}
loading={isLoading}
>
{isLoading ? "Signing in..." : "Sign in"}
</PrimaryButton>
) : (
<PrimaryButton
className="w-full text-center"
size="md"
onClick={() => {
handleSubmit(onSubmit)().then(() => {
setResendCodeTimer(30);
});
}}
disabled={!isValid && isDirty}
loading={isSubmitting}
>
{isSubmitting ? "Sending code..." : "Send sign in code"}
</PrimaryButton>
)}
<div>
{codeSent ? (
<PrimaryButton
type="submit"
className="w-full text-center"
size="md"
onClick={handleSubmit(handleSignin)}
disabled={!isValid && isDirty}
loading={isLoading}
>
{isLoading ? "Signing in..." : "Sign in"}
</PrimaryButton>
) : (
<PrimaryButton
className="w-full text-center"
size="md"
onClick={() => {
handleSubmit(onSubmit)().then(() => {
setResendCodeTimer(30);
});
}}
loading={isSubmitting || (!isValid && isDirty)}
>
{isSubmitting ? "Sending code..." : "Send code"}
</PrimaryButton>
)}
</div>
</form>
</>
);

View file

@ -8,7 +8,7 @@ import { useForm } from "react-hook-form";
// components
import { EmailResetPasswordForm } from "components/account";
// ui
import { Input, SecondaryButton } from "components/ui";
import { Input, PrimaryButton } from "components/ui";
// types
type EmailPasswordFormValues = {
email: string;
@ -42,28 +42,38 @@ export const EmailPasswordForm: React.FC<Props> = ({ onSubmit }) => {
return (
<>
<h1 className="text-center text-2xl sm:text-2.5xl font-semibold text-custom-text-100">
{isResettingPassword
? "Reset your password"
: isSignUpPage
? "Sign up on Plane"
: "Sign in to Plane"}
</h1>
{isResettingPassword ? (
<EmailResetPasswordForm setIsResettingPassword={setIsResettingPassword} />
) : (
<form className="mt-5 py-5 px-5" onSubmit={handleSubmit(onSubmit)}>
<div>
<form
className="space-y-4 mt-10 w-full sm:w-[360px] mx-auto"
onSubmit={handleSubmit(onSubmit)}
>
<div className="space-y-1">
<Input
id="email"
type="email"
name="email"
register={register}
validations={{
required: "Email ID is required",
required: "Email address is required",
validate: (value) =>
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
value
) || "Email ID is not valid",
) || "Email address is not valid",
}}
error={errors.email}
placeholder="Enter your email ID"
placeholder="Enter your email address..."
/>
</div>
<div className="mt-5">
<div className="space-y-1">
<Input
id="password"
type="password"
@ -73,30 +83,28 @@ export const EmailPasswordForm: React.FC<Props> = ({ onSubmit }) => {
required: "Password is required",
}}
error={errors.password}
placeholder="Enter your password"
placeholder="Enter your password..."
/>
</div>
<div className="mt-2 flex items-center justify-between">
<div className="ml-auto text-sm">
{isSignUpPage ? (
<Link href="/">
<a className="font-medium text-custom-primary hover:text-custom-primary">
Already have an account? Sign in.
</a>
</Link>
) : (
<button
type="button"
onClick={() => setIsResettingPassword(true)}
className="font-medium text-custom-primary hover:text-custom-primary"
>
Forgot your password?
</button>
)}
</div>
<div className="text-right text-xs">
{isSignUpPage ? (
<Link href="/">
<a className="text-custom-text-200 hover:text-custom-primary-100">
Already have an account? Sign in.
</a>
</Link>
) : (
<button
type="button"
onClick={() => setIsResettingPassword(true)}
className="text-custom-text-200 hover:text-custom-primary-100"
>
Forgot your password?
</button>
)}
</div>
<div className="mt-5">
<SecondaryButton
<div>
<PrimaryButton
type="submit"
className="w-full text-center"
disabled={!isValid && isDirty}
@ -105,14 +113,14 @@ export const EmailPasswordForm: React.FC<Props> = ({ onSubmit }) => {
{isSignUpPage
? isSubmitting
? "Signing up..."
: "Sign Up"
: "Sign up"
: isSubmitting
? "Signing in..."
: "Sign In"}
</SecondaryButton>
: "Sign in"}
</PrimaryButton>
{!isSignUpPage && (
<Link href="/sign-up">
<a className="block font-medium text-custom-primary hover:text-custom-primary text-sm mt-1">
<a className="block text-custom-text-200 hover:text-custom-primary-100 text-xs mt-4">
Don{"'"}t have an account? Sign up.
</a>
</Link>

View file

@ -59,25 +59,28 @@ export const EmailResetPasswordForm: React.FC<Props> = ({ setIsResettingPassword
};
return (
<form className="mt-5 py-5 px-5" onSubmit={handleSubmit(forgotPassword)}>
<div>
<form
className="space-y-4 mt-10 w-full sm:w-[360px] mx-auto"
onSubmit={handleSubmit(forgotPassword)}
>
<div className="space-y-1">
<Input
id="email"
type="email"
name="email"
register={register}
validations={{
required: "Email ID is required",
required: "Email address is required",
validate: (value) =>
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
value
) || "Email ID is not valid",
) || "Email address is not valid",
}}
error={errors.email}
placeholder="Enter registered Email ID"
placeholder="Enter registered email address.."
/>
</div>
<div className="mt-5 flex items-center gap-2">
<div className="mt-5 flex flex-col-reverse sm:flex-row items-center gap-2">
<SecondaryButton
className="w-full text-center"
onClick={() => setIsResettingPassword(false)}

View file

@ -1,9 +1,14 @@
import { useEffect, useState, FC } from "react";
import Link from "next/link";
import Image from "next/image";
import { useRouter } from "next/router";
// next-themes
import { useTheme } from "next-themes";
// images
import githubImage from "/public/logos/github-black.png";
import githubBlackImage from "/public/logos/github-black.png";
import githubWhiteImage from "/public/logos/github-white.png";
const { NEXT_PUBLIC_GITHUB_ID } = process.env;
@ -11,15 +16,15 @@ export interface GithubLoginButtonProps {
handleSignIn: React.Dispatch<string>;
}
export const GithubLoginButton: FC<GithubLoginButtonProps> = (props) => {
const { handleSignIn } = props;
// router
export const GithubLoginButton: FC<GithubLoginButtonProps> = ({ handleSignIn }) => {
const [loginCallBackURL, setLoginCallBackURL] = useState(undefined);
const [gitCode, setGitCode] = useState<null | string>(null);
const {
query: { code },
} = useRouter();
// states
const [loginCallBackURL, setLoginCallBackURL] = useState(undefined);
const [gitCode, setGitCode] = useState<null | string>(null);
const { theme } = useTheme();
useEffect(() => {
if (code && !gitCode) {
@ -35,13 +40,18 @@ export const GithubLoginButton: FC<GithubLoginButtonProps> = (props) => {
}, []);
return (
<div className="w-full flex justify-center items-center px-[3px]">
<div className="w-full flex justify-center items-center">
<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 justify-center gap-3 rounded border border-custom-border-100 p-2 text-sm font-medium text-custom-text-200 duration-300 hover:bg-custom-background-80">
<Image src={githubImage} height={20} width={20} color="#000" alt="GitHub Logo" />
<span>Sign In with Github</span>
<button className="flex w-full items-center justify-center gap-2 rounded border border-custom-border-300 p-2 text-sm font-medium text-custom-text-100 duration-300 hover:bg-custom-background-80">
<Image
src={theme === "light" ? githubBlackImage : githubWhiteImage}
height={20}
width={20}
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: "410",
width: "360",
text: "continue_with",
} as GsiButtonConfiguration // customization attributes
);
@ -48,7 +48,7 @@ export const GoogleLoginButton: FC<IGoogleLoginButton> = (props) => {
<>
<Script src="https://accounts.google.com/gsi/client" async defer onLoad={loadScript} />
<div
className="overflow-hidden rounded w-full flex justify-center items-center"
className="overflow-hidden rounded w-full flex justify-center items-center !text-sm !font-medium !text-custom-text-100"
id="googleSignInButton"
ref={googleSignInButton}
/>