Skip to content

Commit 6efbf1f

Browse files
committed
Feat: 회원가입 및 로그인 페이지 개선, 이메일 중복 체크 기능 추가
1 parent 3b743f9 commit 6efbf1f

File tree

8 files changed

+65
-297
lines changed

8 files changed

+65
-297
lines changed

src/app/admin/page.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,10 @@ export default function Page() {
168168
className='dark py-[30px] px-[96px] mobile:px-[10px]'
169169
aria-label='Example table with custom cells'
170170
bottomContent={
171-
<AdminTableBottomContent page={page} totalPages={totalPages} onChangePage={(newPage) => setPage(newPage)} />
171+
<div className='relative'>
172+
<AdminTableBottomContent page={page} totalPages={totalPages} onChangePage={(newPage) => setPage(newPage)} />
173+
<div className='text-white text-base absolute right-0 bottom-0'>총 가입자 수 : {totalUsers}</div>
174+
</div>
172175
}
173176
topContent={
174177
<AdminTableTopContent searchValue={searchValue} setSearchValue={setSearchValue} onSearch={handleSearch} />

src/app/auth/signup/page.jsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export default function Signup() {
5858
}, []);
5959

6060
// 첫 번째 화면에서 다음 버튼 클릭 시 처리
61-
const handleNext = () => {
61+
const handleNext = async () => {
6262
if (!name || !email || !password || !confirmPassword) {
6363
alert("모든 칸을 채워주세요.");
6464
return;
@@ -67,11 +67,24 @@ export default function Signup() {
6767
alert("비밀번호가 일치하지 않습니다.");
6868
return;
6969
}
70-
if(email === "pwc2002"){
70+
71+
const checkEmail = await apiClient.get('/auth/check', {
72+
params: {
73+
email: email
74+
}
75+
})
76+
if(checkEmail.data.data.isDuplicated){
7177
setIsEmailValid(true);
72-
alert("이미 가입된 이메일입니다.");
7378
return;
7479
}
80+
81+
if(checkEmail.data.code != 200){
82+
alert("에러가 발생하였습니다.");
83+
return;
84+
}
85+
86+
87+
7588
if(errors.length > 0){
7689
alert("비밀번호 조건을 만족해주세요.");
7790
return;
@@ -109,6 +122,12 @@ export default function Signup() {
109122
try {
110123
const res = await apiClient.post('/auth/signup', userinfo);
111124
console.log(res);
125+
if(res.data.code == 200){
126+
console.log(res.data.message);
127+
router.push("/auth/signin");
128+
} else {
129+
alert(res.data.message);
130+
}
112131
} catch (error) {
113132
console.log(error);
114133
}
@@ -128,10 +147,10 @@ export default function Signup() {
128147

129148
return (
130149
<div className="flex flex-col w-full items-center justify-start h-screen bg-black">
131-
<div className="flex flex-col max-w-[414px] w-full h-full pt-[30px] px-5">
132-
<p className="text-white text-xl font-bold mb-2">회원가입하기</p>
150+
<div className="flex flex-col max-w-[414px] w-full h-full px-5 ">
151+
{/* <p className="text-white text-xl font-bold mb-2">회원가입하기</p> */}
133152

134-
<div className="relative w-full h-full overflow-y-scroll">
153+
<div className="relative w-full h-full overflow-y-scroll flex flex-col justify-center">
135154
<div key="screen1" className={`absolute w-full transition-all duration-500 ease-in-out transform ${isAnimating ? "-translate-x-full opacity-0" : "translate-x-0 opacity-100"}`}>
136155
<ProfileInfoForm
137156
name={name}
@@ -146,6 +165,7 @@ export default function Signup() {
146165
isEmailValid={isEmailValid}
147166
isNameDisabled={isNameDisabled}
148167
isEmailDisabled={isEmailDisabled}
168+
setIsEmailValid={setIsEmailValid}
149169
/>
150170
</div>
151171

@@ -167,7 +187,7 @@ export default function Signup() {
167187
className="text-white bg-[#EA4336] w-full h-[48px] rounded-full"
168188
style={{boxShadow: "black 0px -10px 20px 10px"}}
169189
onPress={isAnimating ? handleSignup : handleNext}
170-
isDisabled={!isAnimating && (!name || !email || !password || !confirmPassword || errors.length > 0 || password !== confirmPassword)}
190+
isDisabled={!isAnimating && (!name || !email || !password || !confirmPassword || errors.length > 0 || password !== confirmPassword || isEmailValid)}
171191
>
172192
{isAnimating ? "가입하기" : "다음"}
173193
</Button>

src/components/auth/ApiCodeGuard.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ export default function ApiCodeGuard({ children }) {
2727
if (code === 200) {
2828
setAllowed(true);
2929
} else {
30-
router.replace('/unauthorized');
30+
router.replace('/auth/signin');
3131
}
3232
}
3333
} catch (error) {
3434
if (!cancelled) {
3535
// 인터셉터에서 401/403 처리로 리다이렉트가 발생할 수 있으므로, 보조적으로 차단
36-
router.replace('/unauthorized');
36+
router.replace('/auth/signin');
3737
}
3838
} finally {
3939
if (!cancelled) {

src/components/auth/screen/AuthLogin.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export default function AuthLogin({ router, onSubmit, errors, password, setPassw
100100
>
101101
회원가입
102102
</Button>
103-
<div className='flex flex-row items-center justify-between max-w-[349px] gap-2'>
103+
{/* <div className='flex flex-row items-center justify-between max-w-[349px] gap-2'>
104104
<hr className='flex-1 border-t border-[#A8A8A8]' />
105105
<div className='px-2 text-[14px] text-[#A8A8A8]'>또는</div>
106106
<hr className='flex-1 border-t border-[#A8A8A8]' />
@@ -114,7 +114,7 @@ export default function AuthLogin({ router, onSubmit, errors, password, setPassw
114114
height={54}
115115
width={54}
116116
/>
117-
</div>
117+
</div> */}
118118
</div>
119119
);
120120
}

src/components/auth/signup/AdditionalInfoForm.jsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,20 @@ export default function AdditionalInfoForm({
9696
placeholder="전화번호를 입력해주세요 (예: 010-1234-5678)"
9797
radius="full"
9898
className="w-full"
99-
value={phoneNumber}
100-
onValueChange={setPhoneNumber}
99+
value={phoneNumber}
100+
onChange={(e) => {
101+
const value = e.target.value.replace(/[^0-9]/g, '');
102+
if (value.length <= 11) {
103+
let formattedNumber = value;
104+
if (value.length > 3) {
105+
formattedNumber = value.slice(0,3) + '-' + value.slice(3);
106+
}
107+
if (value.length > 7) {
108+
formattedNumber = formattedNumber.slice(0,8) + '-' + formattedNumber.slice(8);
109+
}
110+
setPhoneNumber(formattedNumber);
111+
}
112+
}}
101113
classNames={{
102114
label: "!pb-[10px] !text-white",
103115
inputWrapper: `h-[48px] rounded-full border-2 border-white/50 caret-white bg-transparent !transition !duration-300 !ease-in-out

src/components/auth/signup/ProfileInfoForm.jsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ export default function ProfileInfoForm({
88
password, setPassword,
99
confirmPassword, setConfirmPassword,
1010
errors, isEmailValid,
11-
isNameDisabled, isEmailDisabled
11+
isNameDisabled, isEmailDisabled, setIsEmailValid
1212
}) {
13+
14+
const emailChange = (e) => {
15+
setEmail(e.target.value);
16+
setIsEmailValid(false);
17+
}
18+
1319
return (
1420
<div className="w-full">
1521
<Input
@@ -42,7 +48,7 @@ export default function ProfileInfoForm({
4248
radius="full"
4349
className="w-full"
4450
value={email}
45-
onValueChange={setEmail}
51+
onChange={emailChange}
4652
isDisabled={isEmailDisabled}
4753
classNames={{
4854
label: "!pb-[10px] !text-white",

src/components/ui/common/MenuHeader.jsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ export default function MenuHeader() {
1414
const { apiClient, handleLogout }= useAuthenticatedApi();
1515

1616
const menuItems = [
17-
{ name: "스터디", href: "/study" },
17+
{ name: "멤버관리", href: "/admin" },
18+
{ name: "스터디", href: "#", onClick: () => alert('준비중입니다.') },
1819
{ name: "공지사항", href: "#", onClick: () => alert('준비중입니다.') },
19-
{ name: "프로젝트", href: "https://solution.gdgocinha.com" },
20-
{ name: "멤버", href: "#", onClick: () => alert('준비중입니다.') },
20+
{ name: "프로젝트", href: "#", onClick: () => alert('준비중입니다.') },
2121
{ name: "로그아웃", href: "#", onClick: handleLogout }
2222
];
2323

@@ -43,23 +43,23 @@ export default function MenuHeader() {
4343

4444
<NavbarContent className="mobile:hidden flex gap-16 ml-[70px]" justify="start">
4545
<NavbarItem>
46-
<Link color="foreground" className="text-white" href="/study">
47-
스터디
46+
<Link color="foreground" className="text-white" href="/admin" >
47+
멤버관리
4848
</Link>
4949
</NavbarItem>
5050
<NavbarItem>
5151
<Link color="foreground" className="text-white" href="#" onPress={() => alert('준비중입니다.')}>
52-
공지사항
52+
스터디
5353
</Link>
5454
</NavbarItem>
5555
<NavbarItem>
5656
<Link color="foreground" className="text-white" href="#" onPress={() => alert('준비중입니다.')}>
57-
프로젝트
57+
공지사항
5858
</Link>
5959
</NavbarItem>
6060
<NavbarItem>
6161
<Link color="foreground" className="text-white" href="#" onPress={() => alert('준비중입니다.')}>
62-
멤버
62+
프로젝트
6363
</Link>
6464
</NavbarItem>
6565
</NavbarContent>

0 commit comments

Comments
 (0)