Pārlūkot izejas kodu

Merge branch 'feature-chaojie' into dev

username 1 gadu atpakaļ
vecāks
revīzija
972fc09658

+ 51 - 0
src/api/user.ts

@@ -0,0 +1,51 @@
+import { server } from "@/utils/server";
+
+export const getBindPhoneApi = () => {
+    return server.post<any>({
+        url: "/v1/api/user/bind_phone",
+    });
+};
+
+export const getFindPwdApi = () => {
+    return server.post<any>({
+        url: "/v1/api/user/find_pwd"
+    });
+};
+
+export const getGoogleLoginApi = () => {
+    return server.post<any>({
+        url: "/v1/api/user/google_login"
+    });
+};
+
+export const getLoginApi = (data: any) => {
+    return server.post<any>({
+        url: "/v1/api/user/login",
+        data
+    });
+};
+
+export const getLogoutApi = () => {
+    return server.post<any>({
+        url: "/v1/api/user/logout"
+    });
+};
+
+export const getRegisterApi = (data: any) => {
+    return server.post<any>({
+        url: "/v1/api/user/register",
+        data
+    });
+};
+
+export const getSendCodeApi = () => {
+    return server.get<any>({
+        url: "/v1/api/user/send_code"
+    });
+};
+
+export const getUserInfoApi = () => {
+    return server.post<any>({
+        url: "/v1/api/user/user_info"
+    });
+};

+ 10 - 9
src/app/[locale]/(ordinary)/profile/page.scss

@@ -61,14 +61,13 @@
           font-size: .12rem;
         }
       }
+
       .goto {
-        display: -webkit-box;
-        display: -ms-flexbox;
         display: flex;
-        -webkit-box-align: center;
-        -ms-flex-align: center;
         align-items: center;
+        cursor: pointer;
       }
+
       .iconfont {
         font-size: .16rem;
         font-weight: 700;
@@ -78,16 +77,14 @@
         margin-left: .04rem;
       }
     }
+
     .coin {
-      display: -webkit-box;
-      display: -ms-flexbox;
       display: flex;
-      -webkit-box-pack: justify;
-      -ms-flex-pack: justify;
       justify-content: space-between;
       padding: .07rem 0 .3rem;
       margin: 0 .18rem;
       border-top: .01rem dotted #d9a801;
+
       & > div {
         display: flex;
         -webkit-box-align: center;
@@ -96,18 +93,22 @@
         width: 50%;
         -webkit-box-sizing: border-box;
         box-sizing: border-box;
+
         &:first-child {
           border-right: .01rem dotted #d9a801;
         }
+
         .iconfont {
           margin: 0 .08rem;
           font-size: .18rem;
         }
+
         & > div {
           flex: 1;
           display: flex;
           flex-direction: column;
         }
+        
         div {
           span {
             font-size: .12rem;
@@ -185,7 +186,7 @@
             .iconfont {
               margin-right: .04rem;
               margin-left: .1rem;
-              font-size: .18rem;
+              font-size: .16rem;
             }
           }
         }

+ 12 - 6
src/app/[locale]/(ordinary)/profile/page.tsx

@@ -1,5 +1,6 @@
 "use client";
 import { FC, PropsWithChildren } from "react";
+import { useRouter } from "@/i18n";
 // import ButtonOwn from "@/components/ButtonOwn";
 import './page.scss'
 
@@ -10,6 +11,11 @@ const Profile: FC<PropsWithChildren<Props>> = (props) => {
     let amount = 50
     let amountList = [10,20,50,100,200,500,1000,5000,10000,500,1000,5000,10000]
 
+    const router = useRouter();
+    const goPage = (path = '/') => {
+        router.push(path)
+    }
+
     return (
         <div className="main">
             <div className="userContent">
@@ -21,9 +27,9 @@ const Profile: FC<PropsWithChildren<Props>> = (props) => {
                             <span className="phone">5516982013895</span>
                         </div>
                     </div>
-                    <div className="goto">
+                    <div className="goto" onClick={() => goPage('/login')}>
                         <span>Login</span>
-                        <span className="iconfont icon-to"></span>
+                        <span className="iconfont icon-xiangzuo1"></span>
                     </div>
                 </div>
                 <div className="coin">
@@ -51,8 +57,8 @@ const Profile: FC<PropsWithChildren<Props>> = (props) => {
             </div>
 
             <div className="link">
-                <span>Depósito</span>
-                <span>Sacar</span>
+                <span  onClick={() => goPage('/deposit')}>Depósito</span>
+                <span  onClick={() => goPage('/withdraw')}>Sacar</span>
                 {/* <ButtonOwn active={true}>Depósito</ButtonOwn>
                 <ButtonOwn active={true}>Sacar</ButtonOwn> */}
             </div>
@@ -65,13 +71,13 @@ const Profile: FC<PropsWithChildren<Props>> = (props) => {
                                 <span data-v-5c42ece6="" className="iconfont icon-hot"></span>
                                 <div data-v-5c42ece6=""></div>
                             </div>
-                            <div><span className="iconfont icon-to"></span></div>
+                            <div><span className="iconfont icon-xiangyou1"></span></div>
                         </li>
                     ))
                 }
             </ul>
 
-            <span className="logOut">Login</span>
+            <span className="logOut" onClick={() => goPage('/login')}>Login</span>
         </div>
     );
 };

+ 144 - 0
src/app/[locale]/(ordinary)/withdraw/page.scss

@@ -0,0 +1,144 @@
+.deposit-box {
+    width: 100%;
+    min-height: 100vh;
+    padding: 0 .14rem;
+    padding: .44rem .18rem;
+    background-color: #1f1f1f;
+    display: flex;
+    flex-direction: column;
+    .img-box {
+      width: .8rem;
+      height: .27rem;
+      margin: .12rem 0;
+      background: url('/img/pixImg.png') no-repeat center;
+      background-size: 100% 100%;
+    }
+    .btn-box {
+      margin: .1rem 0;
+      height: .3rem;
+      margin-right: .06rem;
+      width: .98rem !important;
+      -ms-flex-negative: 0;
+      flex-shrink: 0;
+      border-radius: .05rem;
+      line-height: .28rem;
+      align-items: center;
+      background: transparent;
+      border: .01px solid #ff9323;
+      border-radius: .05rem;
+      color: #868686;
+      font-size: .1rem;
+      line-height: .28rem;
+      cursor: pointer;
+      text-align: center;
+      font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, miui, Hiragino Sans GB, Microsoft Yahei, sans-serif;
+    }
+    .amount-box {
+      width: 100%;
+      height: auto;
+      margin: .05rem 0;
+      display: flex;
+      flex-direction: column;
+      span {
+        font-size: .13rem;
+        color: #fff;
+      }
+      input {
+        font-size: .16rem;
+        width: 100%;
+        margin: .12rem 0 .04rem;
+        background-color: #494949;
+        border-radius: .05rem;
+        height: .4rem;
+        color: #868686;
+        text-indent: .14rem;
+        outline: none;
+        &::placeholder {
+          color: #868686;
+        }
+      }
+    }
+    .ul-box {
+      width: 100%;
+      height: auto;
+      -webkit-box-pack: justify;
+      -ms-flex-pack: justify;
+      justify-content: space-between;
+      flex-wrap: wrap;
+      margin-top: .09rem;
+      display: flex;
+      -webkit-box-align: center;
+      -ms-flex-align: center;
+      align-items: center;
+      li {
+        width: 30%;
+        height: .48rem;
+        border-radius: .06rem;
+        color: #fff;
+        font-size: .18rem;
+        background: #494949;
+        display: flex;
+        -webkit-box-align: center;
+        -ms-flex-align: center;
+        align-items: center;
+        -webkit-box-orient: vertical;
+        -webkit-box-direction: normal;
+        -ms-flex-direction: column;
+        flex-direction: column;
+        -webkit-box-pack: center;
+        -ms-flex-pack: center;
+        justify-content: center;
+        margin-top: .12rem;
+        position: relative;
+        overflow: hidden;
+        cursor: pointer;
+        &.active {
+          background-color: #ff6a01;
+          .hot {
+            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABBCAYAAABlwHJGAAAFSUlEQVR4nOWce2gcRRzHPycBH7GiIqGif1Sw1gpqQJEqUhqtNa2V1IqPiIK0VoOxPiu1qH+JWLDaQpVCW4pFJdb4KhRqUHwlVCgWo5VWDaZoS0PiI9Y0JtbHyK8zy20uu3ezz7vb+8Kyub1ZfjOfm99vfjM7m5xSCh+dCNwILASuBM4HTvArXOV6qs6j/vXAQ8ByYGpGG+7WKmB1IYhZQAcwrbx1S02PA2vEmBvEAuAd4xJZl8SDx4C1Tjsdn78Y6CwLhN+H0raojOuvdV8UEDlgI3BK2jWipxOenAoHvk7LokBoB9YXfiEg5pjYkK4EQsdt2uRvA2lBaAM2eH0pMaK1rBCW7ITLrk/a4n/AMmCLX4G61HtD+hD+BZYCW4sVqkt1qHRDEI39kbRFgXA38FqpghIjpiRdm+NyQ5huzvJZricjgXCXDQRSS5kL3eHhDmhs15+TgfGPiX0dtjekA+Lk0/TZHROWrU8KxjHgdpMX2UulpeFBb0MbH1Dq/pw+ut+MWpm/lFItMpEMesjs03f6mZo2LYfel7W11m1w9S1he8LNwI4wNycHQrLFz9+CoT6oPwtmzobLF8BJ9d7l3TBaNsG8pUGsjQOLgZ1hqxs/iPFRePWJfKPcmnIBLHzG/xd3w2jvgYuusrE4BtwEdEWpdvwg1rVC3zY4uwnmtMGZ58Ch/fDR8zDyvS5z3RpY9Kj3/QJDeo+de/wp/Qf4MHK9Yw2VXZt10JMAWKixo0q9/nScgXFUKdUUJjB6HfGBkIaunKEb6TdCiBwYUrZYueIaUUrNjguCHPHlEcODuuuLS5ze4F9u8UpdRsp+82kYS5KXzwc+i1DbSYoPxPhRu3Iyalxxh/57f+C2HDEQeoLeWErhQUgmKIHN0RlmnXfg49ILLefO1OfRX4JYFAjzgF2h6ltC4UBIQyUtlqHOgSHu4Eymtj9X/P6xEX1umG5rcRi4Ftgdqr4WCgfivEt0Bihyw2hZpc8yfL73ov/93a/oc2OzjbVfgbnAnlB1tVWkkUKGQGc4dIbMd1+YeO3wD/nyMko4cwuvIXayflZKNcY5Ovgd0RMq9xRbZpMyq5Te8MGKfBkZJU5t0D0Fsx7Rttk/3dYaMj1hb0y/eVF5PemaLIkJ4g5ecqbYOG5iptiXztWxQhovARSTYs+6F5rvKwVhELgG2Jdw+/Oy7v5emeAX7090g0I3cdyh/yt9SNJVWoeVUhem4Q7uozQIv/UCNwTnulfMCKZDSqkZaUOwjxGF6wXiDlvm5z+7J0heMcNOB80Q2ZdM3y8u+2DphuHIbxHFgWG/yPIT0AT0R29SSAXquH5xwEsSE+x0QCk1rRzuENw13IpnWc1Rvxkdfkzsl7ZU8MwyvtXnPvPctewQCJ1iR4fxnYkJB0PZT0DRMku3m6zo9U+6JupbcYdcLjcQNamNU9FT7GBrjPsMBMkcyRYIe+01c4fUt8jYKK3tgr0mWapICFhPuqLpS1nAN+sKFauke8Qe0xMqGgIJg9htIAwnaCM2JQVil1loPVKGNoVSEiB6zJJ71UAggWDZbXbwWj7kqBzF2SM+AZqrEQIxgpCn0TeYp9NVqThAdJlH81ULgRhAyA6VRdUOgYggdhgI4zHWp2wKC2K72bh1LAMMjisMiLeBW7MEgRAgOs2O1kxBICCINwyEvxOsT9lkC0I2dt9pNnpnUjYgtpqt/pmFgAUIeeNlSdYhUAKEvPB2j3kNKPPyA7HBvAhWOcvMCcsLxEvmlcCagYAHiHXAg7UGgQIQ8o70I7UIAReI1eaF8ZqVgHjW/OuA2hXwP8DQnuAIx+ICAAAAAElFTkSuQmCC);
+            width: .33rem;
+            height: .325rem;
+            background-size: 100% 100%;
+          }
+          .amountTips {
+            color: #fff;
+          }
+        }
+        .hot {
+          display: inline-block;
+          position: absolute;
+          top: 0;
+          left: 0;
+          background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAABBCAYAAABlwHJGAAAFWklEQVR4nOWca2gdRRTHf5GApWmxImr0g2i1gkIVlfoqitUa21oxKpa0KD5aoeKLWvpBqH4pQvHRFqwE1CoBS4pBabGgqdZHW/MhEqsG6iMa+0BrqxKjMQ31ETmZs2S4d+/dubuzex/5Q9jHnb0z87tnzjkzu5u60QcppBOBW4CFwFXAecAJBUtXt1bXhzS/AXgMeARorNGO23oCWJsL4kqgHTi7vG3LTKuA56QyG8QC4C0dErWuUWAlsD7oZzDmZwIdZYFw5vVZ1ziqQ3+9fVJA1AEvAZOzbhHNr8DqnXDJQ1nVKBCkshdyP5ChcZ36hmwlEJqWmipPnZ4VhOX6o+dJQCwuK4St62DHyrRr/A94AHi1UIH6zK0hewj/AlJhW7FC9ZmGShuCaPJJadcoEO4FXo8qKM5yatqtGZMN4XC/2cqxnE9HAuFuFwhkljLnDoc158IPX5rjdGD8o76v3fWCbEAMD5qt7ROevTgtGMeBFs2LnCWTLgkr6UsSp58+yK9m1RdwzkVmf8cm2LosKYRFwLZSL8xuNhkGAa+WIRDuiAOBVC1CssXZS+DkRhgZgr5PYecz8Oe34eVty9jdAe2LSqltBLgdeCduc/2DmHo+LO8Y75Stkb9g15bC5m/D2PwUfLLGpcZjwG1AZ5Jm+wfx5PdwxnT4/Sh0vw2/HICzZsKsBTCpwZTp6YRN88KvFxhiPW6+Yhi4FXg/abP9glj8BlxzpxnzMvZtiaXc8xpceLU5mdwxDuvq2YceWu7RWUpH5VcXbV6R/7n4ho2zYV+XOb62JckUfAiY7wsCXkE0XmpMX4ZEoQgharvPlJGyly+JU9MfCmFXgtbmyR+IKae4lRPL6P3Y7M+YVWotgwphT6kXRik+CIn34tgCHfnK7Ew7LXqh5WCv2U6aUkqNAqEJ6IrV3gjFAyEdleRHQl0AQ4ZDMJla+Hjx6xumme3Az641DgA3AN2x2uugeCD2vmi8vsiGsX2d2Ur4XPpu4euvaNbvKVJmXL8BcyXoxmqro+IPDQl9uTAEUI/mNZfdZM7NaBm/RqKEnBNQEmKjE6ZfFcJnXnpbRMnzCHuKHeQPYg0CIpBEiWNDBgC6HrFhfuF02+ioQuhN1D5HuVlEMecXTLGxLEOyxpcfHvcZ4kAFgqTYYjHREI4Ac7KCgJNFBL94WCbY9Dw0q2MUawjmCXZmKcPh9AvM/nfvRQEQHQYk0/o6Vo9iKtoiglifO0W2IQgk6XiYA5VoIr5D/qIh/KiWkCkEnH1E7uKJDAcbgm0pYT7DTYc0RPZ576WDwu6G50s6E8CwV6HDhktwLOVkFummg2oJ/WVgMKbSooZtGVG/tjhYGQ7R2q8Q9ifsSyKVlkfYy2oCpNiymhuEfr3lWFYIxEqo/K0x9imEA3G/wKfiZZbJYXyjw+FQVh2NUvwUOxeG+619CY1z6lrHQmXFKNl6RABDooebT9gnw6GudSxpqihld4PHpMtzdQ5RccrqBs/nmixVJAScE6pk2gvcqOsKFau0LaJHLaGiIZAyiG6FMJBiHd6UFoguXWgddChbEUoDxB5dcq8aCKTgLHfrE7xDnr83dfm0iI+AedUIAY8g5G70zXpjtirlA0Sn3pqvWgh4ACFPqDRXOwQSgtiuEEY8tqdsigtimz64dbwGGIwpDog39RG+moFADBAd+kRrTUGgRBBbFMLfKbanbHIFIQ9236UPetekXEC06aP+NQsBBxDyxsv9tQ6BCBDy7tMyfQ2o5lUIRKu+CJbVwm7ZFQZio74SOGEgEAJiA/DoRINADgh5R3rFRISABWKtvjA+YSUgntZ/HTBxBfwPUDWaaJmlFlUAAAAASUVORK5CYII=);
+          width: .33rem;
+          height: .325rem;
+          background-size: 100% 100%;
+        }
+        .amountContent {
+          width: 100%;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          
+          .iconfont {
+            margin-right: .03rem;
+            font-size: .14rem;
+            font-family: SWISSC-BT;
+            color: #fff;
+            font-weight: bold;
+            font-style: oblique;
+          }
+        }
+        .amountTips {
+          font-size: .1rem;
+          color: #ff9500;
+        }
+      }
+    }
+    .topUp {
+      width: 100%;
+      height: auto;
+      margin: .24rem 0 .19rem;
+    }
+  }
+  

+ 27 - 0
src/app/[locale]/(ordinary)/withdraw/page.tsx

@@ -0,0 +1,27 @@
+import { FC, PropsWithChildren } from "react";
+import clsx from "clsx";
+import ButtonOwn from "@/components/ButtonOwn";
+import './page.scss'
+
+interface Props {}
+
+const Withdraw: FC<PropsWithChildren<Props>> = (props) => {
+    let amount = 50
+    let amountList = [10,20,50,100,200,500,1000,5000,10000]
+
+    return (
+        <div className="deposit-box">
+            <div className="img-box"></div>
+            <p className="btn-box" color="primary">PIX Ⅰ</p>
+            <div className="amount-box">
+                <span>Montante (BRL):</span>
+                <input type="number" placeholder="Mín. 10.00"/>
+            </div>
+            <div className="topUp">
+                <ButtonOwn active={amount>0?true:false}>Saque</ButtonOwn>
+            </div>
+        </div>
+    );
+};
+
+export default Withdraw;

+ 43 - 12
src/app/[locale]/login/component/FromCom/index.tsx

@@ -1,5 +1,5 @@
 "use client";
-import { FC, PropsWithChildren, useState } from "react";
+import { ChangeEvent, FC, PropsWithChildren, useMemo, useState } from "react";
 import clsx from "clsx";
 import Link from "next/link";
 import ButtonOwn from "@/components/ButtonOwn";
@@ -8,35 +8,66 @@ import "./style.scss";
 /**
  * @description 登录注册From表单
  * @param {string} type 使用类型
- * @param {() => void} callbackFun 回调方法
+ * @param {(params: any) => void} callbackFun 回调方法
  */
 export interface FromComProps {
     type?: string;
     text?: string;
-    callbackFun?: () => void;
+    callbackFun?: (params: any) => void;
 }
 
 const FromCom: FC<PropsWithChildren<FromComProps>> = ({type = 'login', callbackFun}) => {
-    let [visible, setVisible] = useState(false)
-
+    let [pwdVisible, setPwdVisible] = useState(false)
     const spanClassName = clsx("iconfont", {
-        "icon-kejian": visible,
-        "icon-bukejian": !visible,
+        "icon-kejian": pwdVisible,
+        "icon-bukejian": !pwdVisible,
     });
 
+    let [fromParam, setFromParam] = useState({
+        userPhone: '',
+        pwd: ''
+    })
+
+    const activeCls = useMemo(() => {
+        let { userPhone, pwd } = fromParam
+        if (userPhone && userPhone.length==11 && pwd && pwd.length>6) {
+            return true
+        }
+        return false
+    }, [fromParam]);
+
+
+    const setInputVal = (e: ChangeEvent<HTMLInputElement>, propsName: string) => {
+        setFromParam({
+            ...fromParam,
+            [propsName]: e.target.value
+        })
+    }
+
+    const verifyPwd = (e: any) => {
+        let pwd = e.target.value || '';
+        pwd.replaceAll(/[^a-zA-Z0-9_-]/g, '')
+        setFromParam({ ...fromParam, pwd })
+        console.log('fromParam', fromParam.pwd)
+    }
+
+    const submitRequest = () => {
+        activeCls && callbackFun!(fromParam)
+    }
+
     return (
         <div className="FromCom">
             <div className="phoneInput">
                 <span className="after">+55</span>
-                <input type="tel" placeholder="Número de Celular" maxLength={11}/>
+                <input type="tel" value={fromParam.userPhone} onChange={(e) => setInputVal(e, 'userPhone') } placeholder="Número de Celular" maxLength={11} />
             </div>
             <div className="passwordInput">
-                <input type={visible?'text':'password'} placeholder="Senha" />
-                <span className={spanClassName} onClick={() => setVisible(!visible)}></span>
+                <input type={pwdVisible?'text':'password'} value={fromParam.pwd} onChange={(e) => setInputVal(e, 'pwd') } onInput={verifyPwd} placeholder="Senha" maxLength={12}/>
+                <span className={spanClassName} onClick={() => setPwdVisible(!pwdVisible)}></span>
             </div>
             <div className="btnContent">
                 <div className="tips"> O número de telefone não existe. </div>
-                <ButtonOwn active={true}>{type == 'login'? 'Login' : 'Criar conta'}</ButtonOwn>
+                <ButtonOwn active={activeCls} callbackFun={submitRequest}>{type == 'login'? 'Login' : 'Criar conta'}</ButtonOwn>
             </div>
             <div className="link">
                 {
@@ -45,7 +76,7 @@ const FromCom: FC<PropsWithChildren<FromComProps>> = ({type = 'login', callbackF
                             <Link href="/br/resetPhone">Esqueci minha senha?</Link>
                             <Link href="/br/register">Criar Conta Nova</Link>
                         </>
-                    ) : <Link href="/br/login" className="active">Já tem uma conta? Log in</Link>
+                    ) : <Link href="/br/login" className="active" replace>Já tem uma conta? Log in</Link>
                 }     
             </div>
         </div>

+ 7 - 1
src/app/[locale]/login/page.tsx

@@ -5,15 +5,21 @@ import GoogleCom from "./component/GoogleCom";
 import FromCom from "./component/FromCom";
 import DomainFooter from "@/components/DomainFooter";
 import './page.scss'
+import {getLoginApi} from "@/api/user";
 
 interface Props {}
 
 const Login: FC<PropsWithChildren<Props>> = () => {
+
+    const loginRequest = async (params: any) => {
+        let data = await getLoginApi(params)
+    }
+
     return (
         <div className="login-box">
             <HeaderBack />
             <GoogleCom />
-            <FromCom />
+            <FromCom callbackFun={loginRequest}/>
             <DomainFooter />
         </div>
     );

+ 6 - 1
src/app/[locale]/register/page.tsx

@@ -5,15 +5,20 @@ import GoogleCom from "../login/component/GoogleCom";
 import FromCom from "../login/component/FromCom";
 import DomainFooter from "@/components/DomainFooter";
 import '../login/page.scss'
+import {getRegisterApi} from "@/api/user";
 
 interface Props {}
 
 const Register: FC<PropsWithChildren<Props>> = () => {
+
+    const registerRequest = async (params: any) => {
+        let data = await getRegisterApi(params)
+    }
     return (
         <div className="register-box">
             <HeaderBack />
             <GoogleCom title="Bem-vindo à 9F.COM" text="Registre-se com Google+"/>
-            <FromCom type="register"/>
+            <FromCom type="register" callbackFun={registerRequest} />
             <DomainFooter />
         </div>
     );

+ 1 - 1
src/components/Footer/index.tsx

@@ -1,6 +1,6 @@
 "use client";
 import { usePathname, useRouter} from "@/i18n";
-import { FC, PropsWithChildren, ReactNode, useEffect } from "react";
+import { FC, PropsWithChildren, ReactNode } from "react";
 import clsx from "clsx";
 import "./style.scss";
 

+ 6 - 0
src/utils/index.ts

@@ -18,3 +18,9 @@ export const setHtmlFontSize = () => {
         recalc();
     })(document, window);
 };
+
+// 密码正则 6到12位(字母,数字,下划线,减号)
+export const pwdRegex = (pwd = '') => {
+	let regex = /^[a-zA-Z0-9_-]{6,12}$/;
+	return regex.test(pwd)
+}