// 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, getLoginOpen, getLoginStatus, getRegisterOpen, 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_LOGIN_TYPE, APP_THEME} from "@constants/app"; import {validateCountryPhone, validateEmail} from "@utils/helpers"; import {CircularProgress} from "@mui/material"; import area from "@db/area"; import SvgIcon from "@components/SvgIcon"; const i18n=global.i18n; const TYPE_LOGIN="login"; const TYPE_REGISTER="register"; const TYPE_FORGET_PASS="forgetPassword"; const LOGIN_TYPE_PHONE=0; const LOGIN_TYPE_SMS=1; const LOGIN_TYPE_ID=2; const LOGIN_TYPE_MAIL=3; const LOGIN_TYPE_GUEST=4; const REG_TYPE_PHONE=0; const REG_TYPE_SMS=1; const REG_TYPE_ID=2; const REG_TYPE_MAIL=3; const REG_TYPE_GUEST=4; 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_PHONE); const {register, handleSubmit, formState: {errors}, control} = useForm({ defaultValues: { // country:'55', account: '', password: '', email:"", repassword:"", lang:"", code:"", phone:"", newpassword:"", renewpassword:"" } }); 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 loginOpen=useSelector(getLoginOpen); const registerOpen=useSelector(getRegisterOpen); //登录类型列表 const [logTypeList,setLogTypeList]=useState([]); //注册类型列表 const [regTypeList,setRegTypeList]=useState([]); 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)); } const parseLogTypeList=(openType,stype)=>{ let subs=openType.split(","); let list=[]; for(let i=0;i{ return a.type-b.type; }) return list; } const getPhoneError=()=>{ if (country==="55")return i18n.t("form_errors.phone_" + country); else return i18n.t("form_errors.phone"); } //effect_______ useEffect(()=>{ return ()=>{ global.authLockPath=null; clearTimer(); objInfo.inSubmit=false; } },[]) useEffect(() => { objInfo.inSubmit=false; 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]) useEffect(()=>{ let list=parseLogTypeList(loginOpen,TYPE_LOGIN); if (list&&list.length>0){ setLogTypeList(list); setLoginType(list[0].type); } },[loginOpen]) useEffect(()=>{ let list=parseLogTypeList(registerOpen,TYPE_REGISTER); if (list&&list.length>0){ setRegTypeList(list); setRegType(list[0].type); } },[registerOpen]) //effect_______ 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 validatePhone=(value)=>{ return validateCountryPhone(country,value); } const validateMail=(value)=>{ return validateEmail(value); } const getAreaItem=()=>{ let areaID=global.getLocalAreaID(); let item=null; for (let i = 0; i < area.length; i++) { let aitem=area[i]; if (aitem.id===areaID){ item=aitem; break; } } return item; } const renderLoading=()=>{ return () } const renderLogo=()=>{ return (
) } const renderAreaSelect=()=>{ let item=getAreaItem(); if (item==null)return (<>); 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")}
{renderAreaSelect()}
) } // const renderGuestLogin = () => { // let subs=loginOpen.split(","); // let isGuest=subs.indexOf(APP_LOGIN_TYPE.GUEST)!==-1; // if (!isGuest)return (<>); // return ( // // ) // } const renderTypeTabs=(type)=>{ let list=type===TYPE_LOGIN?logTypeList:regTypeList; if (list.length<=1)return (<>); let ltype=type===TYPE_LOGIN?loginType:regType; return (
{ list.map((item,index)=>{ return ( ) }) }
) } //login__________ const renderPassLogin = () => { return (
{ data.type=APP_LOGIN_TYPE.PHONE; onSubmitLogin(data); })}> { let message = error ? getPhoneError() : ""; 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 ? getPhoneError() : ""; 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); data.type=APP_LOGIN_TYPE.ID; onSubmitLogin(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 renderMailLogin=()=>{ return (
{ // onSubmitAccountLogin(data); data.type=APP_LOGIN_TYPE.MAIL; onSubmitLogin(data); })}> { return (
onChange(e.target.value)} placeholder={i18n.t('login.mail_ph')} />
{ error?(
{i18n.t('form_errors.email')}
):(<>) }
) }} /> ( onChange(e.target.value)} placeholder={i18n.t('login.login_pwd')} innerRef={ref}/> )} /> {/*{renderGuestLogin()}*/} {renderLoginToReg()} ) } const renderGuestLogin=()=>{ return (
{ // onSubmitAccountLogin(data); data.type=APP_LOGIN_TYPE.GUEST; onSubmitLogin(data); })}> {renderLoginToReg()}
) } const renderLoginType = () => { control._names.mount.clear(); if (loginType === LOGIN_TYPE_PHONE) { return renderPassLogin(); } else if (loginType === LOGIN_TYPE_SMS){ return renderOTPLogin(); } else if (loginType === LOGIN_TYPE_ID){ return renderAccountLogin(); } else if (loginType ===LOGIN_TYPE_MAIL){ return renderMailLogin(); } else if (loginType === LOGIN_TYPE_GUEST){ return renderGuestLogin(); } return (<>); } const renderLoginForm = () => { return (
{i18n.t("login.login_title")}
{renderTypeTabs(TYPE_LOGIN)} { // 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")}
{renderAreaSelect()}
) } // const renderGuestReg = () => { // let subs=registerOpen.split(","); // let isGuest=subs.indexOf(APP_LOGIN_TYPE.GUEST)!==-1; // if (!isGuest)return (<>); // return ( // // ) // } const renderRegPhone = () => { return (
{ data.type=APP_LOGIN_TYPE.PHONE; onSubmitReg(data); })}> { let message = error ? getPhoneError() : ""; 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}/> )} /> {/*{renderGuestReg()}*/} {renderRegToLogin()} ) } const renderRegAccount=()=>{ return (
{ // onSubmitReg(data); // onSubmitAccountReg(data); data.type=APP_LOGIN_TYPE.ID; 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}/> )} /> {/*{renderGuestReg()}*/} {renderRegToLogin()} ) } const renderRegSms=()=>{ return (
{ data.type=APP_LOGIN_TYPE.SMS; onSubmitReg(data); })}> { let message = error ? getPhoneError() : ""; 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}/> )} /> { return (
onChange(e.target.value)} placeholder={i18n.t('login.otp_ph')} />
) }} /> {/*{renderGuestReg()}*/} {renderRegToLogin()} ) } const renderRegMail=()=>{ return (
{ // onSubmitReg(data); // onSubmitAccountReg(data); data.type=APP_LOGIN_TYPE.MAIL; onSubmitReg(data); })}> { return (
onChange(e.target.value)} placeholder={i18n.t('login.mail_ph')} />
{ error?(
{i18n.t('form_errors.email')}
):(<>) }
) }} /> ( onChange(e.target.value)} placeholder={i18n.t('login.login_pwd')} innerRef={ref}/> )} /> ( onChange(e.target.value)} placeholder={i18n.t('login.re_pwd')} innerRef={ref}/> )} /> {/*{renderGuestReg()}*/} {renderRegToLogin()} ) } const renderRegGuest=()=>{ return (
{ data.type=APP_LOGIN_TYPE.GUEST; onSubmitReg(data); })}> {renderRegToLogin()}
) } const renderRegType=()=>{ control._names.mount.clear(); if (regType===REG_TYPE_PHONE){ return renderRegPhone(); } else if (regType===REG_TYPE_ID){ return renderRegAccount(); } else if (regType===REG_TYPE_SMS){ return renderRegSms(); } else if(regType===REG_TYPE_MAIL){ return renderRegMail(); } else if (regType===REG_TYPE_GUEST){ return renderRegGuest(); } return (<>); } const renderRegisterForm = () => { return (
{i18n.t("login.reg_title")}
{renderTypeTabs(TYPE_REGISTER)} {renderRegType()}
) } //register_______________ const renderForgetForm = () => { return (
{i18n.t("login.forget_title")}
{ onSubmitForget(data); })}> { let message = error ? getPhoneError() : ""; 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;