diff --git a/src/apis/auth.ts b/src/apis/auth.ts index 60ba8f4d..8244a9b4 100644 --- a/src/apis/auth.ts +++ b/src/apis/auth.ts @@ -1,30 +1,9 @@ import type { PostSigninRequestType, PostSigninResponseType } from '@/schema/auth'; -import { AxiosError } from 'axios'; import httpClient from '.'; const postSignin = async (request: PostSigninRequestType): Promise => { - try { - const response = await httpClient.post('/auth/signIn', request); - return response.data; - } catch (error) { - if (error instanceof AxiosError) { - // Axios 에러인 경우 - const axiosError = error as AxiosError; - if (axiosError.response) { - // 서버에서 응답이 온 경우 (예: 4xx, 5xx) - throw new Error('로그인 요청 처리 중 문제가 발생했습니다.'); - } else if (axiosError.request) { - // 요청을 보냈지만 응답을 받지 못한 경우 - throw new Error('서버 응답을 받지 못했습니다. 잠시 후 다시 시도해 주세요.'); - } else { - // 요청을 설정하는 과정에서 문제가 발생한 경우 - throw new Error('로그인 요청을 처리하는 동안 문제가 발생했습니다.'); - } - } else { - // Axios 에러가 아닌 경우 (네트워크 문제 등) - throw new Error('알 수 없는 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.'); - } - } + const response = await httpClient.post('/auth/signIn', request); + return response.data; }; export default postSignin; diff --git a/src/apis/index.ts b/src/apis/index.ts index a1b6aaec..4167407d 100644 --- a/src/apis/index.ts +++ b/src/apis/index.ts @@ -27,23 +27,26 @@ httpClient.interceptors.response.use( if (!refreshToken) { window.location.href = '/auth/SignIn'; - } else { - httpClient - .post('/auth/refresh-token', null, { - headers: { Authorization: `Bearer ${refreshToken}` }, - }) - .then((response) => { - const { accessToken } = response.data; - const { refreshToken: newRefreshToken } = response.data; - localStorage.setItem('accessToken', accessToken); - localStorage.setItem('refreshToken', newRefreshToken); - }) - .catch(() => { - window.location.href = '/auth/SignIn'; - }); + return Promise.reject(error); } - } else { - throw new Error(error.response.status); + + return httpClient + .post('/auth/refresh-token', null, { + headers: { Authorization: `Bearer ${refreshToken}` }, + }) + .then((response) => { + const { accessToken, refreshToken: newRefreshToken } = response.data; + localStorage.setItem('accessToken', accessToken); + localStorage.setItem('refreshToken', newRefreshToken); + + const originalRequest = error.config; + return httpClient(originalRequest); + }) + .catch(() => { + window.location.href = '/auth/SignIn'; + return Promise.reject(error); + }); } + return Promise.reject(error); }, ); diff --git a/src/hooks/useSignInMutation.ts b/src/hooks/useSignInMutation.ts new file mode 100644 index 00000000..eaf9fd76 --- /dev/null +++ b/src/hooks/useSignInMutation.ts @@ -0,0 +1,22 @@ +import postSignin from '@/apis/auth'; +import { toast } from '@/components/ui/use-toast'; +import { useMutation } from '@tanstack/react-query'; +import { useRouter } from 'next/router'; + +const useSigninMutation = () => { + const router = useRouter(); + + return useMutation({ + mutationFn: postSignin, + onSuccess: (data) => { + localStorage.setItem('accessToken', data.accessToken); + localStorage.setItem('refreshToken', data.refreshToken); + router.push('/'); + }, + onError: () => { + toast({ description: '이메일 혹은 비밀번호를 확인해주세요.', className: 'border-state-error text-state-error font-semibold' }); + }, + }); +}; + +export default useSigninMutation; diff --git a/src/hooks/userQueryHooks.ts b/src/hooks/userQueryHooks.ts index 005fcf8c..7c28fe75 100644 --- a/src/hooks/userQueryHooks.ts +++ b/src/hooks/userQueryHooks.ts @@ -1,10 +1,8 @@ -import postSignin from '@/apis/auth'; import quries from '@/apis/queries'; import { updateMe } from '@/apis/user'; import { GetUserReponseType, GetUserRequestType, PatchMeRequestType } from '@/schema/user'; import { MutationOptions } from '@/types/query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; -import { useRouter } from 'next/router'; export const useMeQuery = () => useQuery(quries.user.getMe()); @@ -23,21 +21,3 @@ export const useUpdateMe = (options: MutationOptions) => { }, }); }; - -export const useSignin = () => { - const router = useRouter(); - - return useMutation({ - mutationFn: postSignin, - onSuccess: (data) => { - localStorage.setItem('accessToken', data.accessToken); - localStorage.setItem('refreshToken', data.refreshToken); - router.push('/'); - }, - onError: (error) => { - // NOTE: 임시 테스트용 콘솔, 토스트 추가 예정 - /* eslint-disable no-console */ - console.error(error); - }, - }); -}; diff --git a/src/pageLayout/AuthLayout/AuthLayout.tsx b/src/pageLayout/AuthLayout/AuthLayout.tsx deleted file mode 100644 index 3cc64aa7..00000000 --- a/src/pageLayout/AuthLayout/AuthLayout.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { ReactNode } from 'react'; - -export default function AuthLayout({ children }: { children: ReactNode }) { - return
{children}
; -} diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 37d2f8d3..107acf01 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -3,6 +3,7 @@ import '@/styles/globals.css'; import type { AppProps } from 'next/app'; import { HydrationBoundary, QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import Toaster from '@/components/ui/toaster'; export default function App({ Component, pageProps }: AppProps) { const [queryClient] = React.useState(() => new QueryClient()); @@ -10,6 +11,7 @@ export default function App({ Component, pageProps }: AppProps) { + diff --git a/src/pages/auth/SignIn.tsx b/src/pages/auth/SignIn.tsx index d19775e1..400d0edd 100644 --- a/src/pages/auth/SignIn.tsx +++ b/src/pages/auth/SignIn.tsx @@ -1,16 +1,15 @@ import Image from 'next/image'; import Link from 'next/link'; -import AuthLayout from '@/pageLayout/AuthLayout/AuthLayout'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@/components/ui/form'; import { PostSigninRequest, PostSigninRequestType } from '@/schema/auth'; -import { useSignin } from '@/hooks/userQueryHooks'; +import useSigninMutation from '@/hooks/useSignInMutation'; export default function SignIn() { - const mutationSignin = useSignin(); + const mutationSignin = useSigninMutation(); // 폼 정의 const form = useForm({ resolver: zodResolver(PostSigninRequest), @@ -21,13 +20,9 @@ export default function SignIn() { }, }); - function onSubmit(values: PostSigninRequestType) { - mutationSignin.mutate(values); - } - // TODO: 나중에 컴포넌트 분리하기 return ( - +
logo @@ -35,7 +30,7 @@ export default function SignIn() {
- + mutationSignin.mutate(values))} className='flex flex-col items-center lg:gap-6 gap-5 w-full px-6'>
- +
); }