チャットApp(登録・ログイン[ビュー])

今回から登録・ログイン機能を作っていきます。今回はその中でもビューの部分です。firebaseに登録する機能は次回やります。

まずは以下のようにtsxファイルとcssファイルを作ります。

スクリーンショット 2020-08-15 14.07.03

そして以下のように記述してください。

signup.tsx

import { useState } from "react";
import BasicHead from "../components/atom/head";
import TitleLogo from "../components/atom/logo";
import BasicH2 from "../components/atom/basicH2";
import BasicParagraph from "../components/atom/basicP";
import BasicTextField from "../components/atom/textbox";
import BasicButton from "../components/atom/button";
import ContainerDiv from "../components/atom/containerDiv";
import Styles from "../styles/signup.module.css";
import { validationEmail, validationPassword } from "../functions/validation";

export default function SignUp() {
   const [email   , setEmail]    = useState("");
   const [password, setPassword] = useState("");
   const [emailMessage   , setEM] = useState(["メールアドレスを入力してください。", "#000000"]);
   const [passwordMessage, setPM] = useState(["パスワードは半角のアルファベット・数字をそれぞれ1文字以上を含む8文字以上100文字以内で指定してください。", "#000000"]);
   const handleChangeEmail = (event:React.ChangeEvent<{ value: unknown }>) => {
       setEmail(event.target.value as string);
       if (validationEmail(event.target.value as string)) {
           setEM(["OK!!", "#55c501"]);
       } else { 
           setEM(["無効なメールアドレスです", "#ff0000"]);
       }
   }
   const handleChangePassword = (event:React.ChangeEvent<{ value: unknown }>) => {
       setPassword(event.target.value as string);
       if (validationPassword(event.target.value as string)) {
           setPM(["OK!!", "#55c501"]);
       } else {
           setPM(["パスワードは半角のアルファベット・数字をそれぞれ1文字以上を含む8文字以上100文字以内で指定してください。", "#ff0000"]);
       }
   }
   return (
       <div>
           <BasicHead />
           <main>
               <div className={ Styles.title }>
                   <TitleLogo />
               </div>
               <div className={ Styles.box }>
                   <ContainerDiv>
                       <div className={ Styles.register }>
                           <BasicH2>登録</BasicH2>
                       </div>
                       <div className={ Styles.paragraph }>
                           <BasicParagraph>
                               初めての人は、ここでメールアドレスとパスワードの登録をしてください。
                           </BasicParagraph>
                       </div>
                       <div className={ Styles.innerbox }>
                       <BasicTextField
                           label     ="email"
                           value     ={ email }
                           onchange  ={ handleChangeEmail }
                           fullWidth ={ true }
                       />
                       <div style={{color: emailMessage[1]}}>
                           <BasicParagraph>
                               { emailMessage[0] }
                           </BasicParagraph>
                       </div>
                       </div>
                       <div className={ Styles.innerbox }>
                       <BasicTextField
                           label     ="password"
                           value     ={ password }
                           onchange  ={ handleChangePassword }
                           fullWidth ={ true }
                       />
                       <div style={{color: passwordMessage[1]}}>
                           <BasicParagraph>
                               { passwordMessage[0] }
                           </BasicParagraph>
                       </div>
                       </div>
                       <div className={ Styles.innerbox }>
                       <BasicButton
                           fullWidth={ true }
                       >
                           登録
                       </BasicButton>
                       </div>
                   </ContainerDiv>
               </div>
           </main>
       </div>
   );
}

signup.module.css

.title {
   position: absolute;
   top: 0;
   left: 0;
   width: 15%;
   height: 15%;
   min-width: 200px;
   min-height: 200px;
}
.register {
   text-align: center;
   margin-bottom: 3rem;
}
.paragraph {
   margin: 1rem;
}
.box {
   box-sizing: border-box;
   margin: calc(300px - 20vw) auto 0;
   max-width: 500px;
}
.innerbox {
   margin: 1rem;
   width: 430px;
}

前回作った部品を組み合わせて作っていきます。ここでは、reactのuseStateを使用して入力の値を保持します。また、firebaseに送る際のデータもこのuseStateの変数になります。

handleChange関数によって入力された値をuseStateで定義された変数に反映し、入力の内容によってメッセージを表示します。

validationEmailとvalidationPasswordを読み込んでいますが、これは別ファイルに入力された値のチェックのためのバリデーションを行う関数を定義しています。

functions/validation.ts

/**
* メールアドレスのバリデーションチェック関数
* 真偽を返す。
* @param value email address
*/
export const validationEmail = (value:string):boolean => {
   let bool:boolean = false;
   const reg = /^[A-Za-z0-9]{1}[A-Za-z0-9_.-]*@{1}[A-Za-z0-9_.-]{1,}\.[A-Za-z0-9]{1,}$/;
   if (reg.test(value)) {
       bool = true;
   }
   return bool;
}
/**
* パスワードのバリデーションチェック関数
* パスワードは半角のアルファベット・数字をそれぞれ1文字以上を含む8文字以上100文字以内で指定
* 真偽を返す。
* @param value password
*/
export const validationPassword = (value:string):boolean => {
   let bool:boolean = false;
   const reg = /^(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,100}$/i;
   if (reg.test(value)) {
       bool = true;
   }
   return bool;
}

このように引数に対して正規表現を用いてバリデーションのチェックを行います。一度実行して確認します。

スクリーンショット 2020-08-15 14.24.28

このように、入力内容が適切では無い場合、赤い文字で注意されます。

スクリーンショット 2020-08-15 14.25.42

メールアドレスとして適切な形になっていれば、緑の文字でOK!!と出ます。これまでバリデーションはフレームワークを使っていたのでこの実装は勉強になりました。
signin.tsx, signin.module.cssも表示する文章が一部異なるだけなのでsignupをコピペしてください。

これでページとして表示出来る形になったので、ルートページからルーティングしてあげましょう。index.tsxのボタンタグを以下のように書き直してください。

<div className={ styles.button }>
   <BasicButton
       fullWidth ={ true }
       onclick   ={() => Router.push("/signup")}
   >登録</BasicButton>
</div>

<a>タグを使った場合next.jsの場合は<Link>タグを使用するのですが、onclick属性の場合は<Router>を読み込んであげるとルーティングが出来ます。

以上でおしまいです。ボタンやテキストボックス等の部品を一部書き換えましたが、あとは上記の通りです。

次回は実際にfirebaseに登録が出来るようにします。

この記事が気に入ったらサポートをしてみませんか?