-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[기능구현] 회원가입 #59
[기능구현] 회원가입 #59
Changes from 7 commits
3fbe405
0618421
c5a1cd0
da4033d
22625b7
65e77c4
f00db5e
f3e5060
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import { RegisterType } from './components/register-type'; | |
import { Tos } from './components/tos'; | ||
import { FormValues } from './types'; | ||
import { BasicButton } from '@/shared/components/common/button'; | ||
import useRegister from '@/shared/hooks/useRegister'; | ||
import { Divider } from '@chakra-ui/react'; | ||
import styled from '@emotion/styled'; | ||
|
||
|
@@ -17,13 +18,26 @@ const RegisterPage = () => { | |
formState: { errors }, | ||
} = useForm<FormValues>(); | ||
|
||
// 회원가입 처리 | ||
const mutation = useRegister(); | ||
|
||
const handleUserType = (id: string) => { | ||
setUserType(id); | ||
}; | ||
|
||
const onSubmit = (data: FormValues) => { | ||
// 회원가입 api | ||
console.log(userType, data); | ||
// request 에 맞게 데이터 병합 | ||
const isSinitto = userType === 'sinitto'; | ||
|
||
const requestData = { | ||
name: data.name, | ||
phoneNumber: data.phoneNumber, | ||
email: '[email protected]', // 임시 (카카오 로그인 후 넘겨받기) | ||
isSinitto, | ||
}; | ||
console.log(requestData); | ||
// 회원가입 API 호출 | ||
mutation.mutate(requestData); | ||
}; | ||
|
||
return ( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { fetchInstance } from '../instance'; | ||
|
||
// request(요청) 타입 | ||
export type SignupReguestParams = { | ||
name: string; | ||
phoneNumber: string; | ||
email: string; | ||
isSinitto: boolean; | ||
}; | ||
|
||
// response(응답) 타입 - 성공 | ||
export type SignupResponse = { | ||
accessToken: string; | ||
refreshToken: string; | ||
isSinitto?: 'true' | 'false'; | ||
}; | ||
|
||
// 에러(아직 정확히 에러코드 확인 x) or 예외 | ||
export type SignupErrorResponse = { | ||
status: number; | ||
detail: string; | ||
}; | ||
|
||
// 공통 타입 정의 (onSuccess 내부에서 분기) | ||
export type SignupApiResponse = SignupResponse | SignupErrorResponse; | ||
|
||
export const registerUser = async ({ | ||
name, | ||
phoneNumber, | ||
email, | ||
isSinitto, | ||
}: SignupReguestParams): Promise<SignupApiResponse> => { | ||
try { | ||
// 시니또 보호자에 따라 API 엔드포인트 구분 | ||
const endpoint = isSinitto ? 'sinitto' : 'guard'; | ||
|
||
const response = await fetchInstance.post(`/api/members/${endpoint}`, { | ||
name, | ||
phoneNumber, | ||
email, | ||
isSinitto, | ||
}); | ||
if (response.status === 207) { | ||
return { | ||
status: response.status, | ||
detail: response.data.detail, | ||
} as SignupErrorResponse; // 207 (예외 - 중복 이메일) | ||
} | ||
return response.data; // 200 | ||
} catch (err) { | ||
throw new Error('회원가입 실패'); | ||
} | ||
}; |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useRegister.ts는 회원가입 페이지에서만 쓰이는데, pages/common/register 폴더 안에 /api 또는 /api/hooks를 만들어야할 것 같습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 그렇네요! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { useNavigate } from 'react-router-dom'; | ||
|
||
import { AxiosError } from 'axios'; | ||
|
||
import { RouterPath } from '@/app/routes/path'; | ||
import { | ||
SignupApiResponse, | ||
registerUser, | ||
} from '@/shared/api/auth/user-register'; | ||
import { authLocalStorage } from '@/shared/utils/storage'; | ||
import { useMutation } from '@tanstack/react-query'; | ||
|
||
const useRegister = () => { | ||
const navigate = useNavigate(); | ||
|
||
const handleSuccess = (data: SignupApiResponse) => { | ||
if ('status' in data && data.status === 207) { | ||
alert(data.detail); | ||
} else { | ||
console.log(data); | ||
if ('accessToken' in data) { | ||
authLocalStorage.set(data.accessToken); | ||
authLocalStorage.set(data.refreshToken); | ||
alert('회원가입이 완료되었습니다.'); | ||
navigate(data.isSinitto === 'true' ? RouterPath.ROOT : RouterPath.ROOT); | ||
} | ||
} | ||
}; | ||
|
||
const handleError = (error: AxiosError) => { | ||
if (error.response && error.response.data) { | ||
alert('회원가입 중 오류가 발생했습니다.'); | ||
} else { | ||
alert('회원가입 중 네트워크 오류가 발생했습니다.'); | ||
} | ||
}; | ||
|
||
const mutation = useMutation({ | ||
mutationFn: registerUser, | ||
onSuccess: handleSuccess, | ||
onError: handleError, | ||
}); | ||
|
||
return mutation; | ||
}; | ||
|
||
export default useRegister; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
type StorageKey = { | ||
accessToken?: string; | ||
}; | ||
|
||
const initStorage = <T extends keyof StorageKey>(key: T, storage: Storage) => { | ||
const storageKey = `${key}`; | ||
|
||
const get = (): StorageKey[T] => { | ||
const value = storage.getItem(storageKey); | ||
return value as StorageKey[T]; | ||
}; | ||
|
||
const set = (value: StorageKey[T]) => { | ||
if (value == undefined || value == null) { | ||
return storage.removeItem(storageKey); | ||
} | ||
const stringifiedValue = JSON.stringify(value); | ||
storage.setItem(storageKey, stringifiedValue); | ||
}; | ||
|
||
return { get, set }; | ||
}; | ||
|
||
export const authLocalStorage = initStorage('accessToken', localStorage); | ||
Comment on lines
+1
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 코드는 step2에서 강사님이 사용하신 코드 같은데, 혹시 어떤 기능을 하는지 알 수 있을까요? 제가 이 코드에 대해 잘 이해를 못해서.. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이부분은 제가 수정할게요..