/** biome-ignore-all lint/correctness/noChildrenProp: */ "use client"; import { type AnyFieldApi, useForm } from "@tanstack/react-form"; import Image from "next/image"; import Link from "next/link"; import { z } from "zod"; import { signUpUser } from "@/app/actions/signup"; import google from "@/public/google.svg"; import logo from "@/public/logo.svg"; import { authClient } from "@/utils/auth-client"; const signUpSchema = z .object({ name: z .string() .max(50, { message: "Name cannot be longer than 50 characters." }) .nonempty({ message: "Please enter your name." }), email: z .email({ message: "Please enter a valid email address." }) .max(40, { message: "Email cannot be longer than 40 characters." }) .nonempty({ message: "Please enter your email address." }), password: z .string() .min(8, { message: "Password must be at least 8 characters long." }) .max(30, { message: "Password cannot be longer than 30 characters." }) .nonempty({ message: "Please enter a password." }) .regex( /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/, "Ensure at least one uppercase letter, one lowercase letter, and a number in your password.", ), confirmPassword: z .string() .min(8, { message: "Please confirm your password." }) .max(30, { message: "Confirmation password cannot be longer than 30 characters.", }) .nonempty({ message: "Please confirm your password." }), }) .refine((data) => data.password === data.confirmPassword, { message: "Passwords don't match.", path: ["confirmPassword"], }); export function SignUp() { const form = useForm({ defaultValues: { name: "", email: "", password: "", confirmPassword: "", }, validators: { onChange: signUpSchema, }, onSubmit: async ({ value }) => { try { await authClient.signUp.email({ name: value.name, email: value.email, password: value.password, }); } catch (error) { // Set form error } }, }); return (
icon

Let's create your account.

or use email

{ e.preventDefault(); e.stopPropagation(); form.handleSubmit(); }} > ( <> field.handleChange(e.target.value)} placeholder="John Doe" className="px-4 py-2 rounded-lg border border-neutral-300 focus:outline-none focus:border-preply-green placeholder-neutral-400" /> )} /> ( <> field.handleChange(e.target.value)} placeholder="john@example.com" className="px-4 py-2 rounded-lg border border-neutral-300 focus:outline-none focus:border-preply-green placeholder-neutral-400" /> )} /> ( <> field.handleChange(e.target.value)} placeholder="Create a password" className="px-4 py-2 rounded-lg border border-neutral-300 focus:outline-none focus:border-preply-green placeholder-neutral-400" /> )} /> ( <> field.handleChange(e.target.value)} placeholder="Confirm your password" className="px-4 py-2 rounded-lg border border-neutral-300 focus:outline-none focus:border-preply-green placeholder-neutral-400" /> )} /> [state.canSubmit, state.isValidating]} > {([canSubmit, isValidating]) => ( )}

Already have an account?{" "} Sign in

); } function ErrorInfo({ field }: { field: AnyFieldApi }) { return ( <> {field.state.meta.isTouched && !field.state.meta.isValid && field.state.meta.errors.length > 0 ? (

{field.state.meta.errors[0].message}

) : null} {field.state.meta.isValidating ? "Validating..." : null} ); }