import { Button, Stack, TextField, Typography, Box } from '@mui/material'; import { useRef, useState, type Dispatch } from 'react'; import { useTranslation } from 'react-i18next'; import { isNumeric } from '@/utils/regexes/isNumeric'; import type { AuthFactory, AuthType } from '../../types/authTypes'; import { isEmail } from '@/utils/regexes/isEmail'; import { AuthenticationCard } from '../AuthenticationCard'; import { CountryCodeSelector } from '../CountryCodeSelector'; import type { LoginResult, UserStatus } from '../../types/userTypes'; import { getUserStatusByPhoneNumberOrEmail } from '../../api/authorizationAPI'; import type { CountryCode } from '@/types/commonTypes'; import { isPhoneNumber } from '@/utils/regexes/isValidPhoneNumber'; import { useToast } from '@rkheftan/harmony-ui'; import { useApi } from '@/hooks/useApi'; import type { GenerateTokenResponse } from '../../api/identityAPI'; import { GoogleAuthenticationV2 } from './GoogleAuthenticationV2'; import { replacePersianWithRealNumbers } from '@/utils/replacePersianWithRealNumbers'; export interface LoginRegisterFormProps { loginRegisterValue: string; setLoginRegisterValue: Dispatch; countryCode: CountryCode; setCountryCode: Dispatch; authType: AuthType; setAuthType: Dispatch; onLoginRegisterSubmit: (value: string, userStatus: UserStatus) => void; onGoogleAuthenticated: ( loginResult: LoginResult, tokenResponse: GenerateTokenResponse, ) => void; authFactory: AuthFactory; } export function LoginRegisterForm({ loginRegisterValue, setLoginRegisterValue, countryCode, setCountryCode, authType, setAuthType, onLoginRegisterSubmit, onGoogleAuthenticated, authFactory, }: LoginRegisterFormProps) { const { t } = useTranslation('authentication'); const textFieldRef = useRef(null); const inputRef = useRef(null); const [error, setError] = useState(); const [touched, setTouched] = useState(false); const inputError: boolean = touched && !!error; const toast = useToast(); const { loading: userStatusLoading, execute: execUserStatus } = useApi( getUserStatusByPhoneNumberOrEmail, ); const handleInputChange = (event: React.ChangeEvent) => { let newValue = event.target.value; newValue = replacePersianWithRealNumbers(newValue); if (newValue.startsWith('09')) { newValue = newValue.substring(1); } setLoginRegisterValue(newValue); // If the new value contains only digits (or is empty), it's a phone number if (isNumeric(newValue)) { setAuthType('phone'); } else { setAuthType('email'); } }; const handleBlur = () => { setTouched(true); validateInput(loginRegisterValue, authType); }; const validateInput = ( value: string, authType: AuthType, setErrors: boolean = true, ): boolean => { if (!value) { if (setErrors) setError(t('loginForm.thisFieldIsRequired')); return false; } if (authType === 'email' && !isEmail(value)) { if (setErrors) setError(t('loginForm.emailIsInvalid')); return false; } if (authType === 'phone' && !isPhoneNumber(countryCode, value)) { if (setErrors) setError(t('loginForm.phoneNumberIsInvalid')); return false; } if (setErrors) setError(undefined); return true; }; const handleSubmit = async () => { if (validateInput(loginRegisterValue, authType, false)) { const res = await execUserStatus({ phoneNumber: authType === 'phone' ? countryCode + loginRegisterValue : undefined, email: authType === 'email' ? loginRegisterValue : undefined, }); if (!res) { return; } if (res.success) { onLoginRegisterSubmit(loginRegisterValue, res.userStatus); } else { toast({ message: res.message, severity: 'error' }); } } else { inputRef.current?.focus(); validateInput(loginRegisterValue, authType); } }; const showAdornment = authType === 'phone' && loginRegisterValue.length > 0; return ( { e.preventDefault(); e.stopPropagation(); if (!userStatusLoading) { void handleSubmit(); } }} > {t('loginForm.title')} {t('loginForm.description')} ), }, }} sx={{ my: 4 }} /> ); }