Skip to content

Commit 3012189

Browse files
committed
feat: 회원가입 기능 구현
1 parent 5a50fa7 commit 3012189

File tree

4 files changed

+128
-12
lines changed

4 files changed

+128
-12
lines changed

src/apis/authApis.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ interface SignInParams {
44
email: string;
55
password: string;
66
}
7+
8+
interface SignUpParams {
9+
name: string;
10+
nickName: string;
11+
phone: string;
12+
email: string;
13+
password: string;
14+
pwCheck: string;
15+
useTermsCheck: boolean;
16+
privacyTermsCheck: boolean;
17+
}
18+
719
export const signIn = async ({ email, password }: SignInParams) => {
820
const { data, error } = await supabase.auth.signInWithPassword({
921
email: email,
@@ -15,3 +27,22 @@ export const signIn = async ({ email, password }: SignInParams) => {
1527

1628
return data;
1729
};
30+
31+
export const signUp = async ({ name, nickName, phone, email, password }: SignUpParams) => {
32+
const { data, error } = await supabase.auth.signUp({
33+
email: email,
34+
password: password,
35+
options: {
36+
data: {
37+
name: name,
38+
nickName: nickName,
39+
phone: phone,
40+
},
41+
},
42+
});
43+
if (error) {
44+
throw error;
45+
}
46+
47+
return data;
48+
};

src/apis/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { signIn as signIn } from './authApis.ts';
1+
export { signIn as signIn, signUp as signUp } from './authApis.ts';

src/components/Join/JoinButton.tsx

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,97 @@
11
import { useJoinState } from '../../stores/joinStore';
2+
import { isValidName, isValidFormatPhone, isValidEmail, isValidPassword, isValidPwCheck } from '@/utils/authUtils.ts';
3+
import { useRef, useState } from 'react';
4+
import useSignUp from '@/react-queries/useSignUp';
5+
import { isAuthError } from '@supabase/supabase-js';
6+
import { useNavigate } from 'react-router-dom';
7+
import { Loading } from '@/pages';
8+
import Dialog from '../Dialog';
9+
10+
interface DialogElement {
11+
openModal: () => void;
12+
closeModal: () => void;
13+
}
14+
15+
const messages = {
16+
NAME_ISVAILD_ERROR: '이름은 두글자 이상 입력 가능합니다.',
17+
PHONE_ISVAILD_ERROR: '휴대폰 번호를 정확히 입력해주세요.',
18+
PWCHECK_ISVAILD_ERROR: '비밀번호 확인을 진행해주세요.',
19+
EMAIL_PASSWORD_ISVAILD_ERROR: '이메일 또는 비밀번호 형식이 잘못되었습니다.',
20+
TERMS_ISVAILD_ERROR: '개인정보 수집 및 이용약관에 동의해주세요.',
21+
AUTH_ERROR: '이미 가입한 계정이 있습니다. 계정을 확인해주세요.',
22+
};
223

324
const JoinButton = () => {
4-
const { name, phone, email, password, pwCheck, useTermsCheck, privacyTermsCheck } = useJoinState();
25+
const { nickName, name, phone, email, password, pwCheck, useTermsCheck, privacyTermsCheck } = useJoinState();
26+
const { mutate, isPending } = useSignUp();
27+
const navigate = useNavigate();
28+
const dialogRef = useRef<DialogElement | null>(null);
29+
const [dialogMessage, setDialogMessage] = useState('');
530

631
const onClick = () => {
7-
console.log('name: ', name);
8-
console.log('phone: ', phone);
9-
console.log('email: ', email);
10-
console.log('password: ', password);
11-
console.log('pwCheck: ', pwCheck);
12-
console.log('useTermsCheck: ', useTermsCheck);
13-
console.log('privacyTermsCheck: ', privacyTermsCheck);
32+
if (!isValidEmail(email) || !isValidPassword(password)) {
33+
setDialogMessage(messages.EMAIL_PASSWORD_ISVAILD_ERROR);
34+
dialogRef.current?.openModal();
35+
return;
36+
}
37+
38+
if (!isValidName(name)) {
39+
setDialogMessage(messages.NAME_ISVAILD_ERROR);
40+
dialogRef.current?.openModal();
41+
return;
42+
}
43+
44+
if (!isValidFormatPhone(phone)) {
45+
setDialogMessage(messages.PHONE_ISVAILD_ERROR);
46+
dialogRef.current?.openModal();
47+
return;
48+
}
49+
50+
if (!isValidPwCheck(password, pwCheck)) {
51+
setDialogMessage(messages.PWCHECK_ISVAILD_ERROR);
52+
dialogRef.current?.openModal();
53+
return;
54+
}
55+
56+
if (!useTermsCheck || !privacyTermsCheck) {
57+
setDialogMessage(messages.TERMS_ISVAILD_ERROR);
58+
dialogRef.current?.openModal();
59+
return;
60+
}
61+
62+
mutate(
63+
{
64+
name,
65+
nickName,
66+
phone,
67+
email,
68+
password,
69+
pwCheck: '',
70+
useTermsCheck: false,
71+
privacyTermsCheck: false,
72+
},
73+
{
74+
onError: (error) => {
75+
if (isAuthError(error)) {
76+
setDialogMessage(messages.AUTH_ERROR);
77+
dialogRef.current?.openModal();
78+
}
79+
},
80+
onSuccess: () => {
81+
navigate('/*');
82+
},
83+
},
84+
);
1485
};
1586

1687
return (
17-
<button type={'submit'} onClick={onClick} className="btn btn-outline btn-primary w-full">
18-
회원가입 하기
19-
</button>
88+
<>
89+
<button type={'submit'} onClick={onClick} className="btn btn-outline btn-primary w-full">
90+
회원가입 하기
91+
</button>
92+
<Dialog ref={dialogRef} desc={dialogMessage}></Dialog>
93+
{isPending && <Loading size={'lg'} color={'primary'} display={'spinner'} />}
94+
</>
2095
);
2196
};
2297

src/react-queries/useSignUp.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { useMutation } from '@tanstack/react-query';
2+
import { signUp } from '@/apis';
3+
4+
const useSignUp = () =>
5+
useMutation({
6+
mutationKey: ['signUp'],
7+
mutationFn: signUp,
8+
});
9+
10+
export default useSignUp;

0 commit comments

Comments
 (0)