Skip to content

Commit b94fd62

Browse files
committed
refactor: 회원가입 페이지 분리 및 관련 리팩토링
1 parent 22bf211 commit b94fd62

File tree

10 files changed

+565
-237
lines changed

10 files changed

+565
-237
lines changed

src/app/(auth)/login/page.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,24 @@ export default function LoginPage() {
2121
};
2222

2323
return (
24-
<div className="flex min-h-screen items-center justify-center px-4 py-12 sm:px-6 lg:px-8">
25-
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8">
24+
<div className="flex min-h-screen items-center justify-center bg-gradient-to-r from-lime-200 to-lime-300 px-4 py-12 sm:px-6 lg:px-8">
25+
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8 shadow-lg">
2626
<div>
27-
<h2 className="text-grayscale-900 mt-6 text-center text-3xl font-bold tracking-tight">로그인</h2>
28-
<p className="text-grayscale-600 mt-2 text-center text-sm">
29-
아직 계정이 없으신가요?
30-
<Link href="/signup" className="font-medium text-blue-600 hover:text-blue-500">
27+
<h2 className="text-center text-3xl font-bold tracking-tight text-gray-900">로그인</h2>
28+
<p className="mt-2 text-center text-sm text-gray-600">
29+
아직 계정이 없으신가요?{" "}
30+
<Link href="/signup" className="font-medium text-lime-600 hover:text-lime-500">
3131
회원가입하기
3232
</Link>
3333
</p>
3434
</div>
3535
<form className="mt-8 space-y-6" onSubmit={handleSubmit(onSubmit)}>
36-
<div className="space-y-4 rounded-md shadow-sm">
36+
<div className="space-y-4 rounded-md">
3737
<div>
3838
<input
3939
{...register("email")}
4040
type="email"
41-
className="text-grayscale-900 relative block w-full rounded-lg border border-grayscale-300 px-3 py-2 placeholder-grayscale-500 focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm"
41+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
4242
placeholder="이메일"
4343
/>
4444
{errors.email && <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>}
@@ -47,7 +47,7 @@ export default function LoginPage() {
4747
<input
4848
{...register("password")}
4949
type="password"
50-
className="text-grayscale-900 relative block w-full rounded-lg border border-grayscale-300 px-3 py-2 placeholder-grayscale-500 focus:border-blue-500 focus:outline-none focus:ring-blue-500 sm:text-sm"
50+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
5151
placeholder="비밀번호"
5252
/>
5353
{errors.password && <p className="mt-1 text-sm text-red-600">{errors.password.message}</p>}
@@ -58,12 +58,12 @@ export default function LoginPage() {
5858
<button
5959
type="submit"
6060
disabled={isLoginPending}
61-
className="group relative flex w-full justify-center rounded-lg bg-primary-orange-300 px-4 py-2 text-sm font-medium text-white hover:bg-primary-orange-200 focus:outline-none focus:ring-2 focus:ring-primary-orange-300 focus:ring-offset-2 disabled:bg-grayscale-100"
61+
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
6262
>
6363
{isLoginPending ? "로그인 중..." : "로그인"}
6464
</button>
6565
</div>
66-
<div className="flex">
66+
<div className="flex justify-center space-x-4">
6767
<button>
6868
<Image src="/icons/social/social_google.svg" width={72} height={72} alt="구글 로그인" />
6969
</button>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"use client";
2+
3+
import { useAuth } from "@/hooks/useAuth";
4+
import { type SignupSchema, signupSchema } from "@/schemas/authSchema";
5+
import { userRoles } from "@/constants/userRoles";
6+
import { zodResolver } from "@hookform/resolvers/zod";
7+
import Link from "next/link";
8+
import { FieldErrors, useForm } from "react-hook-form";
9+
import Image from "next/image";
10+
11+
export default function ApplicantSignupPage() {
12+
const { signup, isSignupPending } = useAuth();
13+
const {
14+
register,
15+
handleSubmit,
16+
formState: { errors },
17+
} = useForm<SignupSchema>({
18+
resolver: zodResolver(signupSchema),
19+
defaultValues: {
20+
role: userRoles.APPLICANT,
21+
phoneNumber: "",
22+
},
23+
mode: "all",
24+
});
25+
26+
const onSubmit = (data: SignupSchema) => {
27+
signup(data);
28+
};
29+
30+
return (
31+
<div className="flex min-h-screen items-center justify-center bg-gradient-to-r from-lime-200 to-lime-300 px-4 py-12 sm:px-6 lg:px-8">
32+
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8 shadow-lg">
33+
<div>
34+
<h2 className="text-center text-3xl font-bold tracking-tight text-gray-900">지원자 회원가입</h2>
35+
<p className="mt-2 text-center text-sm text-gray-600">
36+
이미 계정이 있으신가요?{" "}
37+
<Link href="/login" className="font-medium text-lime-600 hover:text-lime-500">
38+
로그인하기
39+
</Link>
40+
</p>
41+
</div>
42+
<form className="mt-8 space-y-6" onSubmit={handleSubmit(onSubmit)} noValidate>
43+
<div className="space-y-4 rounded-md">
44+
<input type="hidden" {...register("role")} value={userRoles.APPLICANT} />
45+
<div>
46+
<input
47+
{...register("email")}
48+
type="email"
49+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
50+
placeholder="이메일"
51+
/>
52+
{errors.email && <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>}
53+
</div>
54+
<div>
55+
<input
56+
{...register("name")}
57+
type="text"
58+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
59+
placeholder="이름"
60+
/>
61+
{errors.name && <p className="mt-1 text-sm text-red-600">{errors.name.message}</p>}
62+
</div>
63+
<div>
64+
<input
65+
{...register("nickname")}
66+
type="text"
67+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
68+
placeholder="닉네임"
69+
/>
70+
{errors.nickname && <p className="mt-1 text-sm text-red-600">{errors.nickname.message}</p>}
71+
</div>
72+
<div>
73+
<input
74+
{...register("password")}
75+
type="password"
76+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
77+
placeholder="비밀번호"
78+
/>
79+
{errors.password && <p className="mt-1 text-sm text-red-600">{errors.password.message}</p>}
80+
</div>
81+
<div>
82+
<input
83+
{...register("confirmPassword")}
84+
type="password"
85+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
86+
placeholder="비밀번호 확인"
87+
/>
88+
{errors.confirmPassword && <p className="mt-1 text-sm text-red-600">{errors.confirmPassword.message}</p>}
89+
</div>
90+
<div>
91+
<input
92+
{...register("phoneNumber")}
93+
type="tel"
94+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
95+
placeholder="전화번호 (예: 010-1234-5678)"
96+
/>
97+
{errors.phoneNumber && <p className="mt-1 text-sm text-red-600">{errors.phoneNumber.message}</p>}
98+
</div>
99+
</div>
100+
<div>
101+
<button
102+
type="submit"
103+
disabled={isSignupPending}
104+
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
105+
>
106+
{isSignupPending ? "회원가입 중..." : "회원가입"}
107+
</button>
108+
</div>
109+
<div className="flex justify-center space-x-4">
110+
<button>
111+
<Image src="/icons/social/social_google.svg" width={72} height={72} alt="구글 로그인" />
112+
</button>
113+
<Link
114+
href={`https://kauth.kakao.com/oauth/authorize?client_id=${process.env.NEXT_PUBLIC_KAKAO_REST_API_KEY}&redirect_uri=${process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI}&response_type=code`}
115+
>
116+
<Image src="/icons/social/social_kakao.svg" width={72} height={72} alt="카카오 로그인" />
117+
</Link>
118+
</div>
119+
</form>
120+
</div>
121+
</div>
122+
);
123+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
"use client";
2+
3+
import { useAuth } from "@/hooks/useAuth";
4+
import { type SignupSchema, signupSchema } from "@/schemas/authSchema";
5+
import { userRoles } from "@/constants/userRoles";
6+
import { zodResolver } from "@hookform/resolvers/zod";
7+
import Link from "next/link";
8+
import { useForm } from "react-hook-form";
9+
import Image from "next/image";
10+
11+
export default function OwnerSignupPage() {
12+
const { signup, isSignupPending } = useAuth();
13+
const {
14+
register,
15+
handleSubmit,
16+
formState: { errors },
17+
} = useForm<SignupSchema>({
18+
resolver: zodResolver(signupSchema),
19+
defaultValues: {
20+
role: userRoles.OWNER,
21+
storeName: "",
22+
storePhoneNumber: "",
23+
location: "",
24+
},
25+
mode: "all",
26+
});
27+
28+
const onSubmit = (data: SignupSchema) => {
29+
signup(data);
30+
};
31+
32+
return (
33+
<div className="flex min-h-screen items-center justify-center bg-gradient-to-r from-lime-200 to-lime-300 px-4 py-12 sm:px-6 lg:px-8">
34+
<div className="w-full max-w-md space-y-8 rounded-lg bg-white p-8 shadow-lg">
35+
<div>
36+
<h2 className="text-center text-3xl font-bold tracking-tight text-gray-900">사장님 회원가입</h2>
37+
<p className="mt-2 text-center text-sm text-gray-600">
38+
이미 계정이 있으신가요?{" "}
39+
<Link href="/login" className="font-medium text-lime-600 hover:text-lime-500">
40+
로그인하기
41+
</Link>
42+
</p>
43+
</div>
44+
<form className="mt-8 space-y-6" onSubmit={handleSubmit(onSubmit)} noValidate>
45+
<div className="space-y-4 rounded-md">
46+
<input type="hidden" {...register("role")} value={userRoles.OWNER} />
47+
<div>
48+
<input
49+
{...register("email")}
50+
type="email"
51+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
52+
placeholder="이메일"
53+
/>
54+
{errors.email && <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>}
55+
</div>
56+
<div>
57+
<input
58+
{...register("name")}
59+
type="text"
60+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
61+
placeholder="이름"
62+
/>
63+
{errors.name && <p className="mt-1 text-sm text-red-600">{errors.name.message}</p>}
64+
</div>
65+
<div>
66+
<input
67+
{...register("nickname")}
68+
type="text"
69+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
70+
placeholder="닉네임"
71+
/>
72+
{errors.nickname && <p className="mt-1 text-sm text-red-600">{errors.nickname.message}</p>}
73+
</div>
74+
<div>
75+
<input
76+
{...register("password")}
77+
type="password"
78+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
79+
placeholder="비밀번호"
80+
/>
81+
{errors.password && <p className="mt-1 text-sm text-red-600">{errors.password.message}</p>}
82+
</div>
83+
<div>
84+
<input
85+
{...register("confirmPassword")}
86+
type="password"
87+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
88+
placeholder="비밀번호 확인"
89+
/>
90+
{errors.confirmPassword && <p className="mt-1 text-sm text-red-600">{errors.confirmPassword.message}</p>}
91+
</div>
92+
<div>
93+
<input
94+
{...register("storeName")}
95+
type="text"
96+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
97+
placeholder="가게 이름"
98+
/>
99+
{errors.storeName && <p className="mt-1 text-sm text-red-600">{errors.storeName.message}</p>}
100+
</div>
101+
<div>
102+
<input
103+
{...register("storePhoneNumber")}
104+
type="tel"
105+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
106+
placeholder="가게 전화번호 (예: 02-1234-5678)"
107+
/>
108+
{errors.storePhoneNumber && (
109+
<p className="mt-1 text-sm text-red-600">{errors.storePhoneNumber.message}</p>
110+
)}
111+
</div>
112+
<div>
113+
<input
114+
{...register("location")}
115+
type="text"
116+
className="relative block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:border-lime-500 focus:outline-none focus:ring-lime-500 sm:text-sm"
117+
placeholder="가게 위치"
118+
/>
119+
{errors.location && <p className="mt-1 text-sm text-red-600">{errors.location.message}</p>}
120+
</div>
121+
</div>
122+
<div>
123+
<button
124+
type="submit"
125+
disabled={isSignupPending}
126+
className="group relative flex w-full justify-center rounded-lg bg-lime-600 px-4 py-2 text-sm font-medium text-white hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-lime-500 focus:ring-offset-2 disabled:bg-lime-300"
127+
>
128+
{isSignupPending ? "회원가입 중..." : "회원가입"}
129+
</button>
130+
</div>
131+
<div className="flex justify-center space-x-4">
132+
<button>
133+
<Image src="/icons/social/social_google.svg" width={72} height={72} alt="구글 로그인" />
134+
</button>
135+
<Link
136+
href={`https://kauth.kakao.com/oauth/authorize?client_id=${process.env.NEXT_PUBLIC_KAKAO_REST_API_KEY}&redirect_uri=${process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI}&response_type=code`}
137+
>
138+
<Image src="/icons/social/social_kakao.svg" width={72} height={72} alt="카카오 로그인" />
139+
</Link>
140+
</div>
141+
</form>
142+
</div>
143+
</div>
144+
);
145+
}

0 commit comments

Comments
 (0)