diff --git a/frontend/src/components/login/2FAStep.tsx b/frontend/src/components/login/2FAStep.tsx
new file mode 100644
index 0000000000..dfa9b6645c
--- /dev/null
+++ b/frontend/src/components/login/2FAStep.tsx
@@ -0,0 +1,136 @@
+/* eslint-disable react/jsx-props-no-spreading */
+import React, { useState } from 'react';
+import ReactCodeInput from 'react-code-input';
+import { useTranslation } from 'next-i18next';
+
+import sendVerificationEmail from '@app/pages/api/auth/SendVerificationEmail';
+
+import Button from '../basic/buttons/Button';
+import Error from '../basic/Error';
+
+// The style for the verification code input
+const props = {
+ inputStyle: {
+ fontFamily: 'monospace',
+ margin: '4px',
+ MozAppearance: 'textfield',
+ width: '55px',
+ borderRadius: '5px',
+ fontSize: '24px',
+ height: '55px',
+ paddingLeft: '7',
+ backgroundColor: '#0d1117',
+ color: 'white',
+ border: '1px solid #2d2f33',
+ textAlign: 'center',
+ outlineColor: '#8ca542',
+ borderColor: '#2d2f33'
+ }
+} as const;
+const propsPhone = {
+ inputStyle: {
+ fontFamily: 'monospace',
+ margin: '4px',
+ MozAppearance: 'textfield',
+ width: '40px',
+ borderRadius: '5px',
+ fontSize: '24px',
+ height: '40px',
+ paddingLeft: '7',
+ backgroundColor: '#0d1117',
+ color: 'white',
+ border: '1px solid #2d2f33',
+ textAlign: 'center',
+ outlineColor: '#8ca542',
+ borderColor: '#2d2f33'
+ }
+} as const;
+
+interface CodeInputStepProps {
+ email: string;
+ incrementStep: () => void;
+ setCode: (value: string) => void;
+ codeError: boolean;
+}
+
+/**
+ * This is the second step of sign up where users need to verify their email
+ * @param {object} obj
+ * @param {string} obj.email - user's email to which we just sent a verification email
+ * @param {function} obj.incrementStep - goes to the next step of signup
+ * @param {function} obj.setCode - state updating function that set the current value of the emai verification code
+ * @param {boolean} obj.codeError - whether the code was inputted wrong or now
+ * @returns
+ */
+export default function TwoFAStep({
+ email,
+ incrementStep,
+ setCode,
+ codeError
+}: CodeInputStepProps): JSX.Element {
+ const [isLoading, setIsLoading] = useState(false);
+ const [isResendingVerificationEmail, setIsResendingVerificationEmail] = useState(false);
+ const { t } = useTranslation();
+
+ const resendVerificationEmail = async () => {
+ setIsResendingVerificationEmail(true);
+ setIsLoading(true);
+ sendVerificationEmail(email);
+ setTimeout(() => {
+ setIsLoading(false);
+ setIsResendingVerificationEmail(false);
+ }, 2000);
+ };
+
+ return (
+
+
{t('signup:step2-message')}
+
{email}
+
+
+
+
+
+
+ {codeError &&
}
+
+
+
+
+
+ {t('signup:step2-resend-alert')}
+
+
+
+
+
{t('signup:step2-spam-alert')}
+
+
+ );
+}
diff --git a/frontend/src/components/signup/DonwloadBackupPDFStep.tsx b/frontend/src/components/signup/DonwloadBackupPDFStep.tsx
index 664420c3bd..240d6468a9 100644
--- a/frontend/src/components/signup/DonwloadBackupPDFStep.tsx
+++ b/frontend/src/components/signup/DonwloadBackupPDFStep.tsx
@@ -31,7 +31,7 @@ export default function DonwloadBackupPDFStep({
return (
-
+
{t('signup:step4-message')}
@@ -42,7 +42,7 @@ export default function DonwloadBackupPDFStep({
{t('signup:step4-description3')}
-
+