167 lines
4.9 KiB
TypeScript
167 lines
4.9 KiB
TypeScript
import { Box, Button, TextField, Typography } from '@mui/material';
|
|
import parsePhoneNumberFromString from 'libphonenumber-js';
|
|
import { useRef, useState, type ChangeEvent, type Dispatch } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { AuthenticationCard } from '../AuthenticationCard';
|
|
import { CountryCodeSelector } from '../../../../components/CountryCodeSelector';
|
|
import {
|
|
sendSmsCodeCompleteUserInforamation,
|
|
sendSmsOtp,
|
|
} from '../../api/authorizationAPI';
|
|
import type { CountryCode } from '@/types/commonTypes';
|
|
import { useApi } from '@/hooks/useApi';
|
|
import { replacePersianWithRealNumbers } from '@/utils/replacePersianWithRealNumbers';
|
|
import { useToast } from '@rkheftan/harmony-ui';
|
|
|
|
export interface CompleteSignUpProps {
|
|
email: string;
|
|
value: string;
|
|
setValue: Dispatch<string>;
|
|
countryCode: CountryCode;
|
|
setCountryCode: Dispatch<CountryCode>;
|
|
onCompleteSignUp: (countryCode: string, value: string) => void;
|
|
setTimerValue: Dispatch<number>;
|
|
}
|
|
|
|
export const CompleteSignUp = ({
|
|
email,
|
|
value,
|
|
setValue,
|
|
countryCode,
|
|
setCountryCode,
|
|
onCompleteSignUp,
|
|
setTimerValue,
|
|
}: CompleteSignUpProps) => {
|
|
const { t, i18n } = useTranslation('authentication');
|
|
const [error, setError] = useState<string>();
|
|
const textFieldRef = useRef<HTMLDivElement>(null);
|
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
const [touched, setTouched] = useState<boolean>(false);
|
|
const inputError: boolean = touched && !!error;
|
|
const { loading: sendSmsLoading, execute: sendSmsCall } = useApi(
|
|
sendSmsCodeCompleteUserInforamation,
|
|
);
|
|
const toast = useToast();
|
|
|
|
const isPhoneValid = (code: string, phone: string) => {
|
|
const phoneNumber = parsePhoneNumberFromString(code + phone);
|
|
|
|
return phoneNumber && phoneNumber.isValid();
|
|
};
|
|
|
|
const handleBlur = () => {
|
|
setTouched(true);
|
|
|
|
handleValueError();
|
|
};
|
|
|
|
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
const value = replacePersianWithRealNumbers(event.target.value);
|
|
|
|
setValue(value);
|
|
};
|
|
|
|
const handleValueError = () => {
|
|
if (!value) {
|
|
setError(t('loginForm.thisFieldIsRequired'));
|
|
}
|
|
if (!isPhoneValid(countryCode, value)) {
|
|
setError(t('loginForm.phoneNumberIsInvalid'));
|
|
} else {
|
|
setError(undefined);
|
|
}
|
|
};
|
|
|
|
const handleCompleteSignUp = async () => {
|
|
handleValueError();
|
|
|
|
if (!value || !isPhoneValid(countryCode, value)) {
|
|
inputRef.current?.focus();
|
|
} else {
|
|
let newValue = value;
|
|
if (countryCode === '+98' && newValue.startsWith('09')) {
|
|
newValue = newValue.substring(1);
|
|
setValue(newValue);
|
|
}
|
|
const res = await sendSmsCall({ phoneNumber: countryCode + newValue });
|
|
|
|
if (!res) return;
|
|
|
|
if (res.success) {
|
|
onCompleteSignUp(countryCode, newValue);
|
|
setTimerValue(res.totalSecondForCodeToExpire);
|
|
} else {
|
|
toast({
|
|
message: res.message,
|
|
severity: 'error',
|
|
});
|
|
setError(res.message);
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<AuthenticationCard>
|
|
<Box
|
|
component="form"
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
if (!sendSmsLoading) void handleCompleteSignUp();
|
|
}}
|
|
>
|
|
<Typography variant="h5" sx={{ mb: 0.5 }}>
|
|
{t('completeSignUp.completeSignUp')}
|
|
</Typography>
|
|
|
|
<Typography variant="body2" color="textSecondary" sx={{ mt: 1, mb: 2 }}>
|
|
{t(
|
|
'completeSignUp.emailHasBeenSuccessfullyVerifiedPleaseEnterYourContactNumberToContinue',
|
|
{ email },
|
|
)}
|
|
</Typography>
|
|
|
|
<TextField
|
|
ref={textFieldRef}
|
|
inputRef={inputRef}
|
|
label={t('completeSignUp.phoneNumber')}
|
|
value={value}
|
|
onChange={handleChange}
|
|
onBlur={handleBlur}
|
|
error={inputError}
|
|
helperText={inputError ? error : ''}
|
|
autoFocus
|
|
slotProps={{
|
|
htmlInput: { dir: 'auto', sx: { lineHeight: 1.5 } },
|
|
input: {
|
|
endAdornment: i18n.dir() === 'rtl' && (
|
|
<CountryCodeSelector
|
|
value={countryCode}
|
|
onChange={setCountryCode}
|
|
show={true}
|
|
menuAnchor={textFieldRef.current}
|
|
onCloseFocusRef={inputRef}
|
|
/>
|
|
),
|
|
startAdornment: i18n.dir() === 'ltr' && (
|
|
<CountryCodeSelector
|
|
value={countryCode}
|
|
onChange={setCountryCode}
|
|
show={true}
|
|
menuAnchor={textFieldRef.current}
|
|
onCloseFocusRef={inputRef}
|
|
/>
|
|
),
|
|
},
|
|
}}
|
|
sx={{ my: 4 }}
|
|
/>
|
|
|
|
<Button loading={sendSmsLoading} type="submit">
|
|
{t('verify.confirmAndContinue')}
|
|
</Button>
|
|
</Box>
|
|
</AuthenticationCard>
|
|
);
|
|
};
|