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;