From 7fa73728582e2dfb26ff89786c27dd9da97bebc2 Mon Sep 17 00:00:00 2001
From: Masaya Tojo <masaya@tojo.tokyo>
Date: Mon, 5 Aug 2024 23:26:43 +0900
Subject: zod でバリデーションを試す
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/SignUp.tsx | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

(limited to 'src/SignUp.tsx')

diff --git a/src/SignUp.tsx b/src/SignUp.tsx
index d812b35..2a7f448 100644
--- a/src/SignUp.tsx
+++ b/src/SignUp.tsx
@@ -1,9 +1,73 @@
 import './SignUp.css'
+import { useState } from "react";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import * as z from "zod"
+
+const schema = z.object({
+  name: z.string(),
+  email: z.string().email("それメアドじゃないよ"),
+  birthday: z.coerce.date().max(new Date(), { message: "まだ生まれてないじゃん" }),
+  language: z.string(),
+})
+
+type Answer = {
+  name: string,
+  email: string,
+  birthday: Date,
+  language: string,
+}
 
 export const SignUp = () => {
+  const { register, handleSubmit, reset, formState: { errors } } = useForm<Answer>({
+    resolver: zodResolver(schema)
+  });
+  const [answer, setAnswer] = useState<Answer | null>(null);
+
+  const yourAnswer = answer ? (
+    <>
+      <h2>あなたの情報です</h2>
+      <dl>
+        <dt>おぬしの名前は…</dt>
+        <dd>{answer.name}</dd>
+        <dt>おぬしのメアドは…</dt>
+        <dd>{answer.email}</dd>
+        <dt>あなたの誕生日</dt>
+        <dd>{answer.birthday.getFullYear()}年{answer.birthday.getMonth()}月{answer.birthday.getDay()}日</dd>
+        <dt>おぬしの好きなプログラミング言語は…</dt>
+        <dd>{answer.language}</dd>
+      </dl>
+    </>
+  ) : (<></>)
+
   return (
     <>
       <h1>会員登録</h1>
+      <form className="SignUpForm" onSubmit={handleSubmit((data) => setAnswer(data))}>
+        <label>お名前:</label>
+        <input {...register("name")} placeholder="おなまえ" />
+        {errors.name?.message}
+        <label>めるあど</label>
+        <input {...register("email", { required: true })} placeholder="めるあど" />
+        {errors.email?.message && <p className="error">{errors.email?.message}</p>}
+        <label>生まれた日</label>
+        <input {...register("birthday", { required: true })} placeholder="yyyy/mm/dd" />
+        {errors.birthday?.message && <p className="error">{errors.birthday?.message}</p>}
+        <label>好きなプログラミング言語</label>
+        <select {...register("language", { required: true })}>
+          <option value="">Select...</option>
+          <option value="Gulie">Guile</option>
+          <option value="Gauche">Gauche</option>
+          <option value="Racket">Racket</option>
+          <option value="Larceny">Larceny</option>
+          <option value="Chicken">Chicken</option>
+        </select>
+        {errors.language?.message && <p className="error">{errors.language?.message}</p>}
+        <input type="submit" />
+        <button type="button" onClick={() => reset()}>消す</button>
+      </form>
+
+      {yourAnswer}
     </>
   );
 }
-- 
cgit v1.2.3

