diff --git a/public/locales/en/authentication.json b/public/locales/en/authentication.json
index ef0caca..7b70125 100644
--- a/public/locales/en/authentication.json
+++ b/public/locales/en/authentication.json
@@ -16,7 +16,10 @@
"thereIsNoAccountWithThisEmailAddressA4DigitVerificationCodeHasBeenSentToThisEmailAddressToCreateANewAccount": "There is no account with this email address. A 4-digit verification code has been sent to this email address to create a new account.",
"theVerificationCodeIsIncorrect": "The verification code is incorrect.",
"youHaveSuccessfullyLoggedIn": "You have successfully logged in",
- "youHaveSuccessfullySignedIn": "You have successfully signed in"
+ "youHaveSuccessfullySignedIn": "You have successfully signed in",
+ "resendCodeIn": "Resend code in",
+ "moreMinute": "minute",
+ "resendCode": "Resend code"
},
"completeSignUp": {
"completeSignUp": "Complete Sign Up",
diff --git a/public/locales/fa/authentication.json b/public/locales/fa/authentication.json
index ad86fc7..224d34d 100644
--- a/public/locales/fa/authentication.json
+++ b/public/locales/fa/authentication.json
@@ -19,7 +19,10 @@
"thereIsNoAccountWithThisEmailAddressA4DigitVerificationCodeHasBeenSentToThisEmailAddressToCreateANewAccount": "حساب کاربری با این ایمیل وجود ندارد. برای ساخت حساب جدید، کد تایید ۴ رقمی برای این ایمیل ارسال گردید.",
"theVerificationCodeIsIncorrect": "کد تایید اشتباه می باشد",
"youHaveSuccessfullyLoggedIn": "با موفقیت وارد شدید",
- "youHaveSuccessfullySignedIn": "ثبت نام با موفقیت انجام شد"
+ "youHaveSuccessfullySignedIn": "ثبت نام با موفقیت انجام شد",
+ "resendCodeIn": "ارسال مجدد کد تا",
+ "moreMinute": "دقیقه دیگر",
+ "resendCode": "ارسال مجدد"
},
"completeSignUp": {
"completeSignUp": "تکمیل ثبت نام",
diff --git a/src/features/authentication/components/AuthenticationCard.tsx b/src/features/authentication/components/AuthenticationCard.tsx
new file mode 100644
index 0000000..9e82632
--- /dev/null
+++ b/src/features/authentication/components/AuthenticationCard.tsx
@@ -0,0 +1,18 @@
+import { Paper } from '@mui/material';
+import React, { type PropsWithChildren } from 'react';
+
+// Beacuse in the otp verify there is a element outside of the authentication card
+export const AuthenticationCard = ({ children }: PropsWithChildren) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/features/authentication/components/CompleteSignUp.tsx b/src/features/authentication/components/CompleteSignUp.tsx
index ccf8eb6..098396b 100644
--- a/src/features/authentication/components/CompleteSignUp.tsx
+++ b/src/features/authentication/components/CompleteSignUp.tsx
@@ -1,8 +1,9 @@
-import { Box, Button, TextField, Typography } from '@mui/material';
+import { Box, Button, Paper, TextField, Typography } from '@mui/material';
import parsePhoneNumberFromString from 'libphonenumber-js';
import React, { useRef, useState, type Dispatch } from 'react';
import { useTranslation } from 'react-i18next';
import { CountryCodeSelector } from './CountryCodeSelector';
+import { AuthenticationCard } from './AuthenticationCard';
export interface CompleteSignUpProps {
email: string;
@@ -59,7 +60,7 @@ export const CompleteSignUp = ({
};
return (
-
+
{t('completeSignUp.completeSignUp')}
@@ -101,6 +102,6 @@ export const CompleteSignUp = ({
-
+
);
};
diff --git a/src/features/authentication/components/LoginRegiserForm.tsx b/src/features/authentication/components/LoginRegiserForm.tsx
index edf9296..a851d14 100644
--- a/src/features/authentication/components/LoginRegiserForm.tsx
+++ b/src/features/authentication/components/LoginRegiserForm.tsx
@@ -1,4 +1,11 @@
-import { Box, Button, Stack, TextField, Typography } from '@mui/material';
+import {
+ Box,
+ Button,
+ Paper,
+ Stack,
+ TextField,
+ Typography,
+} from '@mui/material';
import { useRef, useState, type Dispatch } from 'react';
import { useTranslation } from 'react-i18next';
import { CountryCodeSelector } from './CountryCodeSelector';
@@ -7,6 +14,7 @@ import { isNumeric } from '@/utils/regexes/isNumeric';
import type { AuthMode, AuthType } from '../types/auth-types';
import { isEmail } from '@/utils/regexes/isEmail';
import parsePhoneNumberFromString from 'libphonenumber-js';
+import { AuthenticationCard } from './AuthenticationCard';
export interface LoginRegisterFormProps {
loginRegisterValue: string;
@@ -95,7 +103,7 @@ export function LoginRegisterForm({
const showAdornment = authType === 'phone' && loginRegisterValue.length > 0;
return (
-
+
{t('loginForm.title')}
@@ -136,6 +144,6 @@ export function LoginRegisterForm({
{t('loginForm.loginWithGoogle')}
-
+
);
}
diff --git a/src/features/authentication/components/OtpVerifyForm.tsx b/src/features/authentication/components/OtpVerifyForm.tsx
index 0748f42..f958bfc 100644
--- a/src/features/authentication/components/OtpVerifyForm.tsx
+++ b/src/features/authentication/components/OtpVerifyForm.tsx
@@ -1,10 +1,11 @@
import { useTranslation } from 'react-i18next';
-import { Alert, Box, Button, Snackbar, Typography } from '@mui/material';
+import { Alert, Box, Button, Snackbar, Stack, Typography } from '@mui/material';
import { Edit2 } from 'iconsax-reactjs';
import DigitInput from '@/components/components/DigitsInput';
import type { AuthMode, AuthType } from '../types/auth-types';
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import { Toast } from '@/components/Toast';
+import { AuthenticationCard } from './AuthenticationCard';
interface OtpVerifyFormProps {
value: string;
@@ -28,6 +29,42 @@ export function OtpVerifyForm({
useState(false);
const [verifyAlertOpen, setVerifyAlertOpen] = useState(false);
const { t } = useTranslation('authentication');
+ const [resendTimer, setResendTimer] = useState(120);
+ const [canResend, setCanResend] = useState(false);
+ const [resendLoading, setResendLoading] = useState(false);
+
+ useEffect(() => {
+ let interval: NodeJS.Timeout;
+ if (resendTimer > 0) {
+ interval = setInterval(() => {
+ setResendTimer((prev) => prev - 1);
+ }, 1000);
+ } else {
+ setCanResend(true);
+ }
+
+ return () => clearInterval(interval);
+ }, [resendTimer]);
+
+ const handleResendOTPCode = () => {
+ setResendLoading(true);
+
+ // TODO: Call API here instead of settimeout
+
+ setTimeout(() => {
+ console.log('resended');
+
+ setResendTimer(120);
+ setCanResend(false);
+ setResendLoading(false);
+ }, 1000);
+ };
+
+ const formatTime = (seconds: number) => {
+ const min = Math.floor(seconds / 60);
+ const sec = seconds % 60;
+ return `${min}:${sec.toString().padStart(2, '0')}`;
+ };
const handleDigitInputChange = (value: string[]) => {
const formattedValue = value.filter((char) => char !== '').join('');
@@ -87,53 +124,76 @@ export function OtpVerifyForm({
};
return (
-
- setVerifyAlertOpen(false)}
- color={verifyStatus === 'failed' ? 'error' : 'success'}
- >
- {verifyAlertMessage()}
-
+
+
+ setVerifyAlertOpen(false)}
+ color={verifyStatus === 'failed' ? 'error' : 'success'}
+ >
+ {verifyAlertMessage()}
+
-
+ {t('verify.verify')}
+
+ }
+ onClick={onEditValue}
+ >
+ {value}
+
+
+
+
+ {otpMessage()}
+
+
+ handleDigitInputChange(value as string[])}
+ />
+
+
+
+
+
- {t('verify.verify')}
+ {t('verify.resendCodeIn')}
}
- onClick={onEditValue}
+ variant="text"
+ loading={resendLoading}
+ sx={{ width: 'auto' }}
+ onClick={canResend ? handleResendOTPCode : undefined}
>
- {value}
+ {canResend && t('verify.resendCode')}
+ {!canResend && `${formatTime(resendTimer)} ${t('verify.moreMinute')}`}
-
-
-
- {otpMessage()}
-
-
- handleDigitInputChange(value as string[])}
- />
-
-
-
+
+
);
}
diff --git a/src/features/authentication/components/SmsOtpForm.tsx b/src/features/authentication/components/SmsOtpForm.tsx
deleted file mode 100644
index ce03b0a..0000000
--- a/src/features/authentication/components/SmsOtpForm.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useTranslation } from 'react-i18next';
-import { Box, Button, Typography } from '@mui/material';
-import { Edit2 } from 'iconsax-reactjs';
-import DigitInput from '@/components/components/DigitsInput';
-
-interface SmsOtpProps {
- value: string;
- type: 'phone' | 'email';
-}
-
-export function SmsOtpForm({ value, type }: SmsOtpProps) {
- const { t } = useTranslation('authentication');
-
- return (
-
-
- اعتبارسنجی
-
- }
- >
- {value}
-
-
-
- کد تایید ۴ رقمی به شماره موبایل شما ارسال شد. لطفا آن را وارد کنید.
-
- console.log(value)} />
-
-
- );
-}
diff --git a/src/features/authentication/routes/AuthenticationPage.tsx b/src/features/authentication/routes/AuthenticationPage.tsx
index 158d0a8..b23f6c5 100644
--- a/src/features/authentication/routes/AuthenticationPage.tsx
+++ b/src/features/authentication/routes/AuthenticationPage.tsx
@@ -1,7 +1,6 @@
import { FlexBox } from '@/components/components/common/FlexBox';
import Logo from '@/components/Logo';
import { Paper } from '@mui/material';
-import { SmsOtpForm } from '../components/SmsOtpForm';
import { useState } from 'react';
import { AuthenticationContainer } from '../components/AuthenticationContainer';
@@ -17,16 +16,7 @@ export function AuthenticationPage() {
}}
>
-
-
-
+
);
}