|
|
@@ -0,0 +1,229 @@
|
|
|
+// 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 {getLoginStatus, getRegStatus} from "@features/mainSlice";
|
|
|
+import {useLocation} from "react-router";
|
|
|
+import {useEffect} from 'react';
|
|
|
+import SmallLoading from "@components/SmallLoading";
|
|
|
+import {REQ_STATUS} from "@api/config";
|
|
|
+import {reqLogin, reqRegister} from "@features/api";
|
|
|
+
|
|
|
+const i18n=global.i18n;
|
|
|
+const TYPE_LOGIN="login";
|
|
|
+const TYPE_REGISTER="register";
|
|
|
+
|
|
|
+
|
|
|
+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=='dark'?logo_dark:logo_light);
|
|
|
+ const loginStatus=useSelector(getLoginStatus);
|
|
|
+ const regStatus=useSelector(getRegStatus);
|
|
|
+ const dispatch = useDispatch();
|
|
|
+ const {register, handleSubmit, formState: {errors}, control} = useForm({
|
|
|
+ defaultValues: {
|
|
|
+ // country:'55',
|
|
|
+ account: '',
|
|
|
+ password: '',
|
|
|
+ email:"",
|
|
|
+ repassword:"",
|
|
|
+ lang:""
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const {pathname,hash} = useLocation();
|
|
|
+ useEffect(() => {
|
|
|
+ if (hash==="#/signin"){
|
|
|
+ setShowType(TYPE_LOGIN);
|
|
|
+ }
|
|
|
+ else if (hash==="#/signup"){
|
|
|
+ setShowType(TYPE_REGISTER);
|
|
|
+ }
|
|
|
+ }, [pathname,hash]);
|
|
|
+ const onCallback=(code)=>{
|
|
|
+ if (code==200){
|
|
|
+ if (close)close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const onSubmitLogin=(data)=>{
|
|
|
+ data.country=country;
|
|
|
+ data.callback=onCallback;
|
|
|
+ dispatch(reqLogin(data));
|
|
|
+ }
|
|
|
+ const onSubmitReg=(data)=>{
|
|
|
+ data.country=country;
|
|
|
+ data.callback=onCallback;
|
|
|
+ dispatch(reqRegister(data));
|
|
|
+ }
|
|
|
+
|
|
|
+ const renderLoading=()=>{
|
|
|
+ return (<SmallLoading fill={"#fff"}/>)
|
|
|
+ }
|
|
|
+ const renderLogo=()=>{
|
|
|
+ return (
|
|
|
+ <div className={styles.l_logo}>
|
|
|
+ <img className={styles.logo_img} src={logourl}/>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const renderLoginForm=()=>{
|
|
|
+ return (
|
|
|
+ <Spring type="slideUp" >
|
|
|
+ <div className={styles.l_title}>{i18n.t("login.login_title")}</div>
|
|
|
+ <form autocomplete="off" className={styles.l_form} onSubmit={handleSubmit((data) => {
|
|
|
+ onSubmitLogin(data);
|
|
|
+ })}>
|
|
|
+ <Controller control={control}
|
|
|
+ name="account"
|
|
|
+ rules={{required: true}}
|
|
|
+ render={({field: {ref, onChange, value}, fieldState: {error}}) => (
|
|
|
+ <PhoneInput
|
|
|
+ className={classNames({'input-control--error': error})}
|
|
|
+ value={value}
|
|
|
+ onChange={e => onChange(e.target.value)}
|
|
|
+ onChangeCountry={(country)=>{
|
|
|
+ setCountry(country);
|
|
|
+ }}
|
|
|
+ placeholder={i18n.t('login.phone_ph')}
|
|
|
+ innerRef={ref}/>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ <Controller control={control}
|
|
|
+ name="password"
|
|
|
+ rules={{required: true}}
|
|
|
+ render={({field: {ref, onChange, value}, fieldState: {error}}) => (
|
|
|
+ <PasswordInput
|
|
|
+ className={classNames({'input-control--error': error})}
|
|
|
+ value={value}
|
|
|
+ onChange={e => onChange(e.target.value)}
|
|
|
+ placeholder={i18n.t('login.login_pwd')}
|
|
|
+ innerRef={ref}/>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ <div className={styles.l_forgot}>
|
|
|
+ <button className={styles.forgot_btn}>
|
|
|
+ {i18n.t("login.forgot")}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ <button className={"button-green"}>
|
|
|
+ {
|
|
|
+ loginStatus===REQ_STATUS.LOADING?renderLoading():i18n.t("login.sign_in_btn")
|
|
|
+ }
|
|
|
+ </button>
|
|
|
+ {/*<div className={styles.l_reg_new}>*/}
|
|
|
+ {/* <div>{i18n.t("login.reg_new_des")}</div>*/}
|
|
|
+ {/* <div className={styles.reg_btn} onClick={()=>{*/}
|
|
|
+ {/* setShowType(TYPE_REGISTER);*/}
|
|
|
+ {/* }}>*/}
|
|
|
+ {/* {i18n.t("login.reg_new_btn")}*/}
|
|
|
+ {/* </div>*/}
|
|
|
+ {/*</div>*/}
|
|
|
+ </form>
|
|
|
+ </Spring>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const renderRegisterForm=()=>{
|
|
|
+ return (
|
|
|
+ <Spring type="slideUp">
|
|
|
+ <div className={styles.l_title}>{i18n.t("login.reg_title")}</div>
|
|
|
+ <form autocomplete="off" className={styles.l_form} onSubmit={handleSubmit((data) => {
|
|
|
+ onSubmitReg(data);
|
|
|
+ })}>
|
|
|
+ <Controller control={control}
|
|
|
+ name="account"
|
|
|
+ rules={{required: true}}
|
|
|
+ render={({field: {ref, onChange, value}, fieldState: {error}}) => (
|
|
|
+ <PhoneInput
|
|
|
+ className={classNames({'input-control--error': error})}
|
|
|
+ value={value}
|
|
|
+ onChange={e => onChange(e.target.value)}
|
|
|
+ onChangeCountry={(country)=>{
|
|
|
+ setCountry(country);
|
|
|
+ }}
|
|
|
+ placeholder={i18n.t('login.phone_ph')}
|
|
|
+ innerRef={ref}/>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ <Controller control={control}
|
|
|
+ name="password"
|
|
|
+ rules={{required: true}}
|
|
|
+ render={({field: {ref, onChange, value}, fieldState: {error}}) => (
|
|
|
+ <PasswordInput
|
|
|
+ className={classNames({'input-control--error': error})}
|
|
|
+ value={value}
|
|
|
+ onChange={e => onChange(e.target.value)}
|
|
|
+ placeholder={i18n.t('login.login_pwd')}
|
|
|
+ innerRef={ref}/>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ <Controller control={control}
|
|
|
+ name="repassword"
|
|
|
+ rules={{required: true}}
|
|
|
+ render={({field: {ref, onChange, value}, fieldState: {error}}) => (
|
|
|
+ <PasswordInput
|
|
|
+ className={classNames({'input-control--error': error})}
|
|
|
+ value={value}
|
|
|
+ onChange={e => onChange(e.target.value)}
|
|
|
+ placeholder={i18n.t('login.re_pwd')}
|
|
|
+ innerRef={ref}/>
|
|
|
+ )}
|
|
|
+ />
|
|
|
+ <button className={"button-green"}>
|
|
|
+ {
|
|
|
+ regStatus===REQ_STATUS.LOADING?renderLoading():i18n.t("login.sign_up_btn")
|
|
|
+ }
|
|
|
+ </button>
|
|
|
+ {/*<div className={styles.l_reg_new}>*/}
|
|
|
+ {/* <div>{i18n.t("login.login_des")}</div>*/}
|
|
|
+ {/* <div className={styles.reg_btn} onClick={()=>{*/}
|
|
|
+ {/* setShowType(TYPE_LOGIN);*/}
|
|
|
+ {/* }}>*/}
|
|
|
+ {/* {i18n.t("login.sign_in_btn")}*/}
|
|
|
+ {/* </div>*/}
|
|
|
+ {/*</div>*/}
|
|
|
+ </form>
|
|
|
+ </Spring>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const renderForm=()=>{
|
|
|
+ let form=(<></>);
|
|
|
+ if (showType===TYPE_LOGIN){
|
|
|
+ form=renderLoginForm();
|
|
|
+ }
|
|
|
+ else if (showType===TYPE_REGISTER){
|
|
|
+ form=renderRegisterForm();
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <div className={styles.l_form_container}>
|
|
|
+ {form}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <div className={styles.container}>
|
|
|
+ {renderLogo()}
|
|
|
+ {renderForm()}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+export default LoginForm;
|