-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpage.tsx
More file actions
133 lines (122 loc) · 4.07 KB
/
Copy pathpage.tsx
File metadata and controls
133 lines (122 loc) · 4.07 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"use client";
import Image from "next/image";
import Link from "next/link";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { loginSchema, LoginFormValues } from "@/lib/schemas/auth.schema";
import Button from "@/app/components/auth/Button";
import Input from "@/app/components/auth/Input";
export default function LoginPage() {
const [loginError, setLoginError] = useState<string | null>(null);
const [showPassword, setShowPassword] = useState(false);
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<LoginFormValues>({
resolver: zodResolver(loginSchema),
});
const onSubmit = async (data: LoginFormValues) => {
setLoginError(null);
// 가상의 로그인 실패 시나리오
await new Promise((resolve) => setTimeout(resolve, 1000));
console.log(data);
setLoginError("이메일 또는 비밀번호가 \n 올바르지 않습니다.");
};
return (
<div className="flex flex-col items-center w-full gap-8 py-10">
<Link href="/">
<Image
src="/오메추-로고-보라색버전-모자4 1.png" // public 폴더의 로고 이미지
alt="Omechu Logo"
width={139}
height={92}
priority
/>
</Link>
<form
onSubmit={handleSubmit(onSubmit)}
className="flex flex-col w-full gap-4"
>
<Input
{...register("email")}
label="이메일"
type="email"
placeholder="이메일을 입력해주세요"
error={errors.email?.message}
/>
<Input
{...register("password")}
label="비밀번호"
type={showPassword ? "text" : "password"}
placeholder="비밀번호를 입력해주세요"
error={errors.password?.message}
rightAddon={
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="p-2"
>
<Image
src={showPassword ? "/비밀번호보기.svg" : "/mdi-light_eye.svg"}
alt="toggle password visibility"
width={24}
height={24}
/>
</button>
}
/>
<div className="mt-4">
<Button
type="submit"
variant="red"
size="large"
disabled={isSubmitting}
>
{isSubmitting ? "로그인 중..." : "로그인"}
</Button>
</div>
<div className="flex items-center justify-between mt-2 text-sm text-gray-600">
<label className="flex items-center gap-1.5">
<input
type="checkbox"
className="w-4 h-4 rounded border-gray-300 text-red-500 focus:ring-red-500"
{...register("rememberMe")}
/>
<span>로그인 상태 유지</span>
</label>
<div className="flex items-center gap-2">
<Link href="/auth/find-password" className="hover:underline">
비밀번호 찾기
</Link>
<span className="text-gray-300">|</span>
<Link href="/auth/signup" className="hover:underline">
회원가입
</Link>
</div>
</div>
</form>
<div className="relative flex items-center w-full">
<hr className="w-full border-t border-gray-300" />
<span className="absolute px-2 text-xs text-gray-400 bg-[#F8D5FF] -translate-x-1/2 left-1/2">
or
</span>
</div>
<Button
variant="yellow"
size="large"
leftIcon={
<Image src="/kakao.png" alt="카카오 아이콘" width={24} height={24} />
}
>
카카오 로그인
</Button>
{loginError && (
<div className="w-full h-[70px] flex items-center justify-center text-sm text-center text-white bg-[rgba(130,130,130,0.5)] rounded-md mt-4 whitespace-pre-line">
{loginError}
</div>
)}
</div>
);
}