diff --git a/packages/experience/src/containers/TotpCodeVerification/index.tsx b/packages/experience/src/containers/TotpCodeVerification/index.tsx index 16d9897ae521..6fb473000437 100644 --- a/packages/experience/src/containers/TotpCodeVerification/index.tsx +++ b/packages/experience/src/containers/TotpCodeVerification/index.tsx @@ -1,4 +1,5 @@ import { useCallback, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import Button from '@/components/Button'; import VerificationCodeInput from '@/components/VerificationCode'; @@ -18,17 +19,28 @@ type Props = { }; const TotpCodeVerification = ({ flow }: Props) => { + const { t } = useTranslation(); + const [codeInput, setCodeInput] = useState([]); + const [inputErrorMessage, setInputErrorMessage] = useState(); + const errorCallback = useCallback(() => { setCodeInput([]); + setInputErrorMessage(undefined); }, []); - const { errorMessage, onSubmit } = useTotpCodeVerification(flow, errorCallback); + const { errorMessage: submitErrorMessage, onSubmit } = useTotpCodeVerification( + flow, + errorCallback + ); const [isSubmitting, setIsSubmitting] = useState(false); + const errorMessage = inputErrorMessage ?? submitErrorMessage; + const handleSubmit = useCallback( async (code: string[]) => { + setInputErrorMessage(undefined); setIsSubmitting(true); await onSubmit(code.join('')); setIsSubmitting(false); @@ -55,8 +67,12 @@ const TotpCodeVerification = ({ flow }: Props) => { type="primary" className={styles.continueButton} isLoading={isSubmitting} - isDisabled={!isCodeReady(codeInput)} onClick={() => { + if (!isCodeReady(codeInput)) { + setInputErrorMessage(t('error.invalid_passcode')); + return; + } + void handleSubmit(codeInput); }} /> diff --git a/packages/experience/src/containers/VerificationCode/index.tsx b/packages/experience/src/containers/VerificationCode/index.tsx index 35e6c63414d1..f24bfd9276c3 100644 --- a/packages/experience/src/containers/VerificationCode/index.tsx +++ b/packages/experience/src/containers/VerificationCode/index.tsx @@ -23,6 +23,8 @@ type Props = { const VerificationCode = ({ flow, identifier, className, hasPasswordButton, target }: Props) => { const [codeInput, setCodeInput] = useState([]); + const [inputErrorMessage, setInputErrorMessage] = useState(); + const { t } = useTranslation(); const isCodeInputReady = useMemo( @@ -34,13 +36,16 @@ const VerificationCode = ({ flow, identifier, className, hasPasswordButton, targ const errorCallback = useCallback(() => { setCodeInput([]); + setInputErrorMessage(undefined); }, []); - const { errorMessage, clearErrorMessage, onSubmit } = useVerificationCode( - identifier, - target, - errorCallback - ); + const { + errorMessage: submitErrorMessage, + clearErrorMessage, + onSubmit, + } = useVerificationCode(identifier, target, errorCallback); + + const errorMessage = inputErrorMessage ?? submitErrorMessage; const { seconds, isRunning, onResendVerificationCode } = useResendVerificationCode( flow, @@ -52,6 +57,8 @@ const VerificationCode = ({ flow, identifier, className, hasPasswordButton, targ const handleSubmit = useCallback( async (code: string[]) => { + setInputErrorMessage(undefined); + setIsSubmitting(true); await onSubmit( @@ -110,10 +117,14 @@ const VerificationCode = ({ flow, identifier, className, hasPasswordButton, targ