multiple messages for phone login and signup added
This commit is contained in:
@@ -7,6 +7,11 @@
|
|||||||
"loginWithGoogle": "Login with google",
|
"loginWithGoogle": "Login with google",
|
||||||
"emailIsInvalid": "Email is invalid",
|
"emailIsInvalid": "Email is invalid",
|
||||||
"phoneNumberIsInvalid": "Phone number is invalid",
|
"phoneNumberIsInvalid": "Phone number is invalid",
|
||||||
"thisFieldIsRequired": "This field is requried"
|
"thisFieldIsRequired": "This field is requried",
|
||||||
|
"verify": {
|
||||||
|
"verify": "Verify",
|
||||||
|
"a4DigitVerificationCodeHasBeenSentToYourBobileNumberPleaseEnterIt": "A 4-digit verification code has been sent to your mobile number. Please enter it.",
|
||||||
|
"thereIsNoAccountWithThisNumberA4DigitVerificationCodeHasBeenSentToThisNumberToCreateANewAccount": "There is no account with this number. A 4-digit verification code has been sent to this number to create a new account."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,12 @@
|
|||||||
"emailIsInvalid": "ایمیل وارد شده نامعتبر میباشد",
|
"emailIsInvalid": "ایمیل وارد شده نامعتبر میباشد",
|
||||||
"phoneNumberIsInvalid": "شماره وارد شده نامعتبر میباشد",
|
"phoneNumberIsInvalid": "شماره وارد شده نامعتبر میباشد",
|
||||||
"thisFieldIsRequired": "این فیلد الزامی است"
|
"thisFieldIsRequired": "این فیلد الزامی است"
|
||||||
|
},
|
||||||
|
"verify": {
|
||||||
|
"verify": "اعتبارسنجی",
|
||||||
|
"a4DigitVerificationCodeHasBeenSentToYourBobileNumberPleaseEnterIt": "کد تایید ۴ رقمی به شماره موبایل شما ارسال شد. لطفا آن را وارد کنید.",
|
||||||
|
"confirmAndLogin": "تایید و ورود",
|
||||||
|
"confirmAndContinue": "تایید و ادامه",
|
||||||
|
"thereIsNoAccountWithThisNumberA4DigitVerificationCodeHasBeenSentToThisNumberToCreateANewAccount": "حساب کاربری با این شماره وجود ندارد. برای ساخت حساب جدید، کد تایید ۴ رقمی برای این شماره ارسال گردید."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,46 @@
|
|||||||
import React, { useState, type JSX } from 'react';
|
import React, { useState, type JSX } from 'react';
|
||||||
import { LoginRegisterForm } from './LoginRegiserForm';
|
import { LoginRegisterForm } from './LoginRegiserForm';
|
||||||
import type { AuthMode, AuthType } from '../types/auth-types';
|
import type { AuthMode, AuthType } from '../types/auth-types';
|
||||||
|
import { OtpVerifyForm } from './OtpVerifyForm';
|
||||||
|
|
||||||
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'
|
'emailOrPassword' | 'verify' | 'enterPassword'
|
||||||
>('emailOrPassword');
|
>('verify');
|
||||||
|
const [loginRegisterValue, setLoginRegisterValue] =
|
||||||
|
useState<string>('9152814093');
|
||||||
|
|
||||||
const handleLoginRegister = (value: string) => {};
|
const handleLoginRegister = (value: string) => {
|
||||||
|
setLoginRegisterValue(value);
|
||||||
|
setCurrentStep('verify');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditValue = () => {
|
||||||
|
setCurrentStep('emailOrPassword');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{currentStep === 'emailOrPassword' && (
|
{currentStep === 'emailOrPassword' && (
|
||||||
<LoginRegisterForm
|
<LoginRegisterForm
|
||||||
|
loginRegisterValue={loginRegisterValue}
|
||||||
|
setLoginRegisterValue={setLoginRegisterValue}
|
||||||
authType={authType}
|
authType={authType}
|
||||||
setAuthType={setAuthType}
|
setAuthType={setAuthType}
|
||||||
onLoginRegisterSubmit={handleLoginRegister}
|
onLoginRegisterSubmit={handleLoginRegister}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{currentStep === 'verify' && (
|
||||||
|
<OtpVerifyForm
|
||||||
|
onEditValue={handleEditValue}
|
||||||
|
authMode={authMode}
|
||||||
|
authType={authType}
|
||||||
|
value={loginRegisterValue}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,17 +9,21 @@ import { isEmail } from '@/utils/regexes/isEmail';
|
|||||||
import parsePhoneNumberFromString from 'libphonenumber-js';
|
import parsePhoneNumberFromString from 'libphonenumber-js';
|
||||||
|
|
||||||
export interface LoginRegisterFormProps {
|
export interface LoginRegisterFormProps {
|
||||||
|
loginRegisterValue: string;
|
||||||
|
setLoginRegisterValue: Dispatch<string>;
|
||||||
authType: AuthType;
|
authType: AuthType;
|
||||||
setAuthType: Dispatch<AuthType>;
|
setAuthType: Dispatch<AuthType>;
|
||||||
onLoginRegisterSubmit: (value: string) => void;
|
onLoginRegisterSubmit: (value: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function LoginRegisterForm({
|
export function LoginRegisterForm({
|
||||||
|
loginRegisterValue,
|
||||||
|
setLoginRegisterValue,
|
||||||
authType,
|
authType,
|
||||||
setAuthType,
|
setAuthType,
|
||||||
|
onLoginRegisterSubmit,
|
||||||
}: LoginRegisterFormProps) {
|
}: LoginRegisterFormProps) {
|
||||||
const { t, i18n } = useTranslation('authentication');
|
const { t, i18n } = useTranslation('authentication');
|
||||||
const [value, setValue] = useState('');
|
|
||||||
const [countryCode, setCountryCode] = useState('+98');
|
const [countryCode, setCountryCode] = useState('+98');
|
||||||
const textFieldRef = useRef<HTMLDivElement>(null);
|
const textFieldRef = useRef<HTMLDivElement>(null);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
@@ -30,7 +34,7 @@ export function LoginRegisterForm({
|
|||||||
|
|
||||||
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const newValue = event.target.value;
|
const newValue = event.target.value;
|
||||||
setValue(newValue);
|
setLoginRegisterValue(newValue);
|
||||||
|
|
||||||
// If the new value contains only digits (or is empty), it's a phone number
|
// If the new value contains only digits (or is empty), it's a phone number
|
||||||
if (isNumeric(newValue)) {
|
if (isNumeric(newValue)) {
|
||||||
@@ -42,7 +46,7 @@ export function LoginRegisterForm({
|
|||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
setTouched(true);
|
setTouched(true);
|
||||||
validateInput(value, authType);
|
validateInput(loginRegisterValue, authType);
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateInput = (value: string, authType: AuthType) => {
|
const validateInput = (value: string, authType: AuthType) => {
|
||||||
@@ -80,14 +84,15 @@ export function LoginRegisterForm({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
if (isInputValid(value, authType)) {
|
if (isInputValid(loginRegisterValue, authType)) {
|
||||||
|
onLoginRegisterSubmit(loginRegisterValue);
|
||||||
} else {
|
} else {
|
||||||
inputRef.current?.focus();
|
inputRef.current?.focus();
|
||||||
validateInput(value, authType);
|
validateInput(loginRegisterValue, authType);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showAdornment = authType === 'phone' && value.length > 0;
|
const showAdornment = authType === 'phone' && loginRegisterValue.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
@@ -102,7 +107,7 @@ export function LoginRegisterForm({
|
|||||||
ref={textFieldRef}
|
ref={textFieldRef}
|
||||||
inputRef={inputRef}
|
inputRef={inputRef}
|
||||||
label={t('loginForm.emailOrPhoneLabel')}
|
label={t('loginForm.emailOrPhoneLabel')}
|
||||||
value={value}
|
value={loginRegisterValue}
|
||||||
onChange={handleInputChange}
|
onChange={handleInputChange}
|
||||||
onBlur={handleBlur}
|
onBlur={handleBlur}
|
||||||
error={inputError}
|
error={inputError}
|
||||||
|
|||||||
73
src/features/authentication/components/OtpVerifyForm.tsx
Normal file
73
src/features/authentication/components/OtpVerifyForm.tsx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Box, Button, Typography } from '@mui/material';
|
||||||
|
import { Edit2 } from 'iconsax-reactjs';
|
||||||
|
import DigitInput from '@/components/components/DigitsInput';
|
||||||
|
import type { AuthMode, AuthType } from '../types/auth-types';
|
||||||
|
|
||||||
|
interface OtpVerifyFormProps {
|
||||||
|
value: string;
|
||||||
|
authType: AuthType;
|
||||||
|
authMode: AuthMode;
|
||||||
|
onEditValue: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function OtpVerifyForm({
|
||||||
|
value,
|
||||||
|
authType,
|
||||||
|
authMode,
|
||||||
|
onEditValue,
|
||||||
|
}: OtpVerifyFormProps) {
|
||||||
|
const { t } = useTranslation('authentication');
|
||||||
|
|
||||||
|
const otpMessage = (): string => {
|
||||||
|
if (authType === 'phone' && authMode === 'login') {
|
||||||
|
return t(
|
||||||
|
'verify.a4DigitVerificationCodeHasBeenSentToYourBobileNumberPleaseEnterIt',
|
||||||
|
);
|
||||||
|
} else if (authType === 'phone' && authMode === 'register') {
|
||||||
|
return t(
|
||||||
|
'verify.thereIsNoAccountWithThisNumberA4DigitVerificationCodeHasBeenSentToThisNumberToCreateANewAccount',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
gap: 4,
|
||||||
|
mb: 0.5,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h5">{t('verify.verify')}</Typography>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
size="large"
|
||||||
|
sx={{ textTransform: 'lowercase', width: 'auto' }}
|
||||||
|
endIcon={<Edit2 />}
|
||||||
|
onClick={onEditValue}
|
||||||
|
>
|
||||||
|
{value}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Typography variant="body2" color="textSecondary" sx={{ mt: 1 }}>
|
||||||
|
{otpMessage()}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<DigitInput onChange={(value) => console.log(value)} />
|
||||||
|
<Button>
|
||||||
|
{authMode === 'register'
|
||||||
|
? t('verify.confirmAndContinue')
|
||||||
|
: t('verify.confirmAndLogin')}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ export function SmsOtpForm({ value, type }: SmsOtpProps) {
|
|||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
gap: 4,
|
gap: 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user