MystBin
/d696cbf5421765be37 Created 1 month ago...
Raw
signup-form.tsx Hide Copy Raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
"use client"; import { getInputProps, useForm } from "@conform-to/react"; import { getZodConstraint, parseWithZod } from "@conform-to/zod"; import { signup } from "~/app/actions/auth"; import { signupSchema } from "~/lib/schema/auth"; import { useActionState } from "react"; import { Button } from "./ui/button"; import { Input } from "./ui/input"; import { Label } from "./ui/label"; export function SignupForm() { const [lastResult, action, isSubmitting] = useActionState(signup, undefined); const [form, fields] = useForm({ id: "signup", lastResult, constraint: getZodConstraint(signupSchema), shouldValidate: "onBlur", onValidate({ formData }) { return parseWithZod(formData, { schema: signupSchema }); }, }); return ( <form className="flex flex-col gap-2" id={form.id} onSubmit={form.onSubmit} action={action} noValidate > <div> <Label htmlFor={fields.firstName.id}>First Name:</Label> <Input placeholder="First Name" {...getInputProps(fields.firstName, { type: "text" })} /> <p>{fields.firstName.errors?.join(", ")}</p> </div> <div> <Label htmlFor={fields.lastName.id}>Last Name:</Label> <Input placeholder="Last Name" {...getInputProps(fields.lastName, { type: "text" })} /> <p>{fields.lastName.errors?.join(", ")}</p> </div> <div> <Label htmlFor={fields.email.id}>Email:</Label> <Input placeholder="[email protected]" {...getInputProps(fields.email, { type: "email" })} /> <p>{fields.email.errors?.join(", ")}</p> </div> <div> <Label htmlFor={fields.password.id}>Password:</Label> <Input {...getInputProps(fields.password, { type: "password" })} /> <p>{fields.password.errors?.join(", ")}</p> </div> <Button className="mt-2" type="submit" disabled={isSubmitting}> Sign up </Button> </form> ); }
auth.ts Hide Copy Raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
"use server"; import { parseWithZod } from "@conform-to/zod"; import { signupSchema } from "~/lib/schema/auth"; import { signUpEmail } from "~/server/auth"; import { APIError } from "better-auth/api"; export async function signup(prevState: unknown, formData: FormData) { const submission = parseWithZod(formData, { schema: signupSchema }); if (submission.status !== "success") { return submission.reply(); } const { firstName, lastName, email, password } = submission.value; try { await signUpEmail({ body: { name: `${firstName} ${lastName}`, email, password, }, }); } catch (error) { if (error instanceof APIError) { return submission.reply({ fieldErrors: { email: ["Email already exists"] }, resetForm: false, }); } } }