From d65d89be36894fe53a1ebb3a21a46e913365b0d5 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:37:17 +0530 Subject: [PATCH] chore: sign up form password strength improvement (#4876) --- .../account/auth-forms/password.tsx | 258 ++++++++++-------- 1 file changed, 139 insertions(+), 119 deletions(-) diff --git a/web/core/components/account/auth-forms/password.tsx b/web/core/components/account/auth-forms/password.tsx index a11a3eaf8..08f91a9cc 100644 --- a/web/core/components/account/auth-forms/password.tsx +++ b/web/core/components/account/auth-forms/password.tsx @@ -4,7 +4,7 @@ import React, { useEffect, useMemo, useState } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; // icons -import { Eye, EyeOff, XCircle } from "lucide-react"; +import { Eye, EyeOff, Info, X, XCircle } from "lucide-react"; // ui import { Button, Input, Spinner } from "@plane/ui"; // components @@ -61,6 +61,7 @@ export const AuthPasswordForm: React.FC = observer((props: Props) => { const [isSubmitting, setIsSubmitting] = useState(false); const [isPasswordInputFocused, setIsPasswordInputFocused] = useState(false); const [isRetryPasswordInputFocused, setIsRetryPasswordInputFocused] = useState(false); + const [isBannerMessage, setBannerMessage] = useState(false); const handleShowPassword = (key: keyof typeof showPassword) => setShowPassword((prev) => ({ ...prev, [key]: !prev[key] })); @@ -104,10 +105,7 @@ export const AuthPasswordForm: React.FC = observer((props: Props) => { () => !isSubmitting && !!passwordFormData.password && - (mode === EAuthModes.SIGN_UP - ? getPasswordStrength(passwordFormData.password) >= 3 && - passwordFormData.password === passwordFormData.confirm_password - : true) + (mode === EAuthModes.SIGN_UP ? passwordFormData.password === passwordFormData.confirm_password : true) ? false : true, [isSubmitting, mode, passwordFormData.confirm_password, passwordFormData.password] @@ -118,140 +116,162 @@ export const AuthPasswordForm: React.FC = observer((props: Props) => { const renderPasswordMatchError = !isRetryPasswordInputFocused || confirmPassword.length >= password.length; return ( -
{ - setIsSubmitting(true); - captureEvent(mode === EAuthModes.SIGN_IN ? SIGN_IN_WITH_PASSWORD : SIGN_UP_WITH_PASSWORD); - }} - onError={() => setIsSubmitting(false)} - > - - - {nextPath && } -
- -
- handleFormChange("email", e.target.value)} - placeholder="name@company.com" - className={`disable-autofill-style h-[46px] w-full placeholder:text-onboarding-text-400 border-0`} - disabled - /> - {passwordFormData.email.length > 0 && ( - - )} + <> + {isBannerMessage && ( +
+
+ +
+
Try setting-up a strong password to proceed
+
setBannerMessage(false)} + > + +
-
- -
- -
- handleFormChange("password", e.target.value)} - placeholder="Enter password" - className="disable-autofill-style h-[46px] w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400" - onFocus={() => setIsPasswordInputFocused(true)} - onBlur={() => setIsPasswordInputFocused(false)} - autoFocus - /> - {showPassword?.password ? ( - handleShowPassword("password")} - /> - ) : ( - handleShowPassword("password")} - /> - )} -
- {passwordSupport} -
- - {mode === EAuthModes.SIGN_UP && ( + )} + { + event.preventDefault(); // Prevent form from submitting by default + if (getPasswordStrength(passwordFormData.password) >= 3) { + setIsSubmitting(true); + captureEvent(mode === EAuthModes.SIGN_IN ? SIGN_IN_WITH_PASSWORD : SIGN_UP_WITH_PASSWORD); + event.currentTarget.submit(); // Manually submit the form if the condition is met + } else { + setBannerMessage(true); + } + }} + onError={() => setIsSubmitting(false)} + > + + + {nextPath && }
-
+ +
+
handleFormChange("confirm_password", e.target.value)} - placeholder="Confirm password" + type={showPassword?.password ? "text" : "password"} + name="password" + value={passwordFormData.password} + onChange={(e) => handleFormChange("password", e.target.value)} + placeholder="Enter password" className="disable-autofill-style h-[46px] w-full border border-onboarding-border-100 !bg-onboarding-background-200 pr-12 placeholder:text-onboarding-text-400" - onFocus={() => setIsRetryPasswordInputFocused(true)} - onBlur={() => setIsRetryPasswordInputFocused(false)} + onFocus={() => setIsPasswordInputFocused(true)} + onBlur={() => setIsPasswordInputFocused(false)} + autoFocus /> - {showPassword?.retypePassword ? ( + {showPassword?.password ? ( handleShowPassword("retypePassword")} + onClick={() => handleShowPassword("password")} /> ) : ( handleShowPassword("retypePassword")} + onClick={() => handleShowPassword("password")} /> )}
- {!!passwordFormData.confirm_password && - passwordFormData.password !== passwordFormData.confirm_password && - renderPasswordMatchError && Passwords don{"'"}t match} + {passwordSupport}
- )} -
- {mode === EAuthModes.SIGN_IN ? ( - <> - - {isSMTPConfigured && ( - - )} - - ) : ( - +
+ {!!passwordFormData.confirm_password && + passwordFormData.password !== passwordFormData.confirm_password && + renderPasswordMatchError && Passwords don{"'"}t match} +
)} - -
+ +
+ {mode === EAuthModes.SIGN_IN ? ( + <> + + {isSMTPConfigured && ( + + )} + + ) : ( + + )} +
+ + ); });