import InvalidInputMessage from "@/accounts/components/two-factor/InvalidInputMessage"; import { wait } from "@/utils/promise"; import { CenteredFlex, VerticallyCentered, } from "@ente/shared/components/Container"; import SubmitButton from "@ente/shared/components/SubmitButton"; import { Box, Typography } from "@mui/material"; import { Formik, type FormikHelpers } from "formik"; import { t } from "i18next"; import { useRef, useState } from "react"; import OtpInput from "react-otp-input"; interface formValues { otp: string; } interface Props { onSubmit: VerifyTwoFactorCallback; buttonText: string; } export type VerifyTwoFactorCallback = ( otp: string, markSuccessful: () => Promise, ) => Promise; export default function VerifyTwoFactor(props: Props) { const [waiting, setWaiting] = useState(false); const otpInputRef = useRef(null); const [success, setSuccess] = useState(false); const markSuccessful = async () => { setWaiting(false); setSuccess(true); await wait(1000); }; const submitForm = async ( { otp }: formValues, { setFieldError, resetForm }: FormikHelpers, ) => { try { setWaiting(true); await props.onSubmit(otp, markSuccessful); } catch (e) { resetForm(); for (let i = 0; i < 6; i++) { otpInputRef.current?.focusPrevInput(); } const message = e instanceof Error ? e.message : ""; setFieldError("otp", `${t("UNKNOWN_ERROR")} ${message}`); } setWaiting(false); }; const onChange = (callback: Function, triggerSubmit: Function) => (otp: string) => { callback(otp); if (otp.length === 6) { triggerSubmit(otp); } }; return ( initialValues={{ otp: "" }} validateOnChange={false} validateOnBlur={false} onSubmit={submitForm} > {({ values, errors, handleChange, handleSubmit, submitForm }) => (
{t("ENTER_TWO_FACTOR_OTP")} {errors.otp && ( {t("INCORRECT_CODE")} )}
)} ); }