From 464799650db6f25c031c8067c031f728f3b0942f Mon Sep 17 00:00:00 2001 From: yeyounging <133792082+yeyounging@users.noreply.github.com> Date: Fri, 29 Nov 2024 20:21:54 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=ED=9B=85=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/core.ts | 42 +++++++++++++++++++++++++++++++++++++---- src/app/auth/auth.ts | 19 +++++++++++++++++++ src/app/mypage/page.tsx | 8 +++----- 3 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 src/app/auth/auth.ts diff --git a/src/api/core.ts b/src/api/core.ts index 1edc787..e723950 100644 --- a/src/api/core.ts +++ b/src/api/core.ts @@ -8,7 +8,9 @@ import axios, { } from 'axios' import Cookies from 'js-cookie' import { ACCESS_TOKEN, HTTP_METHODS } from '@/constants' -import { BaseResponse } from './types' +import { useLogout } from '@/app/auth/auth' +import { useRouter } from 'next/navigation' +import { BaseResponse, ErrorResponse } from './types' const axiosInstance: AxiosInstance = axios.create({ baseURL: '/v1', @@ -35,11 +37,43 @@ axiosInstance.interceptors.request.use( ) axiosInstance.interceptors.response.use( (response: AxiosResponse) => response.data, - async (error: AxiosError) => { + async (error: AxiosError): Promise => { + const { push } = useRouter() + const { logout } = useLogout() + if (!error.response) { - return Promise.reject(error) + alert('네트워크 오류가 발생했습니다. 다시 시도해 주세요.') + throw { + success: false, + timestamp: new Date(), + statusCode: 0, + code: 'NETWORK_ERROR', + message: 'Network Error', + } as ErrorResponse + } + + const { status: statusCode } = error.response + const message = + (error.response.data as { message?: string })?.message || + 'An error occurred' + const code = + (error.response.data as { code?: string })?.code || 'UNKNOWN_ERROR' + if (statusCode === 401) { + alert('인증이 만료되었습니다. 다시 로그인해 주세요.') + logout() + push('/') + } else if (statusCode === 500) { + alert('서버에서 오류가 발생했습니다. 잠시 후 다시 시도해 주세요.') + } else { + alert(message || '오류가 발생했습니다.') } - return Promise.reject(error.response.data) + throw { + success: false, + timestamp: new Date(), + statusCode, + code, + message, + } as ErrorResponse }, ) diff --git a/src/app/auth/auth.ts b/src/app/auth/auth.ts new file mode 100644 index 0000000..34d5459 --- /dev/null +++ b/src/app/auth/auth.ts @@ -0,0 +1,19 @@ +import Cookies from 'js-cookie' +import useUserInfo from '@/store/useUserInfo' +import { useRouter } from 'next/navigation' + +export const useLogout = () => { + const { push } = useRouter() + const { deleteUserInfo } = useUserInfo() + + const logout = () => { + deleteUserInfo() + Object.keys(Cookies.get()).forEach((cookieName) => { + Cookies.remove(cookieName) + }) + + push('/') + } + + return { logout } +} diff --git a/src/app/mypage/page.tsx b/src/app/mypage/page.tsx index e24913c..bb87c5a 100644 --- a/src/app/mypage/page.tsx +++ b/src/app/mypage/page.tsx @@ -1,6 +1,5 @@ 'use client' -import Cookies from 'js-cookie' import { Button, HeaderWithBack, IconRight, Pencil, Switch } from '@/components' import useUserInfo from '@/store/useUserInfo' import { useRouter } from 'next/navigation' @@ -8,6 +7,7 @@ import Image from 'next/image' import { useState } from 'react' import { useMyPageContext } from './components/fetcher' import { usePatchAlarm } from './api/queries' +import { useLogout } from '../auth/auth' export default function MyPage() { const { nickname, profileImage } = useUserInfo().userInfo @@ -15,7 +15,7 @@ export default function MyPage() { const { isEmailNotificationEnabled, email } = useMyPageContext() const { mutate } = usePatchAlarm() - const { deleteUserInfo } = useUserInfo() + const { logout } = useLogout() const [isEmailAlert, setIsEmailAlert] = useState(isEmailNotificationEnabled) @@ -92,9 +92,7 @@ export default function MyPage() { type="submit" className="px-20 py-16" onClick={() => { - deleteUserInfo() - Cookies.remove('accessToken') - push('/') + logout() }} > 로그아웃