feat: complete sign up form added
This commit is contained in:
@@ -17,7 +17,11 @@
|
|||||||
"theVerificationCodeIsIncorrect": "The verification code is incorrect.",
|
"theVerificationCodeIsIncorrect": "The verification code is incorrect.",
|
||||||
"youHaveSuccessfullyLoggedIn": "You have successfully logged in",
|
"youHaveSuccessfullyLoggedIn": "You have successfully logged in",
|
||||||
"youHaveSuccessfullySignedIn": "You have successfully signed in"
|
"youHaveSuccessfullySignedIn": "You have successfully signed in"
|
||||||
|
},
|
||||||
|
"completeSignUp": {
|
||||||
|
"completeSignUp": "Complete Sign Up",
|
||||||
|
"emailHasBeenSuccessfullyVerifiedPleaseEnterYourContactNumberToContinue": "Email {{ email }} has been successfully verified. Please enter your contact number to continue.",
|
||||||
|
"phoneNumber": "Phone number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,5 +20,10 @@
|
|||||||
"theVerificationCodeIsIncorrect": "کد تایید اشتباه می باشد",
|
"theVerificationCodeIsIncorrect": "کد تایید اشتباه می باشد",
|
||||||
"youHaveSuccessfullyLoggedIn": "با موفقیت وارد شدید",
|
"youHaveSuccessfullyLoggedIn": "با موفقیت وارد شدید",
|
||||||
"youHaveSuccessfullySignedIn": "ثبت نام با موفقیت انجام شد"
|
"youHaveSuccessfullySignedIn": "ثبت نام با موفقیت انجام شد"
|
||||||
|
},
|
||||||
|
"completeSignUp": {
|
||||||
|
"completeSignUp": "تکمیل ثبت نام",
|
||||||
|
"emailHasBeenSuccessfullyVerifiedPleaseEnterYourContactNumberToContinue": "ایمیل {{ email }} با موفقیت تایید شد. برای ادامه لطفا شماره تماس خود را وارد کنید",
|
||||||
|
"phoneNumber": "شماره تماس"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,21 @@ import { LoginRegisterForm } from './LoginRegiserForm';
|
|||||||
import type { AuthMode, AuthType } from '../types/auth-types';
|
import type { AuthMode, AuthType } from '../types/auth-types';
|
||||||
import { OtpVerifyForm } from './OtpVerifyForm';
|
import { OtpVerifyForm } from './OtpVerifyForm';
|
||||||
import { isNumeric } from '@/utils/regexes/isNumeric';
|
import { isNumeric } from '@/utils/regexes/isNumeric';
|
||||||
|
import { CompleteSignUp } from './CompleteSignUp';
|
||||||
|
|
||||||
export const AuthenticationContainer = (): JSX.Element => {
|
export const AuthenticationContainer = (): JSX.Element => {
|
||||||
const [authMode, setAuthMode] = useState<AuthMode>('login');
|
const [authMode, setAuthMode] = useState<AuthMode>('register');
|
||||||
const [authType, setAuthType] = useState<AuthType>('phone');
|
const [authType, setAuthType] = useState<AuthType>('phone');
|
||||||
const [currentStep, setCurrentStep] = useState<
|
const [currentStep, setCurrentStep] = useState<
|
||||||
'emailOrPassword' | 'verify' | 'enterPassword' | 'addPhoneNumber'
|
| 'emailOrPassword'
|
||||||
|
| 'verify'
|
||||||
|
| 'enterPassword'
|
||||||
|
| 'addPhoneNumber'
|
||||||
|
| 'addedPhoneNumberVerify'
|
||||||
>('emailOrPassword');
|
>('emailOrPassword');
|
||||||
const [loginRegisterValue, setLoginRegisterValue] = useState<string>('');
|
const [loginRegisterValue, setLoginRegisterValue] = useState<string>('');
|
||||||
|
const [addedPhoneNumberValue, setAddedPhoneNumberValue] =
|
||||||
|
useState<string>('');
|
||||||
|
|
||||||
const handleLoginRegister = (value: string) => {
|
const handleLoginRegister = (value: string) => {
|
||||||
setLoginRegisterValue(value);
|
setLoginRegisterValue(value);
|
||||||
@@ -19,8 +26,6 @@ export const AuthenticationContainer = (): JSX.Element => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleOTPVerfied = (otpCode: string) => {
|
const handleOTPVerfied = (otpCode: string) => {
|
||||||
console.log(otpCode);
|
|
||||||
|
|
||||||
if (authMode === 'register' && authType === 'email') {
|
if (authMode === 'register' && authType === 'email') {
|
||||||
setAuthType('phone');
|
setAuthType('phone');
|
||||||
setCurrentStep('addPhoneNumber');
|
setCurrentStep('addPhoneNumber');
|
||||||
@@ -31,6 +36,18 @@ export const AuthenticationContainer = (): JSX.Element => {
|
|||||||
setCurrentStep('emailOrPassword');
|
setCurrentStep('emailOrPassword');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCompleteSignUp = (countryCode: string, value: string) => {
|
||||||
|
setCurrentStep('addedPhoneNumberVerify');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCompleteSignUpOTPVerified = (otpCode: string) => {
|
||||||
|
console.log(otpCode);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCompleteSignUpEditValue = () => {
|
||||||
|
setCurrentStep('addPhoneNumber');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{currentStep === 'emailOrPassword' && (
|
{currentStep === 'emailOrPassword' && (
|
||||||
@@ -52,6 +69,25 @@ export const AuthenticationContainer = (): JSX.Element => {
|
|||||||
value={loginRegisterValue}
|
value={loginRegisterValue}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{currentStep === 'addPhoneNumber' && (
|
||||||
|
<CompleteSignUp
|
||||||
|
value={addedPhoneNumberValue}
|
||||||
|
setValue={setAddedPhoneNumberValue}
|
||||||
|
email={loginRegisterValue}
|
||||||
|
onCompleteSignUp={handleCompleteSignUp}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{currentStep === 'addedPhoneNumberVerify' && (
|
||||||
|
<OtpVerifyForm
|
||||||
|
onOTPVerified={handleCompleteSignUpOTPVerified}
|
||||||
|
onEditValue={handleCompleteSignUpEditValue}
|
||||||
|
authMode="register"
|
||||||
|
authType="phone"
|
||||||
|
value={addedPhoneNumberValue}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
106
src/features/authentication/components/CompleteSignUp.tsx
Normal file
106
src/features/authentication/components/CompleteSignUp.tsx
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import { Box, Button, 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';
|
||||||
|
|
||||||
|
export interface CompleteSignUpProps {
|
||||||
|
email: string;
|
||||||
|
value: string;
|
||||||
|
setValue: Dispatch<string>;
|
||||||
|
onCompleteSignUp: (countryCode: string, value: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CompleteSignUp = ({
|
||||||
|
email,
|
||||||
|
value,
|
||||||
|
setValue,
|
||||||
|
onCompleteSignUp,
|
||||||
|
}: CompleteSignUpProps) => {
|
||||||
|
const { t } = useTranslation('authentication');
|
||||||
|
const [countryCode, setCountryCode] = useState('+98');
|
||||||
|
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 isPhoneValid = (code: string, phone: string) => {
|
||||||
|
const phoneNumber = parsePhoneNumberFromString(code + phone);
|
||||||
|
|
||||||
|
return phoneNumber && phoneNumber.isValid();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
setTouched(true);
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
setError(t('loginForm.thisFieldIsRequired'));
|
||||||
|
}
|
||||||
|
if (!isPhoneValid(countryCode, value)) {
|
||||||
|
setError(t('loginForm.phoneNumberIsInvalid'));
|
||||||
|
} else {
|
||||||
|
setError(undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCompleteSignUp = () => {
|
||||||
|
if (!value) {
|
||||||
|
setError(t('loginForm.thisFieldIsRequired'));
|
||||||
|
inputRef.current?.focus();
|
||||||
|
}
|
||||||
|
if (!isPhoneValid(countryCode, value)) {
|
||||||
|
setError(t('loginForm.phoneNumberIsInvalid'));
|
||||||
|
inputRef.current?.focus();
|
||||||
|
} else {
|
||||||
|
setError(undefined);
|
||||||
|
onCompleteSignUp(countryCode, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<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={(e) => setValue(e.target.value)}
|
||||||
|
onBlur={handleBlur}
|
||||||
|
error={inputError}
|
||||||
|
helperText={inputError ? error : ''}
|
||||||
|
autoFocus
|
||||||
|
slotProps={{
|
||||||
|
htmlInput: { dir: 'auto', sx: { lineHeight: 1.5, paddingX: 0 } },
|
||||||
|
input: {
|
||||||
|
endAdornment: (
|
||||||
|
<CountryCodeSelector
|
||||||
|
value={countryCode}
|
||||||
|
onChange={setCountryCode}
|
||||||
|
show={true}
|
||||||
|
menuAnchor={textFieldRef.current}
|
||||||
|
onCloseFocusRef={inputRef}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
sx={{ my: 4 }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button onClick={handleCompleteSignUp}>
|
||||||
|
{t('verify.confirmAndContinue')}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -46,7 +46,7 @@ export const CustomThemeProvider: React.FC<{ children: React.ReactNode }> = ({
|
|||||||
}, [i18n]);
|
}, [i18n]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme} defaultMode="system">
|
<ThemeProvider theme={theme} defaultMode="light">
|
||||||
{children}
|
{children}
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user