From bee1bc9b0bbc9da46095b43cf4c2dce0c733ef22 Mon Sep 17 00:00:00 2001 From: cjeongmin Date: Thu, 16 May 2024 21:29:58 +0900 Subject: [PATCH 1/9] feat: Add axios interceptor setup (#83) --- src/app/layout.tsx | 1 + src/app/lib/axios.ts | 66 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/app/lib/axios.ts diff --git a/src/app/layout.tsx b/src/app/layout.tsx index fc4ca1d..109c3b8 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from 'next'; import { Inter } from 'next/font/google'; import React from 'react'; import './globals.scss'; +import './lib/axios'; import { AuthProvider, diff --git a/src/app/lib/axios.ts b/src/app/lib/axios.ts new file mode 100644 index 0000000..0963a95 --- /dev/null +++ b/src/app/lib/axios.ts @@ -0,0 +1,66 @@ +'use client'; + +import axios, { + type AxiosError, + type AxiosRequestConfig, + type AxiosResponse, +} from 'axios'; +import { useRouter } from 'next/navigation'; + +import { getUserData, postTokenRefresh, useAuthActions } from '@/features/auth'; +import { load } from '@/shared/storage'; + +let isRefreshing = false; + +axios.interceptors.response.use( + (response: AxiosResponse) => response, + async (error: AxiosError) => { + const router = useRouter(); + const { login, logout, setAuthUserData } = useAuthActions(); + + const { config, response } = error; + const originalRequest = config as AxiosRequestConfig; + + const refreshToken = load({ + type: 'local', + key: 'refreshToken', + }); + + if ( + response != null && + refreshToken != null && + response.status === 401 && + !isRefreshing + ) { + isRefreshing = true; + + return await new Promise((resolve, reject) => { + postTokenRefresh(refreshToken) + .then(({ data }) => { + if (originalRequest.headers != null) + originalRequest.headers.Authorization = `Bearer ${data.accessToken}`; + + login(data); + getUserData() + .then(({ data: user }) => { + setAuthUserData(user); + }) + .catch(err => { + console.error(err); + }); + + resolve(axios(originalRequest)); + }) + .catch(err => { + router.push('/'); + logout(); + reject(err); + }) + .finally(() => { + isRefreshing = false; + }); + }); + } + return await Promise.reject(error); + }, +); From f74c96b6d128eb3ac4b2d9ead36106b4108dc5e4 Mon Sep 17 00:00:00 2001 From: cjeongmin Date: Wed, 22 May 2024 00:51:25 +0900 Subject: [PATCH 2/9] feat: Add a message when there are no recommended mates on the main page --- src/app/pages/main-page.tsx | 76 ++++++++++++++++------- src/app/pages/mobile/mobile-main-page.tsx | 48 +++++++++----- 2 files changed, 86 insertions(+), 38 deletions(-) diff --git a/src/app/pages/main-page.tsx b/src/app/pages/main-page.tsx index 8b45947..3697bab 100644 --- a/src/app/pages/main-page.tsx +++ b/src/app/pages/main-page.tsx @@ -83,6 +83,19 @@ const styles = { display: none; } `, + mateRecommendationIsEmpty: styled.div` + color: #000; + font-family: 'Noto Sans KR'; + font-size: 1.5rem; + font-style: normal; + font-weight: 500; + line-height: normal; + + display: flex; + width: 100%; + justify-content: center; + padding-block: 2rem; + `, }; export function MainPage() { @@ -146,30 +159,45 @@ export function MainPage() { {auth?.user?.name}님의 추천 메이트 - - - {recommendationMates?.data?.map( - ({ memberId, score, nickname, location, profileImageUrl }) => ( - - - - ), - )} - - + {recommendationMates?.data != null && + recommendationMates.data.length > 0 ? ( + <> + + + {recommendationMates?.data?.map( + ({ + memberId, + score, + nickname, + location, + profileImageUrl, + }) => ( + + + + ), + )} + + + + ) : ( + + 추천되는 메이트가 없습니다. + + )} diff --git a/src/app/pages/mobile/mobile-main-page.tsx b/src/app/pages/mobile/mobile-main-page.tsx index b53457a..9071ebc 100644 --- a/src/app/pages/mobile/mobile-main-page.tsx +++ b/src/app/pages/mobile/mobile-main-page.tsx @@ -88,6 +88,19 @@ const styles = { overflow-x: auto; flex-wrap: wrap; `, + mateRecommendationIsEmpty: styled.div` + color: #000; + font-family: 'Noto Sans KR'; + font-size: 1rem; + font-style: normal; + font-weight: 500; + line-height: normal; + + display: flex; + width: 100%; + justify-content: center; + padding-block: 2rem; + `, }; export function MobileMainPage() { @@ -136,20 +149,27 @@ export function MobileMainPage() {

{auth?.user?.name}님의 추천 메이트

- - {recommendationMates?.data?.map( - ({ memberId, score, nickname, location, profileImageUrl }) => ( - - - - ), - )} - + {recommendationMates?.data != null && + recommendationMates.data.length > 0 ? ( + + {recommendationMates?.data?.map( + ({ memberId, score, nickname, location, profileImageUrl }) => ( + + + + ), + )} + + ) : ( + + 추천되는 메이트가 없습니다. + + )} ); From 7b06fab2556b1a046b0f287b70e72cca2c1d25d6 Mon Sep 17 00:00:00 2001 From: cjeongmin Date: Wed, 22 May 2024 01:00:31 +0900 Subject: [PATCH 3/9] feat: Add a message when there are no recommended mates on the posts page --- src/app/pages/main-page.tsx | 4 +- src/app/pages/mobile/mobile-main-page.tsx | 4 +- .../pages/mobile/mobile-shared-posts-page.tsx | 39 +++++++++++++------ src/app/pages/shared-posts-page.tsx | 39 +++++++++++++------ 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/app/pages/main-page.tsx b/src/app/pages/main-page.tsx index 3697bab..d58da08 100644 --- a/src/app/pages/main-page.tsx +++ b/src/app/pages/main-page.tsx @@ -168,7 +168,7 @@ export function MainPage() { onClick={handleScrollLeft} /> - {recommendationMates?.data?.map( + {recommendationMates.data.map( ({ memberId, score, @@ -195,7 +195,7 @@ export function MainPage() { ) : ( - 추천되는 메이트가 없습니다. +

추천되는 메이트가 없습니다.

)} diff --git a/src/app/pages/mobile/mobile-main-page.tsx b/src/app/pages/mobile/mobile-main-page.tsx index 9071ebc..dd49959 100644 --- a/src/app/pages/mobile/mobile-main-page.tsx +++ b/src/app/pages/mobile/mobile-main-page.tsx @@ -152,7 +152,7 @@ export function MobileMainPage() { {recommendationMates?.data != null && recommendationMates.data.length > 0 ? ( - {recommendationMates?.data?.map( + {recommendationMates.data.map( ({ memberId, score, nickname, location, profileImageUrl }) => ( ) : ( - 추천되는 메이트가 없습니다. +

추천되는 메이트가 없습니다.

)} diff --git a/src/app/pages/mobile/mobile-shared-posts-page.tsx b/src/app/pages/mobile/mobile-shared-posts-page.tsx index 0a7905f..b8b8b05 100644 --- a/src/app/pages/mobile/mobile-shared-posts-page.tsx +++ b/src/app/pages/mobile/mobile-shared-posts-page.tsx @@ -135,6 +135,16 @@ const styles = { justify-content: flex-start; } `, + noRecommendationMates: styled.div` + font-family: 'Noto Sans KR'; + font-size: 0.85rem; + font-style: normal; + font-weight: 500; + + display: flex; + width: 100%; + justify-content: center; + `, }; export function MobileSharedPostsPage() { @@ -302,17 +312,24 @@ export function MobileSharedPostsPage() { ) : ( - {recommendationMates?.data?.map( - ({ memberId, score, nickname, location, profileImageUrl }) => ( - - - - ), + {recommendationMates?.data != null && + recommendationMates.data.length > 0 ? ( + recommendationMates.data.map( + ({ memberId, score, nickname, location, profileImageUrl }) => ( + + + + ), + ) + ) : ( + +

추천되는 메이트가 없습니다.

+
)}
)} diff --git a/src/app/pages/shared-posts-page.tsx b/src/app/pages/shared-posts-page.tsx index 2d1872d..e1c9b4a 100644 --- a/src/app/pages/shared-posts-page.tsx +++ b/src/app/pages/shared-posts-page.tsx @@ -113,6 +113,16 @@ const styles = { flex-wrap: wrap; gap: 2rem 2.62rem; `, + noRecommendationMates: styled.div` + font-family: 'Noto Sans KR'; + font-size: 1.25rem; + font-style: normal; + font-weight: 500; + + display: flex; + width: 100%; + justify-content: center; + `, }; export function SharedPostsPage() { @@ -280,17 +290,24 @@ export function SharedPostsPage() { ) : ( - {recommendationMates?.data?.map( - ({ memberId, score, nickname, location, profileImageUrl }) => ( - - - - ), + {recommendationMates?.data != null && + recommendationMates.data.length > 0 ? ( + recommendationMates.data.map( + ({ memberId, score, nickname, location, profileImageUrl }) => ( + + + + ), + ) + ) : ( + +

추천되는 메이트가 없습니다.

+
)}
)} From 75d5090c2f1782334855d6d0b44a6dd3cad74483 Mon Sep 17 00:00:00 2001 From: cjeongmin Date: Wed, 22 May 2024 01:11:28 +0900 Subject: [PATCH 4/9] feat: Add a message when there are no recommended posts on the posts page --- .../pages/mobile/mobile-shared-posts-page.tsx | 60 +++++++------------ src/app/pages/shared-posts-page.tsx | 60 +++++++------------ 2 files changed, 40 insertions(+), 80 deletions(-) diff --git a/src/app/pages/mobile/mobile-shared-posts-page.tsx b/src/app/pages/mobile/mobile-shared-posts-page.tsx index b8b8b05..a03139e 100644 --- a/src/app/pages/mobile/mobile-shared-posts-page.tsx +++ b/src/app/pages/mobile/mobile-shared-posts-page.tsx @@ -22,8 +22,6 @@ import { useDormitorySharedPosts, usePaging, useSharedPosts, - type GetDormitorySharedPostsDTO, - type GetSharedPostsDTO, } from '@/features/shared'; const styles = { @@ -135,7 +133,7 @@ const styles = { justify-content: flex-start; } `, - noRecommendationMates: styled.div` + noRecommendation: styled.div` font-family: 'Noto Sans KR'; font-size: 0.85rem; font-style: normal; @@ -153,9 +151,6 @@ export function MobileSharedPostsPage() { const auth = useAuthValue(); const [selected, setSelected] = useState('hasRoom'); const [totalPageCount, setTotalPageCount] = useState(0); - const [prevSharedPosts, setPrevSharedPosts] = useState< - GetSharedPostsDTO | GetDormitorySharedPostsDTO | null - >(null); const { filter, derivedFilter, reset: resetFilter } = useSharedPostsFilter(); @@ -207,10 +202,8 @@ export function MobileSharedPostsPage() { useEffect(() => { if (selected === 'hasRoom' && sharedPosts != null) { setTotalPageCount(sharedPosts.data.totalPages); - setPrevSharedPosts(null); } else if (selected === 'dormitory' && dormitorySharedPosts != null) { setTotalPageCount(dormitorySharedPosts.data.totalPages); - setPrevSharedPosts(null); } }, [selected, dormitorySharedPosts, sharedPosts]); @@ -234,27 +227,23 @@ export function MobileSharedPostsPage() { {selected === 'hasRoom' || selected === 'dormitory' ? ( <> - {prevSharedPosts != null - ? prevSharedPosts.data.content.map(post => ( - { - router.push(`/shared/${post.id}`); - }} - /> - )) - : posts?.data.content.map(post => ( - { - router.push( - `/shared/${selected === 'hasRoom' ? 'room' : 'dormitory'}/${post.id}`, - ); - }} - /> - ))} + {posts?.data != null && posts.data.content.length > 0 ? ( + posts?.data.content.map(post => ( + { + router.push( + `/shared/${selected === 'hasRoom' ? 'room' : 'dormitory'}/${post.id}`, + ); + }} + /> + )) + ) : ( + +

추천되는 게시글이 없습니다.

+
+ )}
{posts?.data.content.length !== 0 && ( @@ -262,9 +251,6 @@ export function MobileSharedPostsPage() { direction="left" disabled={isFirstPage} onClick={() => { - if (sharedPosts != null) { - setPrevSharedPosts(sharedPosts); - } handlePrevPage(); window.scrollTo({ top: 0, behavior: 'smooth' }); }} @@ -279,9 +265,6 @@ export function MobileSharedPostsPage() {