import { zodResolver } from "@hookform/resolvers/zod" import { SelfServiceRegistrationFlow } from "@ory/client" import { useRouter } from "next/router" import { useMemo } from "react" import { FC, useEffect, useState } from "react" import { SubmitHandler, useForm } from "react-hook-form" import { z } from "zod" import ory from "../services/ory" import FormField from "./FormField" import InlineLink from "./InlineLink" import Input from "./Input" import SubmitButton from "./SubmitButton" const PASSWORD_REGEX = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$ %^&*-]).{8,64}$/ const SignupFormSchema = z .object({ csrfToken: z.string(), username: z .string() .trim() .min(1, { message: "Username must be at least 1 character long." }) .max(16, { message: "Username can't be longer than 16 characters.." }), password: z .string() .trim() .regex( PASSWORD_REGEX, "Password must be 8-64 long and must contain a number, uppercase, lowercase and special character.", ), passwordRepeat: z.string().trim(), email: z.string().email({ message: "Not a valid email address" }).trim(), }) .refine((data) => data.password === data.passwordRepeat, { message: "Passwords do not match.", path: ["passwordRepeat"], }) type SignupFormValues = z.infer const formFields = [ { id: "username", label: "Username", type: "text" }, { id: "password", label: "Password", type: "password" }, { id: "passwordRepeat", label: "Confirm Password", type: "password" }, { id: "email", label: "Email", type: "email" }, ] const SignupForm: FC = () => { const router = useRouter() const [flow, setFlow] = useState() const { flow: flowId, return_to: returnTo } = router.query const { register, handleSubmit, formState } = useForm({ resolver: zodResolver(SignupFormSchema), }) useEffect(() => { const func = async () => { if (!router.isReady || flow) { return } let serviceFlow if (flowId) { serviceFlow = await ory.getSelfServiceRegistrationFlow(String(flowId)) } else { serviceFlow = await ory.initializeSelfServiceRegistrationFlowForBrowsers( returnTo ? String(returnTo) : undefined, ) } setFlow(serviceFlow.data) } func() }, [flowId, router, router.isReady, returnTo, flow]) const onSubmit: SubmitHandler = async (data) => { await router.push(`/signup?flow=${flow?.id}`, undefined, { shallow: true, }) try { const resp = await ory.submitSelfServiceRegistrationFlow( String(flow?.id), { csrf_token: data.csrfToken, method: "password", password: data.password, traits: { email: data.email, // username: data.username, }, }, ) console.log(resp) } catch (e) { console.log(e) } } return (
{flow && ( )}

Creating an account allows you to participate in chat, follow your favorite channels, and broadcast from your own channel.

{formFields.map((field) => ( {formState.errors[(field.id as any) || ""]?.message}

} /> ))}

By clicking Sign Up, you are agreeing to twitch-clone's{" "} Terms of Service .

) } export default SignupForm