diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/SignUp.css | 10 | ||||
| -rw-r--r-- | src/SignUp.tsx | 64 | 
2 files changed, 74 insertions, 0 deletions
| diff --git a/src/SignUp.css b/src/SignUp.css index e69de29..602ed0a 100644 --- a/src/SignUp.css +++ b/src/SignUp.css @@ -0,0 +1,10 @@ +.SignUpForm { +    display: flex; +    flex-direction: column; +    gap: 15px; +} + +.error { +    margin: 0; +    color: red; +} 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}      </>    );  } | 
