import { useTranslation } from 'react-i18next'; import { Box, Button, Stack, Typography } from '@mui/material'; import { Edit2 } from 'iconsax-react'; import DigitInput from '@/components/DigitsInput'; import type { AuthMode, AuthType } from '../../types/authTypes'; import { useEffect, useState } from 'react'; import { AuthenticationCard } from '../AuthenticationCard'; import type { LoginRequest, LoginResult } from '../../types/userTypes'; import { loginOrSignUpWithOtp, sendEmailOtp, sendSmsOtp, } from '../../api/authorizationAPI'; import type { CountryCode, GUID } from '@/types/commonTypes'; import { Icon, useToast } from '@rkheftan/harmony-ui'; import { useApi } from '@/hooks/useApi'; import { generateTokenWithOtp } from '../../api/identityAPI'; import { useAuth } from '@/hooks/useAuth'; interface OtpVerifyFormProps { value: string; countryCode: CountryCode; authType: AuthType; authMode: AuthMode; onEditValue: () => void; onOTPVerified: (loginResult: LoginResult) => void; authReturnUrl: string; } export function OtpVerifyForm({ value, countryCode, authType, authMode, onEditValue, onOTPVerified, authReturnUrl, }: OtpVerifyFormProps) { const [otpCode, setOtpCode] = useState(''); const [otpDigitInvalid, setOtpDigitInvalid] = useState(false); const [isStatusSuccess, setIsStatusSuccess] = useState(); const { t } = useTranslation('authentication'); const [resendTimer, setResendTimer] = useState(120); const [canResend, setCanResend] = useState(false); const toast = useToast(); const { loading: smsResendLoading, execute: smsResendCall } = useApi(sendSmsOtp); const { loading: emailResendLoading, execute: emailResendCall } = useApi(sendEmailOtp); const { loading: loginSignUpLoading, execute: loginSignUpCall } = useApi(loginOrSignUpWithOtp); const auth = useAuth(); useEffect(() => { let interval: NodeJS.Timeout; if (resendTimer > 0) { interval = setInterval(() => { setResendTimer((prev) => prev - 1); }, 1000); } else { setCanResend(true); } return () => clearInterval(interval); }, [resendTimer]); const handleResendOTPCode = async () => { if (authType === 'phone') { await smsResendCall({ phoneNumber: countryCode + value }); } else { await emailResendCall({ email: value }); } setResendTimer(120); setCanResend(false); }; const formatTime = (seconds: number) => { const min = Math.floor(seconds / 60); const sec = seconds % 60; return `${min}:${sec.toString().padStart(2, '0')}`; }; const handleVerifyOTP = () => { if (!otpCode || otpCode.length < 4) { setOtpDigitInvalid(true); } else { handleLoginOrSignUp(); } }; const handleLoginOrSignUp = async () => { setOtpDigitInvalid(false); const loginRequest: LoginRequest = { otpCode: otpCode, phoneNumber: authType === 'phone' ? countryCode + value : undefined, email: authType === 'email' ? value : undefined, returnUrl: authReturnUrl, }; const res = await loginSignUpCall(loginRequest); if (!res) { return; } if (res.success) { setIsStatusSuccess(true); const tokenRes = await generateTokenWithOtp({ email: loginRequest.email, phonenumber: loginRequest.phoneNumber, otp: loginRequest.otpCode, }); auth.login({ ...tokenRes.data, }); onOTPVerified(res); toast({ message: authMode === 'login' ? t('verify.youHaveSuccessfullyLoggedIn') : t('verify.youHaveSuccessfullySignedIn'), severity: 'success', }); } else { setIsStatusSuccess(false); toast({ message: res.message, severity: 'error', }); } }; const otpMessageFn = (): string => { if (authType === 'phone' && authMode === 'login') { return t( 'verify.a4DigitVerificationCodeHasBeenSentToYourBobileNumberPleaseEnterIt', ); } else if (authType === 'phone' && authMode === 'register') { return t( 'verify.thereIsNoAccountWithThisNumberA4DigitVerificationCodeHasBeenSentToThisNumberToCreateANewAccount', ); } else if (authType === 'email' && authMode === 'login') { return t( 'verify.a4digitVerificationCodeHasBeenSentToYourEmailAddressPleaseEnterIt', ); } else if (authType === 'email' && authMode === 'register') { return t( 'verify.thereIsNoAccountWithThisEmailAddressA4DigitVerificationCodeHasBeenSentToThisEmailAddressToCreateANewAccount', ); } return ''; }; const otpMessage = otpMessageFn(); return ( {t('verify.verify')} {otpMessage} setOtpCode(value)} /> {t('verify.resendCodeIn')} {!canResend && `${formatTime(resendTimer)} ${t('verify.moreMinute')}`} {canResend && ( )} ); }