diff --git a/packages/account/package.json b/packages/account/package.json
index cfb0e50f8eba..a588ce2970a8 100644
--- a/packages/account/package.json
+++ b/packages/account/package.json
@@ -39,6 +39,7 @@
"@deriv/hooks": "^1.0.0",
"@deriv/integration": "1.0.0",
"@deriv/quill-icons": "^1.22.10",
+ "dayjs": "^1.11.10",
"@deriv/shared": "^1.0.0",
"@deriv/stores": "^1.0.0",
"@deriv/translations": "^1.0.0",
diff --git a/packages/account/src/Sections/Profile/PersonalDetails/verify-button.tsx b/packages/account/src/Sections/Profile/PersonalDetails/verify-button.tsx
index 1b40d03c4271..d85f66b59914 100644
--- a/packages/account/src/Sections/Profile/PersonalDetails/verify-button.tsx
+++ b/packages/account/src/Sections/Profile/PersonalDetails/verify-button.tsx
@@ -6,6 +6,7 @@ import { useHistory } from 'react-router';
import { routes } from '@deriv/shared';
import { Popover, Text } from '@deriv/components';
import { Localize } from '@deriv/translations';
+import { useVerifyEmail } from '@deriv/hooks';
export const VerifyButton = observer(() => {
const [open_popover, setOpenPopover] = React.useState(false);
@@ -15,8 +16,10 @@ export const VerifyButton = observer(() => {
const { phone_number_verification } = account_settings;
const { verified: phone_number_verified } = phone_number_verification;
const history = useHistory();
+ const { send } = useVerifyEmail('phone_number_verification');
const redirectToPhoneVerification = () => {
+ send();
history.push(routes.phone_verification);
};
@@ -26,7 +29,7 @@ export const VerifyButton = observer(() => {
- Verified
+
({
useRequestPhoneNumberOTP: jest.fn(() => ({
requestOnWhatsApp: jest.fn(),
requestOnSMS: jest.fn(),
+ email_otp_error: null,
})),
}));
describe('DidntGetTheCodeModal', () => {
const mock_store = mockStore({});
const mockSetShouldShowDidntGetTheCodeModal = jest.fn();
- const mockSetStartTimer = jest.fn();
const mockSetOtpVerification = jest.fn();
+ const mockReInitializeGetSettings = jest.fn();
+ const mockSetIsButtonDisabled = jest.fn();
const resend_code_text = /Resend code/;
const renderComponent = (phone_verification_type: string) => {
render(
@@ -37,7 +40,6 @@ describe('DidntGetTheCodeModal', () => {
beforeEach(() => {
mockSetShouldShowDidntGetTheCodeModal.mockClear();
- mockSetStartTimer.mockClear();
mockSetOtpVerification.mockClear();
});
@@ -55,21 +57,19 @@ describe('DidntGetTheCodeModal', () => {
expect(screen.getByRole('button', { name: /Send code via SMS/ })).toBeInTheDocument();
});
- it('should render setOtpVerification and setShouldShowDidintGetTheCodeModal when Change phone number is clicked, should not render setStartTimer', () => {
+ it('should render setOtpVerification and setShouldShowDidintGetTheCodeModal when Change phone number is clicked, should not render mockSetTimer', () => {
renderComponent(VERIFICATION_SERVICES.SMS);
const change_phone_number_button = screen.getByRole('button', { name: /Change phone number/ });
userEvent.click(change_phone_number_button);
expect(mockSetShouldShowDidntGetTheCodeModal).toHaveBeenCalledTimes(1);
expect(mockSetOtpVerification).toHaveBeenCalledTimes(1);
- expect(mockSetStartTimer).not.toBeCalled();
});
- it('should render setStartTimer and setShouldShowDidintGetTheCodeModal when Resend code is clicked', () => {
+ it('should render setShouldShowDidintGetTheCodeModal when Resend code is clicked', () => {
renderComponent(VERIFICATION_SERVICES.SMS);
const resend_code_button = screen.getByRole('button', { name: resend_code_text });
userEvent.click(resend_code_button);
expect(mockSetShouldShowDidntGetTheCodeModal).toHaveBeenCalledTimes(1);
- expect(mockSetStartTimer).toHaveBeenCalledTimes(1);
});
it('should render mockRequestOnSMS and setOtpVerification with phone_verification_type: sms when Resend code is clicked, phone_verification_type is sms', () => {
diff --git a/packages/account/src/Sections/Profile/PhoneVerification/__test__/otp-verification.spec.tsx b/packages/account/src/Sections/Profile/PhoneVerification/__test__/otp-verification.spec.tsx
index c2c16dba8775..0cba425020fe 100644
--- a/packages/account/src/Sections/Profile/PhoneVerification/__test__/otp-verification.spec.tsx
+++ b/packages/account/src/Sections/Profile/PhoneVerification/__test__/otp-verification.spec.tsx
@@ -2,14 +2,12 @@ import { render, screen } from '@testing-library/react';
import React from 'react';
import { StoreProvider, mockStore } from '@deriv/stores';
import OTPVerification from '../otp-verification';
-import { useSendOTPVerificationCode, useVerifyEmail } from '@deriv/hooks';
+import { useSendOTPVerificationCode, useSettings } from '@deriv/hooks';
import userEvent from '@testing-library/user-event';
jest.mock('@deriv/hooks', () => ({
...jest.requireActual('@deriv/hooks'),
- useVerifyEmail: jest.fn(() => ({
- send: jest.fn(),
- })),
+ useSettings: jest.fn(),
useSendOTPVerificationCode: jest.fn(),
}));
@@ -26,7 +24,6 @@ describe('OTPVerification', () => {
});
let phone_verification_type = 'sms';
const mockSetOtpVerification = jest.fn();
- const mockSend = jest.fn();
const mockSendPhoneOTPVerification = jest.fn();
const mockSetPhoneOtpErrorMessage = jest.fn();
const renderComponent = () => {
@@ -40,13 +37,19 @@ describe('OTPVerification', () => {
);
};
- it('should render ConfirmYourEmail in OTP Verification', () => {
- (useVerifyEmail as jest.Mock).mockReturnValueOnce({
- send: mockSend,
+ beforeEach(() => {
+ (useSettings as jest.Mock).mockReturnValue({
+ data: {
+ email: 'johndoe@regentmarkets.com',
+ },
+ invalidate: jest.fn(() => Promise.resolve()),
});
(useSendOTPVerificationCode as jest.Mock).mockReturnValue({
sendPhoneOTPVerification: jest.fn(),
});
+ });
+
+ it('should render ConfirmYourEmail in OTP Verification', () => {
renderComponent();
expect(screen.getByText(/Confirm it's you/)).toBeInTheDocument();
expect(screen.getByText(/We've sent a verification code to/)).toBeInTheDocument();
@@ -56,14 +59,10 @@ describe('OTPVerification', () => {
).toBeInTheDocument();
expect(screen.getByRole('textbox', { name: /OTP code/ })).toBeInTheDocument();
expect(screen.getByRole('button', { name: /Resend code/ })).toBeInTheDocument();
- expect(mockSend).toHaveBeenCalled();
});
it('should render Verify your number in OTP Verification', () => {
store.ui.should_show_phone_number_otp = true;
- (useSendOTPVerificationCode as jest.Mock).mockReturnValue({
- sendPhoneOTPVerification: jest.fn(),
- });
renderComponent();
expect(screen.getByText(/Verify your number/)).toBeInTheDocument();
expect(screen.getByText(/Enter the 6-digit code sent to you via SMS at :/)).toBeInTheDocument();
@@ -71,9 +70,6 @@ describe('OTPVerification', () => {
it('should render whatsapp when phone_verification_type is whatsapp', () => {
store.ui.should_show_phone_number_otp = true;
- (useSendOTPVerificationCode as jest.Mock).mockReturnValue({
- sendPhoneOTPVerification: jest.fn(),
- });
phone_verification_type = 'whatsapp';
renderComponent();
expect(screen.getByText(/WhatsApp/)).toBeInTheDocument();
diff --git a/packages/account/src/Sections/Profile/PhoneVerification/__test__/resend-code-timer.spec.tsx b/packages/account/src/Sections/Profile/PhoneVerification/__test__/resend-code-timer.spec.tsx
index 9b835ed5cb9b..a9e5a522c2ae 100644
--- a/packages/account/src/Sections/Profile/PhoneVerification/__test__/resend-code-timer.spec.tsx
+++ b/packages/account/src/Sections/Profile/PhoneVerification/__test__/resend-code-timer.spec.tsx
@@ -1,4 +1,4 @@
-import { act, render, screen } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import userEvent from '@testing-library/user-event';
import ResendCodeTimer from '../resend-code-timer';
@@ -9,6 +9,15 @@ jest.mock('@deriv/hooks', () => ({
...jest.requireActual('@deriv/hooks'),
useVerifyEmail: jest.fn(() => ({
send: jest.fn(),
+ is_success: false,
+ })),
+ useSettings: jest.fn(() => ({
+ data: {
+ phone_number_verification: {
+ next_email_attempt: null,
+ next_attempt: null,
+ },
+ },
})),
}));
@@ -23,38 +32,38 @@ describe('ConfirmPhoneNumber', () => {
const mock_store = mockStore({});
- it('should disable button after its clicked', () => {
+ it('should disable button if timer value is given ', async () => {
render(
);
- const resend_button = screen.getByRole('button', { name: 'Resend code in 60s' });
- userEvent.click(resend_button);
+ await waitFor(() => {
+ screen.queryByRole('button', { name: 'Resend code in 59s' });
+ });
- expect(resend_button).toBeDisabled();
+ expect(screen.queryByRole('button', { name: 'Resend code in 59s' })).toBeDisabled;
});
- it('should trigger mockSend and mockSetStartTimer when send button is clicked', () => {
+ it('should trigger mockSend when send button is clicked', () => {
const mockSend = jest.fn();
(useVerifyEmail as jest.Mock).mockReturnValue({
send: mockSend,
});
- const mockSetStartTimer = jest.fn();
render(
@@ -63,139 +72,56 @@ describe('ConfirmPhoneNumber', () => {
expect(resend_button).toBeEnabled();
userEvent.click(resend_button);
- expect(mockSetStartTimer).toBeCalledWith(true);
expect(mockSend).toBeCalled();
});
- it('should display correct title if value of resend_code_text is Resend code', () => {
+ it('should display Resend code when should_show_resend_code_button is true', () => {
render(
);
- const resend_button = screen.getByRole('button', { name: 'Resend code in 60s' });
+ const resend_button = screen.getByRole('button', { name: 'Resend code' });
expect(resend_button).toBeInTheDocument();
});
- it('should display correct title if value of resend_code_text is Didn’t get the code?', () => {
+ it('should display Didn’t get the code? should_show_resend_code_button is false', () => {
render(
);
- const resend_button = screen.getByRole('button', { name: 'Didn’t get the code? (60s)' });
+ const resend_button = screen.getByRole('button', { name: "Didn't get the code?" });
expect(resend_button).toBeInTheDocument();
});
- it('should check if title changes when timer expires and value of resend_code_text is Didn’t get the code?', () => {
- render(
-
-
-
- );
- const resend_button = screen.getByRole('button', { name: 'Didn’t get the code? (6s)' });
- userEvent.click(resend_button);
-
- act(() => {
- jest.advanceTimersByTime(6000); // Advance timers by 6 seconds
- });
-
- const resend_button_after = screen.getByRole('button', { name: 'Didn’t get the code?' });
- expect(resend_button_after).toBeInTheDocument();
- });
-
it('should trigger setShouldShowDidntGetTheCodeModal when Didn`t get the code is clicked', () => {
- const setShouldShowDidntGetTheCodeModal = jest.fn();
+ const mockSetShouldShowDidntGetTheCodeModal = jest.fn();
render(
);
- const resend_button_after = screen.getByRole('button', { name: 'Didn’t get the code?' });
+ const resend_button_after = screen.getByRole('button', { name: "Didn't get the code?" });
userEvent.click(resend_button_after);
- expect(setShouldShowDidntGetTheCodeModal).toHaveBeenCalled();
- });
-
- it('should check if title displays countdown time when timer starts and value of resend_code_text is Didn’t get the code?', async () => {
- render(
-
-
-
- );
- expect(screen.getByRole('button', { name: 'Didn’t get the code? (6s)' })).toBeInTheDocument();
- jest.advanceTimersByTime(3000);
- const updated_resend_button = screen.getByRole('button', { name: 'Didn’t get the code? (4s)' });
- expect(updated_resend_button).toBeInTheDocument();
- });
-
- it('should check if title changes when timer expires and value of resend_code_text is Resend code', () => {
- render(
-
-
-
- );
- const resend_button = screen.getByRole('button', { name: 'Resend code in 6s' });
- userEvent.click(resend_button);
-
- act(() => {
- jest.advanceTimersByTime(6000);
- });
-
- const resend_button_after = screen.getByRole('button', { name: 'Resend code' });
- expect(resend_button_after).toBeInTheDocument();
- });
-
- it('should check if title displays countdown time when timer starts and value of resend_code_text is Resend code', async () => {
- render(
-
-
-
- );
- expect(screen.getByRole('button', { name: 'Resend code in 6s' })).toBeInTheDocument();
- jest.advanceTimersByTime(3000);
- const updated_resend_button = screen.getByRole('button', { name: 'Resend code in 4s' });
- expect(updated_resend_button).toBeInTheDocument();
+ expect(mockSetShouldShowDidntGetTheCodeModal).toHaveBeenCalled();
});
});
diff --git a/packages/account/src/Sections/Profile/PhoneVerification/__test__/validation.spec.tsx b/packages/account/src/Sections/Profile/PhoneVerification/__test__/validation.spec.tsx
index bf281f34f855..063634558785 100644
--- a/packages/account/src/Sections/Profile/PhoneVerification/__test__/validation.spec.tsx
+++ b/packages/account/src/Sections/Profile/PhoneVerification/__test__/validation.spec.tsx
@@ -1,11 +1,15 @@
import { act } from '@testing-library/react';
-import { validatePhoneNumber } from '../validation';
+import { otpRequestCountdown, validatePhoneNumber } from '../validation';
+import dayjs from 'dayjs';
describe('validatePhoneNumber', () => {
- let setErrorMessage: jest.Mock;
+ let setErrorMessage: jest.Mock, setTitleMock: jest.Mock, setTimerMock: jest.Mock, current_time: dayjs.Dayjs;
beforeEach(() => {
setErrorMessage = jest.fn();
+ setTitleMock = jest.fn();
+ setTimerMock = jest.fn();
+ current_time = dayjs();
});
it('should set an empty error message for a valid phone number', async () => {
@@ -55,4 +59,22 @@ describe('validatePhoneNumber', () => {
});
expect(setErrorMessage).toHaveBeenCalledWith(['Please enter a valid phone number.']);
});
+
+ it('should set title and timer correctly if next_request is greater than 0', () => {
+ const nextAttemptTimestamp = current_time.add(60, 'seconds').unix();
+
+ otpRequestCountdown(nextAttemptTimestamp, setTitleMock, setTimerMock, current_time);
+
+ expect(setTitleMock).toHaveBeenCalledWith(60);
+ expect(setTimerMock).toHaveBeenCalledWith(60);
+ });
+
+ it('should not set title and timer if next_request is less than or equal to 0', () => {
+ const nextAttemptTimestamp = current_time.subtract(60, 'seconds').unix();
+
+ otpRequestCountdown(nextAttemptTimestamp, setTitleMock, setTimerMock, current_time);
+
+ expect(setTitleMock).not.toHaveBeenCalled();
+ expect(setTimerMock).not.toHaveBeenCalled();
+ });
});
diff --git a/packages/account/src/Sections/Profile/PhoneVerification/confirm-phone-number.tsx b/packages/account/src/Sections/Profile/PhoneVerification/confirm-phone-number.tsx
index 437a9596bd7d..820f851c2ff6 100644
--- a/packages/account/src/Sections/Profile/PhoneVerification/confirm-phone-number.tsx
+++ b/packages/account/src/Sections/Profile/PhoneVerification/confirm-phone-number.tsx
@@ -13,8 +13,16 @@ type TConfirmPhoneNumber = {
const ConfirmPhoneNumber = observer(({ setOtpVerification }: TConfirmPhoneNumber) => {
const [phone_number, setPhoneNumber] = React.useState('');
- const { requestOnSMS, requestOnWhatsApp, error_message, setErrorMessage, setUsersPhoneNumber, ...rest } =
- useRequestPhoneNumberOTP();
+ const [phone_verification_type, setPhoneVerificationType] = React.useState('');
+ const {
+ requestOnSMS,
+ requestOnWhatsApp,
+ error_message,
+ setErrorMessage,
+ setUsersPhoneNumber,
+ is_email_verified,
+ ...rest
+ } = useRequestPhoneNumberOTP();
const { data: account_settings } = useSettings();
const { ui } = useStore();
const { setShouldShowPhoneNumberOTP } = ui;
@@ -23,19 +31,24 @@ const ConfirmPhoneNumber = observer(({ setOtpVerification }: TConfirmPhoneNumber
setPhoneNumber(account_settings?.phone || '');
}, [account_settings?.phone]);
+ React.useEffect(() => {
+ if (is_email_verified) {
+ setOtpVerification({ show_otp_verification: true, phone_verification_type });
+ setShouldShowPhoneNumberOTP(true);
+ }
+ }, [is_email_verified]);
+
const handleOnChangePhoneNumber = (e: React.ChangeEvent) => {
setPhoneNumber(e.target.value);
validatePhoneNumber(e.target.value, setErrorMessage);
};
const handleSubmit = async (phone_verification_type: string) => {
+ setPhoneVerificationType(phone_verification_type);
const { error } = await setUsersPhoneNumber({ phone: phone_number });
if (!error) {
phone_verification_type === VERIFICATION_SERVICES.SMS ? requestOnSMS() : requestOnWhatsApp();
- //TODOs: Add an error checking from API here before setting setOtpVerification to true
- setOtpVerification({ show_otp_verification: true, phone_verification_type });
- setShouldShowPhoneNumberOTP(true);
}
};
diff --git a/packages/account/src/Sections/Profile/PhoneVerification/didnt-get-the-code-modal.tsx b/packages/account/src/Sections/Profile/PhoneVerification/didnt-get-the-code-modal.tsx
index 9e66577e84d2..ee10b2e1577c 100644
--- a/packages/account/src/Sections/Profile/PhoneVerification/didnt-get-the-code-modal.tsx
+++ b/packages/account/src/Sections/Profile/PhoneVerification/didnt-get-the-code-modal.tsx
@@ -7,33 +7,45 @@ import { useRequestPhoneNumberOTP } from '@deriv/hooks';
import { convertPhoneTypeDisplay } from 'Helpers/utils';
type TDidntGetTheCodeModal = {
+ phone_verification_type: string;
should_show_didnt_get_the_code_modal: boolean;
+ setIsButtonDisabled: (value: boolean) => void;
setShouldShowDidntGetTheCodeModal: (value: boolean) => void;
- setStartTimer: (value: boolean) => void;
- phone_verification_type: string;
setOtpVerification: (value: { show_otp_verification: boolean; phone_verification_type: string }) => void;
+ reInitializeGetSettings: () => void;
};
const DidntGetTheCodeModal = observer(
({
should_show_didnt_get_the_code_modal,
setShouldShowDidntGetTheCodeModal,
- setStartTimer,
+ setIsButtonDisabled,
+ reInitializeGetSettings,
phone_verification_type,
setOtpVerification,
}: TDidntGetTheCodeModal) => {
- const { requestOnSMS, requestOnWhatsApp, ...rest } = useRequestPhoneNumberOTP();
+ const { requestOnSMS, requestOnWhatsApp, is_email_verified, ...rest } = useRequestPhoneNumberOTP();
const { ui } = useStore();
const { is_mobile } = ui;
+ React.useEffect(() => {
+ //TODO: will replace error_otp_error once BE error is solved
+ if (is_email_verified) reInitializeGetSettings();
+ }, [is_email_verified, reInitializeGetSettings]);
+
+ const setDidntGetACodeButtonDisabled = () => {
+ setIsButtonDisabled(true);
+ };
+
const handleResendCode = () => {
+ setDidntGetACodeButtonDisabled();
phone_verification_type === VERIFICATION_SERVICES.SMS ? requestOnSMS() : requestOnWhatsApp();
setOtpVerification({ show_otp_verification: true, phone_verification_type });
- setStartTimer(true);
setShouldShowDidntGetTheCodeModal(false);
};
const handleChangeOTPVerification = () => {
+ setDidntGetACodeButtonDisabled();
const changed_phone_verification_type =
phone_verification_type === VERIFICATION_SERVICES.SMS
? VERIFICATION_SERVICES.WHATSAPP
@@ -41,7 +53,6 @@ const DidntGetTheCodeModal = observer(
phone_verification_type === VERIFICATION_SERVICES.SMS ? requestOnWhatsApp() : requestOnSMS();
- setStartTimer(true);
setOtpVerification({
show_otp_verification: true,
phone_verification_type: changed_phone_verification_type,
diff --git a/packages/account/src/Sections/Profile/PhoneVerification/otp-verification.tsx b/packages/account/src/Sections/Profile/PhoneVerification/otp-verification.tsx
index 84dbfcc29051..69fde2664243 100644
--- a/packages/account/src/Sections/Profile/PhoneVerification/otp-verification.tsx
+++ b/packages/account/src/Sections/Profile/PhoneVerification/otp-verification.tsx
@@ -3,7 +3,7 @@ import PhoneVerificationCard from './phone-verification-card';
import { Text, InputGroupButton } from '@deriv-com/quill-ui';
import { Localize, localize } from '@deriv/translations';
import { observer, useStore } from '@deriv/stores';
-import { useSendOTPVerificationCode, useVerifyEmail } from '@deriv/hooks';
+import { useSendOTPVerificationCode, useSettings } from '@deriv/hooks';
import { convertPhoneTypeDisplay } from 'Helpers/utils';
import ResendCodeTimer from './resend-code-timer';
import DidntGetTheCodeModal from './didnt-get-the-code-modal';
@@ -16,14 +16,13 @@ type TOTPVerification = {
const OTPVerification = observer(({ phone_verification_type, setOtpVerification }: TOTPVerification) => {
const { client, ui } = useStore();
- const { account_settings, email, setVerificationCode } = client;
- const { phone } = account_settings;
+ const { setVerificationCode } = client;
+ const { data: account_settings, invalidate } = useSettings();
const [should_show_phone_number_verified_modal, setShouldShowPhoneNumberVerifiedModal] = React.useState(false);
const [should_show_didnt_get_the_code_modal, setShouldShowDidntGetTheCodeModal] = React.useState(false);
- const [start_timer, setStartTimer] = React.useState(true);
const [otp, setOtp] = React.useState('');
+ const [is_button_disabled, setIsButtonDisabled] = React.useState(false);
- const { send } = useVerifyEmail('phone_number_verification');
const {
sendPhoneOTPVerification,
phone_otp_error_message,
@@ -35,23 +34,25 @@ const OTPVerification = observer(({ phone_verification_type, setOtpVerification
//TODO: this shall be replace by BE API call when it's ready
const { should_show_phone_number_otp } = ui;
+ const reInitializeGetSettings = React.useCallback(() => {
+ invalidate('get_settings').then(() => {
+ setIsButtonDisabled(false);
+ });
+ }, [invalidate]);
+
+ React.useEffect(() => {
+ setIsButtonDisabled(true);
+ invalidate('get_settings').then(() => setIsButtonDisabled(false));
+ }, [invalidate]);
+
React.useEffect(() => {
if (is_phone_number_verified) {
setShouldShowPhoneNumberVerifiedModal(true);
} else if (is_email_verified) {
- setVerificationCode('phone_number_verification', otp);
+ setVerificationCode(otp, 'phone_number_verification');
setOtpVerification({ show_otp_verification: false, phone_verification_type: '' });
- } else if (!should_show_phone_number_otp) {
- send();
}
- }, [
- should_show_phone_number_otp,
- send,
- is_phone_number_verified,
- setShouldShowPhoneNumberVerifiedModal,
- is_email_verified,
- setOtpVerification,
- ]);
+ }, [is_phone_number_verified, is_email_verified, setOtpVerification]);
const handleGetOtpValue = (e: React.ChangeEvent) => {
setOtp(e.target.value);
@@ -74,11 +75,12 @@ const OTPVerification = observer(({ phone_verification_type, setOtpVerification
setShouldShowPhoneNumberVerifiedModal={setShouldShowPhoneNumberVerifiedModal}
/>
{should_show_phone_number_otp ? (
@@ -94,7 +96,7 @@ const OTPVerification = observer(({ phone_verification_type, setOtpVerification
i18n_default_text='Enter the 6-digit code sent to you via {{phone_verification_type}} at {{users_phone_number}}:'
values={{
phone_verification_type: localize(convertPhoneTypeDisplay(phone_verification_type)),
- users_phone_number: phone,
+ users_phone_number: account_settings?.phone,
}}
/>
@@ -103,7 +105,7 @@ const OTPVerification = observer(({ phone_verification_type, setOtpVerification
]}
/>
@@ -124,12 +126,11 @@ const OTPVerification = observer(({ phone_verification_type, setOtpVerification
maxLength={6}
/>
diff --git a/packages/account/src/Sections/Profile/PhoneVerification/resend-code-timer.tsx b/packages/account/src/Sections/Profile/PhoneVerification/resend-code-timer.tsx
index e9f67fc0fef4..20fcaeeb2682 100644
--- a/packages/account/src/Sections/Profile/PhoneVerification/resend-code-timer.tsx
+++ b/packages/account/src/Sections/Profile/PhoneVerification/resend-code-timer.tsx
@@ -1,64 +1,115 @@
import React from 'react';
import { Button, CaptionText } from '@deriv-com/quill-ui';
import { Localize } from '@deriv/translations';
-import { useVerifyEmail } from '@deriv/hooks';
+import { useSettings, useVerifyEmail } from '@deriv/hooks';
+import dayjs from 'dayjs';
+import { otpRequestCountdown } from './validation';
type TResendCodeTimer = {
- resend_code_text: string;
- count_from: number;
+ is_button_disabled: boolean;
+ should_show_resend_code_button: boolean;
+ setIsButtonDisabled: (value: boolean) => void;
setShouldShowDidntGetTheCodeModal: (value: boolean) => void;
- start_timer: boolean;
- setStartTimer: (value: boolean) => void;
+ reInitializeGetSettings: () => void;
};
const ResendCodeTimer = ({
- count_from = 60,
- resend_code_text,
+ is_button_disabled,
+ should_show_resend_code_button,
+ setIsButtonDisabled,
setShouldShowDidntGetTheCodeModal,
- start_timer,
- setStartTimer,
+ reInitializeGetSettings,
}: TResendCodeTimer) => {
- // TODO: calculate count_from and time units(secs or mins) using timestamp once mockApi is finalised
- // TODO: revist start timer logic and localizing the title
- const [timer, setTimer] = React.useState(count_from);
- const { send } = useVerifyEmail('phone_number_verification');
- const initial_timer_title =
- resend_code_text === 'Resend code' ? `Resend code in ${timer}s` : `Didn’t get the code? (${timer}s)`;
- const [timer_title, setTimerTitle] = React.useState(initial_timer_title);
+ const [timer, setTimer] = React.useState();
+ const [next_otp_request, setNextOtpRequest] = React.useState('');
+ // @ts-expect-error this for now
+ const { send, is_success } = useVerifyEmail('phone_number_verification');
+ const { data: account_settings } = useSettings();
+ const current_time = dayjs();
- const setTitle = (timer: number, text: string) => {
- const title = text === 'Resend code' ? `Resend code in ${timer}s` : `Didn’t get the code? (${timer}s)`;
- setTimerTitle(title);
- };
+ const setTitle = React.useCallback(
+ (timer: number) => {
+ let display_time: string;
+ if (timer > 60) {
+ display_time = `${Math.round(timer / 60)}m`;
+ } else {
+ display_time = `${timer}s`;
+ }
+ should_show_resend_code_button
+ ? setNextOtpRequest(` in ${display_time}`)
+ : setNextOtpRequest(` (${display_time})`);
+ },
+ [should_show_resend_code_button]
+ );
+
+ React.useEffect(() => {
+ if (is_success) reInitializeGetSettings();
+ }, [is_success, reInitializeGetSettings]);
+
+ React.useEffect(() => {
+ // @ts-expect-error this for now
+ if (should_show_resend_code_button && account_settings?.phone_number_verification?.next_email_attempt) {
+ otpRequestCountdown(
+ // @ts-expect-error this for now
+ account_settings.phone_number_verification.next_email_attempt,
+ setTitle,
+ setTimer,
+ current_time
+ );
+ // @ts-expect-error this for now
+ } else if (account_settings?.phone_number_verification?.next_attempt) {
+ otpRequestCountdown(
+ // @ts-expect-error this for now
+ account_settings.phone_number_verification.next_attempt,
+ setTitle,
+ setTimer,
+ current_time
+ );
+ }
+ }, [
+ // @ts-expect-error this for now
+ account_settings?.phone_number_verification?.next_email_attempt,
+ // @ts-expect-error this for now
+ account_settings?.phone_number_verification?.next_attempt,
+ timer,
+ setTitle,
+ should_show_resend_code_button,
+ current_time,
+ ]);
React.useEffect(() => {
let countdown: ReturnType;
- if (start_timer && timer > 0) {
+ if (timer && timer > 0) {
countdown = setInterval(() => {
- setTimer(prevTime => prevTime - 1);
- setTitle(timer, resend_code_text);
+ setTimer(timer - 1);
+ setTitle(timer);
}, 1000);
} else {
- setStartTimer(false);
- setTimerTitle(resend_code_text);
+ setNextOtpRequest('');
}
return () => clearInterval(countdown);
- }, [timer, start_timer]);
+ }, [timer, setTitle]);
const resendCode = () => {
- if (resend_code_text !== 'Resend code') {
- setShouldShowDidntGetTheCodeModal(true);
- } else {
+ if (should_show_resend_code_button) {
+ setIsButtonDisabled(true);
send();
- setTimer(count_from);
- setStartTimer(true);
+ } else {
+ setShouldShowDidntGetTheCodeModal(true);
}
};
return (
-