import { useMemo, useState, type JSX } from 'react'; import { LoginRegisterForm } from './LoginRegiserForm'; import type { AuthFactory, AuthMode, AuthStep, AuthType, } from '../../types/authTypes'; import { OtpVerifyForm } from './OtpVerifyForm'; import { isNumeric } from '@/utils/regexes/isNumeric'; import { CompleteSignUp } from './CompleteSignUp'; import { EnterPasswordForm } from './EnterPasswordForm'; import { UserStatus, type LoginResult } from '../../types/userTypes'; import type { CountryCode } from '@/types/commonTypes'; import { VerifyPhoneNumber } from './VerifyPhoneNumber'; import { useNavigate, useSearchParams } from 'react-router-dom'; import type { GenerateTokenResponse } from '../../api/identityAPI'; import { useAuth } from '@/hooks/useAuth'; export const AuthenticationSteps = (): JSX.Element => { const navigate = useNavigate(); const [searchParams] = useSearchParams(); const [authMode, setAuthMode] = useState('register'); const [authType, setAuthType] = useState('phone'); const [currentStep, setCurrentStep] = useState('emailOrPhone'); const [loginRegisterValue, setLoginRegisterValue] = useState(''); const [countryCode, setCountryCode] = useState('+98'); const [addPhoneCountryCode, setAddPhoneCountryCode] = useState('+98'); const [addedPhoneNumberValue, setAddedPhoneNumberValue] = useState(''); const [memoryTokenRes, setMemoryTokenRes] = useState(); const [hasPassword, setHasPassword] = useState(false); const { login } = useAuth(); const authFactory: AuthFactory = useMemo(() => { const redirectUrl = searchParams.get('redirect_url'); const clientId = searchParams.get('client_id'); if (!clientId) { const defaultFactory: AuthFactory = { clientId: import.meta.env.VITE_IDENTITY_CLIENT_ID, redirectUrl: import.meta.env.VITE_APP_URL, isCurrentApplication: function () { return this.clientId === import.meta.env.VITE_IDENTITY_CLIENT_ID; }, getFullRedirectUrl: function (token: string) { return this.redirectUrl + '?token=' + token; }, }; return defaultFactory; } const resFactory: AuthFactory = { clientId: clientId, redirectUrl: redirectUrl as string, isCurrentApplication: function () { return this.clientId === import.meta.env.VITE_IDENTITY_CLIENT_ID; }, getFullRedirectUrl: function (token: string) { return this.redirectUrl + '?token=' + token; }, }; return resFactory; }, [searchParams]); const handleLoginRegister = (value: string, userStatus: UserStatus) => { setAuthType(isNumeric(value) ? 'phone' : 'email'); switch (userStatus) { case UserStatus.NotRegistered: setAuthMode('register'); setCurrentStep('verify'); break; case UserStatus.RegisteredWithoutPassword: setAuthMode('login'); setCurrentStep('verify'); break; case UserStatus.RegisteredWithPassword: setAuthMode('login'); setCurrentStep('enterPassword'); setHasPassword(true); break; } }; const handleUserLoggedIn = ( loginResult: LoginResult, tokenResponse: GenerateTokenResponse, ) => { setMemoryTokenRes(tokenResponse); // TODO: For now both application scopes can have their tokens // later we need to discuss this base on business plan and change it // if (authFactory.isCurrentApplication()) {} login(tokenResponse); if (loginResult.registeredWithOutPhoneNumber) { setCurrentStep('addPhoneNumber'); return; } if (!loginResult.completedUserInformation) { if (!authFactory.isCurrentApplication()) { navigate( `/signup?returnUrl=${authFactory.getFullRedirectUrl(tokenResponse.refresh_token)}`, ); } else { navigate(`/signup`); } return; } redirectToReturnUrl(tokenResponse.refresh_token); }; const handlePhoneNumberVerified = () => { if (!authFactory.isCurrentApplication()) { navigate( `/signup?returnUrl=${authFactory.getFullRedirectUrl(memoryTokenRes?.refresh_token as string)}`, ); } else { navigate(`/signup`); } }; const redirectToReturnUrl = (refreshToken: string) => { if (authFactory.isCurrentApplication()) { navigate(import.meta.env.VITE_DEFUALT_AUTH_RETURN_URL); } else { if (authMode === 'register') { navigate( `/account-created?returnUrl=${authFactory.getFullRedirectUrl(refreshToken)}`, ); } else { location.href = authFactory.getFullRedirectUrl(refreshToken); } } }; return ( <> {currentStep === 'emailOrPhone' && ( )} {currentStep === 'verify' && ( setCurrentStep('emailOrPhone')} authMode={authMode} authType={authType} value={loginRegisterValue} hasPassword={hasPassword} onLoginWithPassword={() => setCurrentStep('enterPassword')} /> )} {currentStep === 'enterPassword' && ( setCurrentStep('emailOrPhone')} onLoginWithOTP={() => setCurrentStep('verify')} emailOrPhone={loginRegisterValue} /> )} {currentStep === 'addPhoneNumber' && ( setCurrentStep('addedPhoneNumberVerify')} /> )} {currentStep === 'addedPhoneNumberVerify' && ( setCurrentStep('addPhoneNumber')} value={addedPhoneNumberValue} onPhoneNumberVerified={handlePhoneNumberVerified} /> )} ); };