// components import PasswordInput from '@components/UInput/PasswordInput'; import BasicCheckbox from '@ui/BasicCheckbox'; import ResetPasswordPopup from '@components/ResetPasswordPopup'; // hooks import {useForm, Controller} from 'react-hook-form'; import {useNavigate} from 'react-router-dom'; import React, {useState} from 'react'; import styles from './styles.module.scss'; import logo_dark from '@assets/logo/logo.png'; import logo_light from '@assets/logo/logo_w.png'; // utils import classNames from 'classnames'; import {useThemeProvider} from "@contexts/themeContext"; import Spring from "@components/Spring"; import PhoneInput from "@components/UInput/PhoneInput"; import {animated,useSpring} from "@react-spring/web"; import {toast} from 'react-toastify'; import {useDispatch, useSelector} from "react-redux"; import { getAccountLogin, getChangePassStatus, getLoginStatus, getRegStatus, getSendCodeStatus, getSendCodeTS, getSMSLoginStatus } from "@features/mainSlice"; import {useLocation} from "react-router"; import {useEffect} from 'react'; import SmallLoading from "@components/SmallLoading"; import {REQ_STATUS} from "@api/config"; import {reqForgetPass, reqLogin, reqRegister, reqSendCode, reqSMSLogin} from "@features/api"; import {ROUTE_PATH} from "@constants/routes"; import {APP_THEME} from "@constants/app"; import {validateCountryPhone} from "@utils/helpers"; import {CircularProgress} from "@mui/material"; const i18n=global.i18n; const TYPE_LOGIN="login"; const TYPE_REGISTER="register"; const TYPE_FORGET_PASS="forgetPassword"; const LOGIN_TYPE_PASS=0; const LOGIN_TYPE_OTP=1; const LOGIN_TYPE_ACOUNT=2; const REG_TYPE_PHONE=0; const REG_TYPE_ACCOUNT=1; const objInfo={ cdTimer:null, inSubmit:false } const LoginForm = ({close}) => { const {theme,isMobile} = useThemeProvider(); const [showType,setShowType]=useState(TYPE_LOGIN); const [open, setOpen] = useState(false); const [country, setCountry] = useState("55"); const logourl=(theme===APP_THEME.DARK?logo_dark:logo_light); const loginStatus=useSelector(getLoginStatus); const regStatus=useSelector(getRegStatus); const forgetStatus=useSelector(getChangePassStatus); const dispatch = useDispatch(); const navigate=useNavigate(); const [loginType,setLoginType]=useState(LOGIN_TYPE_PASS); const {register, handleSubmit, formState: {errors}, control} = useForm({ defaultValues: { // country:'55', account: '', password: '', email:"", repassword:"", lang:"", code:"", phone:"", newpassword:"", renewpassword:"", acc_account:"", acc_password:"", acc_repassword:"" } }); const {pathname,hash} = useLocation(); const otpTimeStamp=useSelector(getSendCodeTS); const [otpCD,setOtpCD]=useState(-1); const otpStatus=useSelector(getSendCodeStatus); const smsLoginStatus=useSelector(getSMSLoginStatus); const isAccountLogin=useSelector(getAccountLogin); const [regType,setRegType]=useState(REG_TYPE_PHONE); const onSendCode=(e)=>{ if (otpCD>0)return; if (otpStatus===REQ_STATUS.LOADING)return; let phone=control._formValues.phone; if (phone==null||phone==="")return; let validate=validatePhone(phone); if (!validate){ control.setError("phone",true) return; } let params={phone:phone}; dispatch(reqSendCode(params)); } const getLeftCD=()=>{ let now=Date.now(); let delta=now-otpTimeStamp; delta=Math.floor(delta/1000); delta=60-delta; if (delta<0)return -1; else return delta; } const clearTimer=()=>{ if (objInfo.cdTimer!=null){ clearInterval(objInfo.cdTimer); objInfo.cdTimer=null; } } const onSubmitOTPLogin=(data)=>{ if (smsLoginStatus===REQ_STATUS.LOADING)return; data.callback=onCallback; dispatch(reqSMSLogin(data)); } useEffect(()=>{ return ()=>{ global.authLockPath=null; clearTimer(); objInfo.inSubmit=false; } },[]) useEffect(() => { if (hash===ROUTE_PATH.SIGN_IN){ setShowType(TYPE_LOGIN); } else if (hash===ROUTE_PATH.SIGN_UP){ setShowType(TYPE_REGISTER); } }, [pathname,hash]); useEffect(()=>{ let left=getLeftCD(); setOtpCD(left); clearTimer(); if (left>0){ objInfo.cdTimer=setInterval(()=>{ left=getLeftCD(); setOtpCD(left); if (left<0){ clearTimer(); } },1000) } },[otpTimeStamp]) const navigatRoute=(route)=>{ navigate(route,{replace:true}); } const onCallback=(code)=>{ // global.authLockPath=null; objInfo.inSubmit=false; if (code==200){ if (global.authLockPath!=null){ let path=global.authLockPath; global.authLockPath=null; navigate(path,{replace:true}); } else{ if (close)close(); } } } const onSubmitLogin=(data)=>{ if (loginStatus===REQ_STATUS.LOADING)return; if (objInfo.inSubmit)return; data.country=country; data.callback=onCallback; dispatch(reqLogin(data)); objInfo.inSubmit=true; } const onSubmitReg=(data)=>{ if (regStatus===REQ_STATUS.LOADING)return; if (objInfo.inSubmit)return; data.country=country; data.callback=onCallback; dispatch(reqRegister(data)); objInfo.inSubmit=true; } const onSubmitForget=(data)=>{ if (forgetStatus===REQ_STATUS.LOADING)return; if (objInfo.inSubmit)return; data.country=country; data.callback=onCallback; dispatch(reqForgetPass(data)); objInfo.inSubmit=true; } const onSubmitAccountLogin=(data)=>{ } const validatePhone=(value)=>{ return validateCountryPhone(country,value); } const renderLoading=()=>{ return () } const renderLogo=()=>{ return (
) } const renderLoginToReg=()=>{ return (
{i18n.t("login.reg_new_des")}
{ // setShowType(TYPE_REGISTER); if (isMobile()) navigatRoute(ROUTE_PATH.SIGN_UP) else setShowType(TYPE_REGISTER); }}> {i18n.t("sign_up")}
) } const renderGuestLogin=()=>{ // return ( // // ) } //login__________ const renderPassLogin = () => { return (
{ onSubmitLogin(data); })}> { let message = error ? i18n.t("form_errors.phone_" + country) : ""; return ( onChange(e.target.value)} onChangeCountry={(country) => { setCountry(country); }} placeholder={i18n.t('login.phone_ph')} innerRef={ref}/>) }} /> ( onChange(e.target.value)} placeholder={i18n.t('login.login_pwd')} innerRef={ref}/> )} />
{renderGuestLogin()} {renderLoginToReg()} ) } const renderOTPLogin=()=>{ return (
{ onSubmitOTPLogin(data); })}> { let message = error ? i18n.t("form_errors.phone_" + country) : ""; return ( onChange(e.target.value)} onChangeCountry={(country) => { setCountry(country); }} placeholder={i18n.t('login.phone_ph')} innerRef={ref}/>) }} /> { return (
onChange(e.target.value)} placeholder={i18n.t('login.otp_ph')} />
) }} /> {renderGuestLogin()} {renderLoginToReg()} ) } const renderAccountLogin=()=>{ return (
{ onSubmitAccountLogin(data); })}> { return (
onChange(e.target.value)} placeholder={i18n.t('login.account_ph')} />
{ error?(
{i18n.t('form_errors.account')}
):(<>) }
) }} /> ( onChange(e.target.value)} placeholder={i18n.t('login.login_pwd')} innerRef={ref}/> )} /> {renderGuestLogin()} {renderLoginToReg()} ) } const renderLoginType = () => { if (loginType === LOGIN_TYPE_PASS) { return renderPassLogin(); } else if (loginType === LOGIN_TYPE_OTP){ return renderOTPLogin(); } else if (loginType === LOGIN_TYPE_ACOUNT){ return renderAccountLogin(); } return (<>); } const renderLoginForm = () => { return (
{i18n.t("login.login_title")}
{ isAccountLogin?( ):(<>) }
{ // loginType===LOGIN_TYPE_PASS?renderPassLogin():renderOTPLogin() renderLoginType() }
) } //login__________ //register_______________ const renderRegToLogin=()=>{ return (
{i18n.t("login.login_des")}
{ // setShowType(TYPE_LOGIN); if (isMobile()) navigatRoute(ROUTE_PATH.SIGN_IN) else setShowType(TYPE_LOGIN); }}> {i18n.t("login.sign_in_btn")}
) } const renderRegPhone = () => { return (
{ onSubmitReg(data); })}> { let message = error ? i18n.t("form_errors.phone_" + country) : ""; return ( onChange(e.target.value)} onChangeCountry={(country) => { setCountry(country); }} placeholder={i18n.t('login.phone_ph')} innerRef={ref}/>) }} /> ( onChange(e.target.value)} placeholder={i18n.t('login.login_pwd')} innerRef={ref}/> )} /> ( onChange(e.target.value)} placeholder={i18n.t('login.re_pwd')} innerRef={ref}/> )} /> {renderRegToLogin()} ) } const renderRegAccount=()=>{ return (
{ // onSubmitReg(data); })}> { return (
onChange(e.target.value)} placeholder={i18n.t('login.account_ph')} />
{ error?(
{i18n.t('form_errors.account')}
):(<>) }
) }} /> ( onChange(e.target.value)} placeholder={i18n.t('login.login_pwd')} innerRef={ref}/> )} /> ( onChange(e.target.value)} placeholder={i18n.t('login.re_pwd')} innerRef={ref}/> )} /> {renderRegToLogin()} ) } const renderRegType=()=>{ if (regType===REG_TYPE_PHONE){ return renderRegPhone(); } else if (regType===REG_TYPE_ACCOUNT){ return renderRegAccount(); } return (<>); } const renderRegisterForm = () => { return (
{i18n.t("login.reg_title")}
{ isAccountLogin?(
):(<>) } {renderRegType()}
) } //register_______________ const renderForgetForm = () => { return (
{i18n.t("login.forget_title")}
{ onSubmitForget(data); })}> { let message = error ? i18n.t("form_errors.phone_" + country) : ""; return ( onChange(e.target.value)} onChangeCountry={(country) => { setCountry(country); }} placeholder={i18n.t('login.phone_ph')} innerRef={ref}/>) }} /> ( onChange(e.target.value)} placeholder={i18n.t('user.password.newpassword')} innerRef={ref}/> )} /> ( onChange(e.target.value)} placeholder={i18n.t('user.password.renewpassword')} innerRef={ref}/> )} /> { return (
onChange(e.target.value)} placeholder={i18n.t('login.otp_ph')} />
) }} />
{i18n.t("login.back_to_login")}
{ setShowType(TYPE_LOGIN); }}> {i18n.t("login.sign_in_btn")}
) } const renderForm = () => { let form = (<>); if (showType === TYPE_LOGIN) { form = renderLoginForm(); } else if (showType === TYPE_REGISTER) { form = renderRegisterForm(); } else if (showType === TYPE_FORGET_PASS) { form = renderForgetForm(); } return (
{form}
) } return (
{renderLogo()} {renderForm()}
) } export default LoginForm;