From 71abc48fd4525b9194df848a6915ab4dfc11c354 Mon Sep 17 00:00:00 2001 From: Masaya Tojo Date: Sun, 1 Sep 2024 22:36:21 +0900 Subject: 確認画面まで作成する MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SignUpConfirm.tsx | 33 +++++++++++++++++++++++++++++++++ src/SignUpForm1.tsx | 48 ++++++++---------------------------------------- src/SignUpForm2.tsx | 40 ++++++++++++++++++++++++++++++++++++++++ src/routes.tsx | 2 ++ src/signUpSchema.ts | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 134 insertions(+), 40 deletions(-) create mode 100644 src/SignUpConfirm.tsx create mode 100644 src/signUpSchema.ts (limited to 'src') diff --git a/src/SignUpConfirm.tsx b/src/SignUpConfirm.tsx new file mode 100644 index 0000000..295bad6 --- /dev/null +++ b/src/SignUpConfirm.tsx @@ -0,0 +1,33 @@ +import './SignUp.css' +import { useLocation, Navigate } from 'react-router-dom'; +import { Form } from './signUpSchema' + +export const SignUpConfirm = () => { + const location = useLocation() + + const form = location.state as Form | null; + + // form1 のデータがない場合は form1 にリダイレクトする + if (form === null) { + return + } + + return ( + <> +

会員登録 確認画面

+
+

あなたの情報

+
+

お名前: {form.name}

+

名前カナ: {form.kana}

+

電話番号: {form.tel1}-{form.tel2}-{form.tel3}

+
+

ログイン関連の情報

+
+

メールアドレス: {form.email}

+

パスワード: セキュリティ上の理由のため非表示

+
+
+ + ); +} diff --git a/src/SignUpForm1.tsx b/src/SignUpForm1.tsx index fee515f..76c6020 100644 --- a/src/SignUpForm1.tsx +++ b/src/SignUpForm1.tsx @@ -1,49 +1,18 @@ import './SignUp.css' import { useForm } from 'react-hook-form' import { zodResolver } from "@hookform/resolvers/zod" -import * as z from "zod" -import parsePhoneNumber from 'libphonenumber-js' - -const kanaRegex = /^[ァ-ン]+$/ - -const schema = z.object({ - name: z.string().min(1, { message: '必須項目です' }), - kana: z.string().min(1, { message: '必須項目です' }).regex(kanaRegex, { message: 'カタカナを入力してください' }), - tel1: z.string(), - tel2: z.string(), - tel3: z.string(), -}).refine( - ({ tel1, tel2, tel3 }) => (tel1.length > 0 && tel2.length > 0 && tel3.length > 0), - { - message: '必須項目です', - path: ['tel3'], - } -).refine( - ({ tel1, tel2, tel3 }) => { - const phoneNumber = parsePhoneNumber('+81' + `${tel1}${tel2}${tel3}`) - console.log([`${tel1}${tel2}${tel3}`, phoneNumber?.isValid()]) - return phoneNumber?.isValid() - }, - { - message: '電話番号が不正です', - path: ['tel3'], - } -) - -type Form1 = { - name: string, - kana: string, - tel1: string, - tel2: string, - tel3: string, -} +import { useNavigate } from 'react-router-dom'; +import { Form1, form1Schema } from './signUpSchema' export const SignUpForm1 = () => { const { register, handleSubmit, formState: { errors } } = useForm({ - resolver: zodResolver(schema), + resolver: zodResolver(form1Schema), }); + const navigate = useNavigate(); - const onsubmit = (data: Form1) => console.log(data); + const onsubmit = (state: Form1) => { + navigate('/sign-up/form2', { state }) + } const onerror = (err: any) => console.log(err); return ( @@ -70,8 +39,7 @@ export const SignUpForm1 = () => {
- + ); } - diff --git a/src/SignUpForm2.tsx b/src/SignUpForm2.tsx index 1824fd6..f355225 100644 --- a/src/SignUpForm2.tsx +++ b/src/SignUpForm2.tsx @@ -1,9 +1,49 @@ import './SignUp.css' +import { useForm } from 'react-hook-form' +import { zodResolver } from "@hookform/resolvers/zod" +import { useLocation, Navigate, useNavigate } from 'react-router-dom'; +import { Form1, Form2, form2Schema } from './signUpSchema' export const SignUpForm2 = () => { + const { register, handleSubmit, formState: { errors } } = useForm({ + resolver: zodResolver(form2Schema), + }); + const location = useLocation(); + const form1 = location.state as Form1 | null; + const navigate = useNavigate(); + + // form1 のデータがない場合は form1 にリダイレクトする + if (form1 === null) { + return + } + + const onsubmit = (form2: Form2) => { + const state = { + ...form1, + ...form2, + } + navigate('/sign-up/confirm', { state }) + } + const onerror = (err: any) => console.log(err); + return ( <>

会員登録 フェーズ 2

+
+
+ + +
{errors.email?.message}
+
+
+ + +
{errors.password?.message}
+
+
+ +
+
); } diff --git a/src/routes.tsx b/src/routes.tsx index cb2b37c..1a3daa1 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -3,10 +3,12 @@ import { Top } from './Top'; import { SignUp } from './SignUp'; import { SignUpForm1 } from './SignUpForm1'; import { SignUpForm2 } from './SignUpForm2'; +import { SignUpConfirm } from './SignUpConfirm'; export const routes = createBrowserRouter([ { path: '/', element: }, { path: '/sign-up', element: }, { path: '/sign-up/form1', element: }, { path: '/sign-up/form2', element: }, + { path: '/sign-up/confirm', element: }, ]); diff --git a/src/signUpSchema.ts b/src/signUpSchema.ts new file mode 100644 index 0000000..4d8b71f --- /dev/null +++ b/src/signUpSchema.ts @@ -0,0 +1,51 @@ +import * as z from "zod" +import parsePhoneNumber from 'libphonenumber-js' + +const kanaRegex = /^[ァ-ン]+$/; + +const form1SchemaWithoutRefine = z.object({ + name: z.string().min(1, { message: '必須項目です' }), + kana: z.string().min(1, { message: '必須項目です' }).regex(kanaRegex, { message: 'カタカナを入力してください' }), + tel1: z.string(), + tel2: z.string(), + tel3: z.string(), +}) + +const addRefine = (schema: Form1) => ( + schema.refine( + ({ tel1, tel2, tel3 }) => (tel1.length > 0 && tel2.length > 0 && tel3.length > 0), + { + message: '必須項目です', + path: ['tel3'], + } + ).refine( + ({ tel1, tel2, tel3 }) => { + const phoneNumber = parsePhoneNumber('+81' + `${tel1}${tel2}${tel3}`) + console.log([`${tel1}${tel2}${tel3}`, phoneNumber?.isValid()]) + return phoneNumber?.isValid() + }, + { + message: '電話番号が不正です', + path: ['tel3'], + } + )) + + +export type Form1 = z.infer + +export const form2Schema = z.object({ + email: z.string().min(1, { message: '必須項目です' }).email({ message: 'メールアドレスを入力してください' }), + password: z.string() + .min(1, { message: '必須項目です' }) + .min(12, { message: '12文字以上で入力してください' }) + .max(128, { message: '128文字以下で入力してください' }) +}) + +export type Form2 = z.infer + +const formSchemaWithoutRefine = form1SchemaWithoutRefine.merge(form2Schema) + +export type Form = z.infer + +export const form1Schema = addRefine(form1SchemaWithoutRefine) +export const formSchema = addRefine(formSchemaWithoutRefine) -- cgit v1.2.3