Spaces:
Sleeping
Sleeping
File size: 3,326 Bytes
17fabdd bde621d 241884b 17fabdd d76adb4 17fabdd bde621d 17fabdd d76adb4 17fabdd 241884b 17fabdd 241884b 17fabdd bde621d 17fabdd 2cdd792 abd36ff d76adb4 abd36ff bde621d abd36ff d76adb4 abd36ff d76adb4 bde621d abd36ff bde621d abd36ff 53bb58b abd36ff 2cdd792 d76adb4 2cdd792 d76adb4 2cdd792 d76adb4 241884b 2cdd792 17fabdd |
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { SubmitHandler, useForm } from "react-hook-form";
import { z } from "zod";
import { Input } from "./ui/input";
import { Button } from "./ui/button";
import { login } from "@/utils/signIn";
import { Label } from "./ui/label";
import { useState } from "react";
import { Eye, EyeOff, Loader2 } from "lucide-react";
import Link from "next/link";
const schema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
type FormFields = z.infer<typeof schema>;
const SignInForm = () => {
const [showPassword, setShowPassword] = useState(false);
const {
register,
handleSubmit,
setError,
formState: { errors, isSubmitting },
} = useForm<FormFields>({
defaultValues: {},
resolver: zodResolver(schema),
});
const onSubmit: SubmitHandler<FormFields> = async (data) => {
try {
const res = await login(data.email, data.password);
if (res && "ok" in res && !res.ok) {
setError("root", { message: res.message || "Gagal login" });
}
// On success, server action will redirect to "/".
} catch (error) {
setError("root", { message: "Terjadi kesalahan. Coba lagi." });
}
};
const togglePasswordVisibility = () => {
setShowPassword(!showPassword);
};
return (
<>
<form className="flex flex-col gap-2" onSubmit={handleSubmit(onSubmit)}>
<Label htmlFor="email" className="text-left">
Email
</Label>
<Input
{...register("email")}
placeholder="Email"
id="email"
type="email"
/>
{errors.email && (
<div className="text-left text-xs text-red-500">
{errors.email.message}
</div>
)}
<Label htmlFor="password" className="text-left">
Password
</Label>
<div className="relative">
<Input
{...register("password")}
placeholder="Password"
type={showPassword ? "text" : "password"}
id="password"
className="pr-10"
/>
<button
type="button"
onClick={togglePasswordVisibility}
className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500 hover:text-gray-700"
tabIndex={-1}
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
)}
</button>
</div>
{errors.password && (
<div className="text-left text-xs text-red-500">
{errors.password.message}
</div>
)}
<Button
disabled={isSubmitting}
type="submit"
className="mt-4 bg-orange-600 hover:bg-orange-800"
>
{isSubmitting ? "Loading..." : "Login"}
</Button>
{errors.root && (
<div className="text-xs text-red-500">{errors.root.message}</div>
)}
<div className="mt-3 text-center text-xs">
<Link
href="/forgot-password"
className="text-blue-600 hover:underline"
>
Lupa password?
</Link>
</div>
</form>
</>
);
};
export default SignInForm;
|