105 lines
2.8 KiB
TypeScript
105 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { signUp } from "@/server/users";
|
|
import { z } from "zod";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { useForm } from "react-hook-form";
|
|
import toast from "react-hot-toast";
|
|
import { useState } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
const signUpFormSchema = z.object({
|
|
email: z.email(),
|
|
password: z.string().min(8),
|
|
name: z.string().min(1),
|
|
});
|
|
|
|
type SignUpForm = z.infer<typeof signUpFormSchema>;
|
|
|
|
export default function Login() {
|
|
const router = useRouter();
|
|
const [loading, setLoading] = useState(false);
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
// watch,
|
|
formState: { errors },
|
|
} = useForm<SignUpForm>({
|
|
resolver: zodResolver(signUpFormSchema),
|
|
defaultValues: {
|
|
email: "",
|
|
password: "",
|
|
name: "",
|
|
},
|
|
});
|
|
|
|
const onSubmit = async (values: SignUpForm) => {
|
|
setLoading(true);
|
|
const resp = await signUp(values);
|
|
if (!resp.success) {
|
|
toast.error(resp.message);
|
|
setLoading(false);
|
|
} else {
|
|
toast.success(resp.message);
|
|
router.push("/dashboard");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className={"flex flex-col items-center"}>
|
|
<div className={"p-5 bg-gray-100 w-2/3 rounded-md"}>
|
|
<form
|
|
className={"flex flex-col gap-y-4 items-center"}
|
|
onSubmit={handleSubmit(onSubmit)}
|
|
>
|
|
<div>
|
|
<label
|
|
htmlFor={"username"}
|
|
className={"block text-sm font-semibold"}
|
|
>
|
|
Username
|
|
</label>
|
|
<input
|
|
type={"text"}
|
|
className={"rounded-md"}
|
|
{...register("name")}
|
|
/>
|
|
<p>{errors.name ? errors.name.message : ""}</p>
|
|
</div>
|
|
<div>
|
|
<label htmlFor={"email"} className={"block text-sm font-semibold"}>
|
|
Email
|
|
</label>
|
|
<input
|
|
type={"text"}
|
|
className={"rounded-md"}
|
|
{...register("email")}
|
|
/>
|
|
<p>{errors.email ? errors.email.message : ""}</p>
|
|
</div>
|
|
<div>
|
|
<label htmlFor={"email"} className={"block text-sm font-semibold"}>
|
|
Password
|
|
</label>
|
|
<input
|
|
type={"password"}
|
|
className={"rounded-md"}
|
|
{...register("password")}
|
|
/>
|
|
<p>{errors.password ? errors.password.message : ""}</p>
|
|
</div>
|
|
{/* TODO remove cursor-pointer when "Processing..." */}
|
|
<button
|
|
type={"submit"}
|
|
className={
|
|
"border border-gray-700 rounded-md px-5 py-1 bg-green-300 hover:bg-green-200 cursor-pointer"
|
|
}
|
|
disabled={loading}
|
|
>
|
|
{loading ? "Processing..." : "Login"}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|