From 06c58f8606d4388422c93d3b2e4fe62d67020318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Fri, 18 Nov 2022 13:54:48 +0900 Subject: [PATCH 01/12] feat - add Introduction organism --- .../Main/organisms/Introduction/index.tsx | 26 +++++++++++++ .../organisms/Introduction/style.module.scss | 37 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/components/Main/organisms/Introduction/index.tsx create mode 100644 src/components/Main/organisms/Introduction/style.module.scss diff --git a/src/components/Main/organisms/Introduction/index.tsx b/src/components/Main/organisms/Introduction/index.tsx new file mode 100644 index 00000000..b090f5e6 --- /dev/null +++ b/src/components/Main/organisms/Introduction/index.tsx @@ -0,0 +1,26 @@ +import { Star } from '@atoms/icon'; +import { Bubble } from '@atoms/icon/Bubble'; +import Span from '@atoms/Span'; + +import $ from './style.module.scss'; + +function Introduction() { + return ( +
+ + re:Fashion + + + AI 기반 추천 알고리즘을 통해 상하의 코디를 매칭하고 상품 + 판매 시 AI 이미지 인식을 통해 의류를 분석하여 알찬 의류 + 정보를 제공해주는 패션 리세일 마켓입니다. + + + + + +
+ ); +} + +export default Introduction; diff --git a/src/components/Main/organisms/Introduction/style.module.scss b/src/components/Main/organisms/Introduction/style.module.scss new file mode 100644 index 00000000..fa3656f1 --- /dev/null +++ b/src/components/Main/organisms/Introduction/style.module.scss @@ -0,0 +1,37 @@ +.introduction { + position: relative; + left: calc(50% - 23px); + transform: translateX(-50%); + max-width: 432px; + padding: 23px 32px; + margin: 10px 23px; + background: $white; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); + border-radius: 20px; + + .title { + margin-bottom: 8px; + } + + .text { + line-height: 23px; + } + + .bubble { + position: absolute; + top: -13px; + right: -15px; + } + + .green-star { + position: absolute; + top: 9px; + right: -19px; + } + + .pink-star { + position: absolute; + bottom: 27px; + left: -16px; + } +} From 84e9f6f1fd820597a766c70856a8e4074d84f198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Fri, 18 Nov 2022 13:55:19 +0900 Subject: [PATCH 02/12] feat - add Bubble icon --- .../TodayRecommend/style.module.scss | 7 ++---- src/components/shared/atoms/icon/Bubble.tsx | 22 +++++++++++++++++++ src/components/shared/atoms/icon/Star.tsx | 10 ++++----- src/pages/index.tsx | 3 +++ src/store/useFilterStore.ts | 3 +-- 5 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 src/components/shared/atoms/icon/Bubble.tsx diff --git a/src/components/Main/organisms/TodayRecommend/style.module.scss b/src/components/Main/organisms/TodayRecommend/style.module.scss index 66158be0..c21cdb5d 100644 --- a/src/components/Main/organisms/TodayRecommend/style.module.scss +++ b/src/components/Main/organisms/TodayRecommend/style.module.scss @@ -1,20 +1,17 @@ .today-recommend { overflow-x: hidden; position: relative; - left: 50%; + left: calc(50% - 23px); transform: translateX(-50%); max-width: 500px; min-height: 300px; display: flex; flex-direction: column; align-items: center; - margin: 71px 0 15px; + margin: 97px 23px 15px; padding-top: 20px; border-radius: 19px; background-color: rgba($second, 0.25); - @include mobile() { - border-radius: 0; - } } .circle { diff --git a/src/components/shared/atoms/icon/Bubble.tsx b/src/components/shared/atoms/icon/Bubble.tsx new file mode 100644 index 00000000..ba274576 --- /dev/null +++ b/src/components/shared/atoms/icon/Bubble.tsx @@ -0,0 +1,22 @@ +import type { IconProps } from '#types/props'; + +function Bubble({ className, style }: IconProps) { + return ( + + + + + + ); +} +export { Bubble }; diff --git a/src/components/shared/atoms/icon/Star.tsx b/src/components/shared/atoms/icon/Star.tsx index c1882442..dc0b99f0 100644 --- a/src/components/shared/atoms/icon/Star.tsx +++ b/src/components/shared/atoms/icon/Star.tsx @@ -1,18 +1,18 @@ -import type { StyleProps } from '#types/props'; +import type { IconProps } from '#types/props'; -function Star({ className, style }: StyleProps) { +function Star({ className, style, fill, size }: IconProps) { return ( ); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 76498851..b8893b73 100755 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -6,6 +6,7 @@ import Footer from '@organisms/Footer'; import Layout from '@templates/Layout'; import MainHeader from 'src/components/Main/molecules/MainHeader'; import RecommendListHeader from 'src/components/Main/molecules/RecommendListHeader'; +import Introduction from 'src/components/Main/organisms/Introduction'; import TodayRecommend from 'src/components/Main/organisms/TodayRecommend'; import ProductItemList from 'src/components/Shop/Organisms/ProductItemList'; @@ -26,6 +27,8 @@ function Main() { + + ((set) => ({ ...filterInitialState, priceUpdate: (value: number, idx: number) => { From 899e4c4383ce1f4ece99c126e3114aba56458e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sat, 19 Nov 2022 18:49:46 +0900 Subject: [PATCH 03/12] chore - move MainHeader --- .../Main/molecules/MainHeader/index.tsx | 20 ----------- .../Main/organisms/MainHeader/index.tsx | 36 +++++++++++++++++++ .../MainHeader/style.module.scss | 0 3 files changed, 36 insertions(+), 20 deletions(-) delete mode 100644 src/components/Main/molecules/MainHeader/index.tsx create mode 100644 src/components/Main/organisms/MainHeader/index.tsx rename src/components/Main/{molecules => organisms}/MainHeader/style.module.scss (100%) diff --git a/src/components/Main/molecules/MainHeader/index.tsx b/src/components/Main/molecules/MainHeader/index.tsx deleted file mode 100644 index c7888c2c..00000000 --- a/src/components/Main/molecules/MainHeader/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import Link from 'next/link'; - -import $ from './style.module.scss'; - -function MainHeader() { - return ( -
-
-

re:Fashion

- - - -
-
- ); -} - -export default MainHeader; diff --git a/src/components/Main/organisms/MainHeader/index.tsx b/src/components/Main/organisms/MainHeader/index.tsx new file mode 100644 index 00000000..8e5567db --- /dev/null +++ b/src/components/Main/organisms/MainHeader/index.tsx @@ -0,0 +1,36 @@ +import Link from 'next/link'; + +import ErrorFallback from '@atoms/ErrorFallback'; +import Loading from '@atoms/Loading'; +import AsyncBoundary from '@templates/AsyncBoundary'; + +import UserDropDown from '../UserDropDown'; +import $ from './style.module.scss'; + +function MainHeader() { + const LoginBtn = ( + + + + ); + + return ( +
+
+

re:Fashion

+ } + errorFallback={ErrorFallback} + otherRenderComponent={LoginBtn} + includedStatusCodes={[401, 403]} + > + + +
+
+ ); +} + +export default MainHeader; diff --git a/src/components/Main/molecules/MainHeader/style.module.scss b/src/components/Main/organisms/MainHeader/style.module.scss similarity index 100% rename from src/components/Main/molecules/MainHeader/style.module.scss rename to src/components/Main/organisms/MainHeader/style.module.scss From 91295ae61e264d78eb112004bad3d034c31e6f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sat, 19 Nov 2022 18:50:23 +0900 Subject: [PATCH 04/12] feat - add UserDropDown component --- .../Main/organisms/UserDropDown/index.tsx | 52 +++++++++++++++++++ .../organisms/UserDropDown/style.module.scss | 29 +++++++++++ .../shared/atoms/icon/SelectArrow.tsx | 6 +-- .../shared/molecules/DropDown/index.tsx | 12 ++++- src/pages/index.tsx | 2 +- 5 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 src/components/Main/organisms/UserDropDown/index.tsx create mode 100644 src/components/Main/organisms/UserDropDown/style.module.scss diff --git a/src/components/Main/organisms/UserDropDown/index.tsx b/src/components/Main/organisms/UserDropDown/index.tsx new file mode 100644 index 00000000..d4786233 --- /dev/null +++ b/src/components/Main/organisms/UserDropDown/index.tsx @@ -0,0 +1,52 @@ +import { useRouter } from 'next/router'; + +import { SelectArrow } from '@atoms/icon'; +import ProfileImg from '@atoms/ProfileImg'; +import Span from '@atoms/Span'; +import { IMAGE_BLUR_DATA_URL } from '@constants/img'; +import DropDown from '@molecules/DropDown'; +import { logoutUtil } from 'src/api/login'; +import { useMyInfo } from 'src/hooks/api/profile'; + +import $ from './style.module.scss'; + +const initialProfile = { + name: '', + profileImage: IMAGE_BLUR_DATA_URL, + totalCount: '', +}; + +function UserDropDown() { + const router = useRouter(); + const { data } = useMyInfo(); + const { profileImage, name } = data?.data || initialProfile; + const profileView = ( +
+ + + {name} + +
+ ); + + const options = [ + profileView, + { name: '마이페이지', onClick: () => router.push('/mypage') }, + { + name: '계정 정보 수정', + onClick: () => router.push('/mypage/setting/user'), + }, + { name: '로그아웃', onClick: () => logoutUtil() }, + ]; + + return ( + +
+ + +
+
+ ); +} + +export default UserDropDown; diff --git a/src/components/Main/organisms/UserDropDown/style.module.scss b/src/components/Main/organisms/UserDropDown/style.module.scss new file mode 100644 index 00000000..7f53963d --- /dev/null +++ b/src/components/Main/organisms/UserDropDown/style.module.scss @@ -0,0 +1,29 @@ +.profile-container { + width: 50px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 2px; + background-color: $primary; + border-radius: 19px; + cursor: pointer; + &:hover { + background-color: rgba($primary, 0.8); + } + + .arrow { + width: 10px; + height: 8px; + margin-right: 6px; + } +} + +.profile { + display: flex; + align-items: center; + padding: 4px; + + .name { + margin-left: 6px; + } +} diff --git a/src/components/shared/atoms/icon/SelectArrow.tsx b/src/components/shared/atoms/icon/SelectArrow.tsx index 18778c2c..8d471742 100644 --- a/src/components/shared/atoms/icon/SelectArrow.tsx +++ b/src/components/shared/atoms/icon/SelectArrow.tsx @@ -1,6 +1,6 @@ -import type { StyleProps } from '#types/props'; +import type { IconProps } from '#types/props'; -function SelectArrow({ className, style }: StyleProps) { +function SelectArrow({ className, style, stroke }: IconProps) { return ( )[]; + options: (string | Partial | JSX.Element)[]; children: React.ReactNode; name: string; top?: string; @@ -20,6 +20,12 @@ type Props = { fontSize?: number; } & StyleProps; +const isReactComponent = ( + option: Props['options'][0], +): option is JSX.Element => { + return typeof option === 'object' && !('name' in option); +}; + function DropDown(selectProps: Props) { const { options, children, className } = selectProps; const { name, fontWeight, fontSize, top, right, bottom, left } = selectProps; @@ -63,6 +69,8 @@ function DropDown(selectProps: Props) { style={{ top, right, bottom, left }} > {options.map((option) => { + if (isReactComponent(option)) return option; + const isObject = typeof option === 'object'; const optionName = isObject ? option.name : option; const optionClick = isObject ? option.onClick : undefined; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index b8893b73..e31c1f3f 100755 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -4,9 +4,9 @@ import HeadMeta from '@atoms/HeadMeta'; import { seoData } from '@constants/seo'; import Footer from '@organisms/Footer'; import Layout from '@templates/Layout'; -import MainHeader from 'src/components/Main/molecules/MainHeader'; import RecommendListHeader from 'src/components/Main/molecules/RecommendListHeader'; import Introduction from 'src/components/Main/organisms/Introduction'; +import MainHeader from 'src/components/Main/organisms/MainHeader'; import TodayRecommend from 'src/components/Main/organisms/TodayRecommend'; import ProductItemList from 'src/components/Shop/Organisms/ProductItemList'; From 4af037b4e3d5bb3c700bc47c596f0fd6e52dec34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sat, 19 Nov 2022 19:36:26 +0900 Subject: [PATCH 05/12] feat - add cloneElement in DropDown component --- src/components/Main/organisms/UserDropDown/index.tsx | 9 ++++++--- src/components/shared/molecules/DropDown/index.tsx | 8 ++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/Main/organisms/UserDropDown/index.tsx b/src/components/Main/organisms/UserDropDown/index.tsx index d4786233..a5e33ca9 100644 --- a/src/components/Main/organisms/UserDropDown/index.tsx +++ b/src/components/Main/organisms/UserDropDown/index.tsx @@ -20,9 +20,12 @@ function UserDropDown() { const router = useRouter(); const { data } = useMyInfo(); const { profileImage, name } = data?.data || initialProfile; + const profileImgView = ( + + ); const profileView = ( -
- +
+ {profileImgView} {name} @@ -42,7 +45,7 @@ function UserDropDown() { return (
- + {profileImgView}
diff --git a/src/components/shared/molecules/DropDown/index.tsx b/src/components/shared/molecules/DropDown/index.tsx index 1b8a9b11..b061aeb6 100644 --- a/src/components/shared/molecules/DropDown/index.tsx +++ b/src/components/shared/molecules/DropDown/index.tsx @@ -68,8 +68,12 @@ function DropDown(selectProps: Props) { className={$['dropdown-menulist']} style={{ top, right, bottom, left }} > - {options.map((option) => { - if (isReactComponent(option)) return option; + {options.map((option, idx) => { + if (isReactComponent(option)) + return React.cloneElement(option, { + // eslint-disable-next-line react/no-array-index-key + key: `component-menu-${idx}`, + }); const isObject = typeof option === 'object'; const optionName = isObject ? option.name : option; From 00aaf1df3270912284222a03864c94cabec3aa1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sat, 19 Nov 2022 19:45:01 +0900 Subject: [PATCH 06/12] feat - add user skeleton --- src/components/Main/organisms/MainHeader/index.tsx | 5 +++-- src/components/Main/organisms/MainHeader/style.module.scss | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/Main/organisms/MainHeader/index.tsx b/src/components/Main/organisms/MainHeader/index.tsx index 8e5567db..d6598c89 100644 --- a/src/components/Main/organisms/MainHeader/index.tsx +++ b/src/components/Main/organisms/MainHeader/index.tsx @@ -1,7 +1,6 @@ import Link from 'next/link'; import ErrorFallback from '@atoms/ErrorFallback'; -import Loading from '@atoms/Loading'; import AsyncBoundary from '@templates/AsyncBoundary'; import UserDropDown from '../UserDropDown'; @@ -16,12 +15,14 @@ function MainHeader() { ); + const UserSkeleton =
; + return (

re:Fashion

} + suspenseFallback={UserSkeleton} errorFallback={ErrorFallback} otherRenderComponent={LoginBtn} includedStatusCodes={[401, 403]} diff --git a/src/components/Main/organisms/MainHeader/style.module.scss b/src/components/Main/organisms/MainHeader/style.module.scss index 3b73e451..5ac02a53 100644 --- a/src/components/Main/organisms/MainHeader/style.module.scss +++ b/src/components/Main/organisms/MainHeader/style.module.scss @@ -31,3 +31,10 @@ color: $white; } } + +.user-skeleton { + width: 54px; + height: 32px; + border-radius: 19px; + @include loading(); +} From 373129dee919b3b49bbf8216b3b40778a7dc4dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sun, 20 Nov 2022 01:12:31 +0900 Subject: [PATCH 07/12] feat - add otherRenderComponent & error handle logic in ErrorBoundary --- .../shared/atoms/ErrorFallback/index.tsx | 18 ++++++- .../shared/templates/AsyncBoundary.tsx | 9 +++- .../shared/templates/ErrorBoundary.tsx | 50 +++++++++++++++---- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/components/shared/atoms/ErrorFallback/index.tsx b/src/components/shared/atoms/ErrorFallback/index.tsx index e76c5ac1..a0dae43a 100644 --- a/src/components/shared/atoms/ErrorFallback/index.tsx +++ b/src/components/shared/atoms/ErrorFallback/index.tsx @@ -1,18 +1,32 @@ import { StyleProps } from '#types/props'; import Span from '@atoms/Span'; import classnames from 'classnames'; +import { ApiError } from 'src/api/core/error'; import $ from './style.module.scss'; type Props = { - error: Error; + error: Error | ApiError; reset: () => void; + otherRenderComponent?: React.ReactNode; + includedStatusCodes?: number[]; } & StyleProps; function ErrorFallback(props: Props) { const { error, reset, className } = props; + const { otherRenderComponent, includedStatusCodes } = props; - return ( + const isIncludeOtherRender = () => { + if ('status' in error) + return includedStatusCodes?.some((code) => error.status === code); + return false; + }; + + const otherRenderCondition = !!otherRenderComponent && isIncludeOtherRender(); + + return otherRenderCondition ? ( + otherRenderComponent + ) : (
diff --git a/src/components/shared/templates/AsyncBoundary.tsx b/src/components/shared/templates/AsyncBoundary.tsx index b718a9cf..4712235f 100644 --- a/src/components/shared/templates/AsyncBoundary.tsx +++ b/src/components/shared/templates/AsyncBoundary.tsx @@ -11,17 +11,24 @@ type Props = { suspenseFallback: ComponentProps['fallback']; errorFallback: ErrorBoundaryProps['errorFallback']; keys?: Array; + otherRenderComponent?: React.ReactNode; + includedStatusCodes?: number[]; }; function AsyncBoundary(props: PropsWithChildren) { const { suspenseFallback, errorFallback, children, keys } = props; + const { otherRenderComponent, includedStatusCodes } = props; const { reset } = useQueryErrorResetBoundary(); const resetHandler = useCallback(() => { reset(); }, [reset]); return ( - + {children} ); diff --git a/src/components/shared/templates/ErrorBoundary.tsx b/src/components/shared/templates/ErrorBoundary.tsx index e23cb2c9..d8ee5146 100644 --- a/src/components/shared/templates/ErrorBoundary.tsx +++ b/src/components/shared/templates/ErrorBoundary.tsx @@ -1,8 +1,19 @@ +import { NextRouter, withRouter } from 'next/router'; + import React, { ReactElement } from 'react'; +import { isInstanceOfAPIError } from 'src/api/core/error'; +import NotFoundPage from 'src/pages/404'; + type ErrorFallbackProps = { error: ErrorType; reset: (...args: unknown[]) => void; + otherRenderComponent?: React.ReactNode; + includedStatusCodes?: number[]; +}; + +type WithRouterProps = { + router: NextRouter; }; type ErrorFallbackType = ( @@ -10,11 +21,13 @@ type ErrorFallbackType = ( ) => React.ReactNode; type Props = { - resetQuery?: () => void; errorFallback: ErrorFallbackType; children: ReactElement; + resetQuery?: () => void; keys?: unknown[]; -}; + otherRenderComponent?: React.ReactNode; + includedStatusCodes?: number[]; +} & WithRouterProps; type State = { hasError: boolean; @@ -34,7 +47,7 @@ const changedArray = ( ); }; -export default class ErrorBoundary extends React.Component { +class ErrorBoundary extends React.Component { constructor(props: Props) { super(props); this.state = initialState; @@ -65,16 +78,31 @@ export default class ErrorBoundary extends React.Component { render() { const { hasError, error } = this.state; - const { errorFallback } = this.props; - const { children } = this.props; - - if (hasError && error !== null) { - return errorFallback({ - error, - reset: this.resetBoundary, - }); + const { errorFallback, router } = this.props; + const { children, otherRenderComponent, includedStatusCodes } = this.props; + + if (isInstanceOfAPIError(error)) { + const { redirectUrl, notFound } = error; + const renderCondition = !redirectUrl || otherRenderComponent; + if (redirectUrl && !otherRenderComponent) { + router.replace(redirectUrl); + } + if (notFound) { + return ; + } + + if (hasError && error !== null && renderCondition) { + return errorFallback({ + error, + reset: this.resetBoundary, + otherRenderComponent, + includedStatusCodes, + }); + } } return children; } } + +export default withRouter(ErrorBoundary); From 7f662160d5033086545551cbd1b1dba14aba9b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sun, 20 Nov 2022 01:14:28 +0900 Subject: [PATCH 08/12] feat - add 500 error img --- .../shared/templates/NotFound/index.tsx | 18 ++++++++++++++---- src/pages/_error.tsx | 13 ++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/components/shared/templates/NotFound/index.tsx b/src/components/shared/templates/NotFound/index.tsx index 476a6a59..c7c10cda 100644 --- a/src/components/shared/templates/NotFound/index.tsx +++ b/src/components/shared/templates/NotFound/index.tsx @@ -6,18 +6,28 @@ import { IMAGE_BLUR_DATA_URL } from '@constants/img'; import $ from './style.module.scss'; -function NotFound() { +type Props = { + title?: string; + img?: string; + alt?: string; +}; + +function NotFound(props: Props) { + const { title, img, alt } = props; const router = useRouter(); const handleClick = () => router.back(); return ( <> - +
404 Not Found; +function CustomErrorComponent() { + const props = { + title: '500 server error', + img: 'https://user-images.githubusercontent.com/62797441/202860611-d4b97a7b-7f38-4ce7-a3b2-9af800877250.png', + alt: '500 server error', + }; + return ; } CustomErrorComponent.getInitialProps = async (contextData: NextPageContext) => { await Sentry.captureUnderscoreErrorException(contextData); - return NextErrorComponent.getInitialProps(contextData); }; export default CustomErrorComponent; From 72bf4e9f5b925873084640135bb1a7c0f028052f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sun, 20 Nov 2022 01:14:45 +0900 Subject: [PATCH 09/12] chore - change util name --- src/hooks/api/core/index.ts | 10 +++++----- src/utils/{errorHandler.ts => axiosErrorHandler.ts} | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) rename src/utils/{errorHandler.ts => axiosErrorHandler.ts} (90%) diff --git a/src/hooks/api/core/index.ts b/src/hooks/api/core/index.ts index f10ede4f..bc978e62 100644 --- a/src/hooks/api/core/index.ts +++ b/src/hooks/api/core/index.ts @@ -13,7 +13,7 @@ import type { } from '@tanstack/react-query'; import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'; import type { AxiosError } from 'axios'; -import { errorHandler } from 'src/utils/errorHandler'; +import { axiosErrorHandler } from 'src/utils/axiosErrorHandler'; export function useCoreQuery( keyName: QueryKey, @@ -26,8 +26,8 @@ export function useCoreQuery( const router = useRouter(); return useQuery(keyName, query, { onError: (err) => { - errorHandler(err, router); - return console.error(err); + axiosErrorHandler(err, router); + console.error(err); }, ...options, }); @@ -40,8 +40,8 @@ export function useCoreMutation( const router = useRouter(); return useMutation(mutation, { onError: (err) => { - errorHandler(err, router); - return console.error(err); + axiosErrorHandler(err, router); + console.error(err); }, ...options, }); diff --git a/src/utils/errorHandler.ts b/src/utils/axiosErrorHandler.ts similarity index 90% rename from src/utils/errorHandler.ts rename to src/utils/axiosErrorHandler.ts index 734c9e73..d1036ccd 100644 --- a/src/utils/errorHandler.ts +++ b/src/utils/axiosErrorHandler.ts @@ -5,7 +5,7 @@ import { AxiosError } from 'axios'; import { isInstanceOfAPIError } from 'src/api/core/error'; import { toastError } from 'src/utils/toaster'; -export function errorHandler(err: AxiosError, router: NextRouter) { +export function axiosErrorHandler(err: AxiosError, router: NextRouter) { if (isInstanceOfAPIError(err)) { const { redirectUrl, notFound, status, code } = err; const isStatus403 = status === 403; From c64464dfd135e7b19e34b53def802bd663afb3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sun, 20 Nov 2022 02:17:48 +0900 Subject: [PATCH 10/12] feat - add useMyUser hook --- src/components/Main/organisms/UserDropDown/index.tsx | 4 ++-- src/hooks/api/profile/index.ts | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/components/Main/organisms/UserDropDown/index.tsx b/src/components/Main/organisms/UserDropDown/index.tsx index a5e33ca9..ade0a5bc 100644 --- a/src/components/Main/organisms/UserDropDown/index.tsx +++ b/src/components/Main/organisms/UserDropDown/index.tsx @@ -6,7 +6,7 @@ import Span from '@atoms/Span'; import { IMAGE_BLUR_DATA_URL } from '@constants/img'; import DropDown from '@molecules/DropDown'; import { logoutUtil } from 'src/api/login'; -import { useMyInfo } from 'src/hooks/api/profile'; +import { useMyUser } from 'src/hooks/api/profile'; import $ from './style.module.scss'; @@ -18,7 +18,7 @@ const initialProfile = { function UserDropDown() { const router = useRouter(); - const { data } = useMyInfo(); + const { data } = useMyUser(); const { profileImage, name } = data?.data || initialProfile; const profileImgView = ( diff --git a/src/hooks/api/profile/index.ts b/src/hooks/api/profile/index.ts index 9b49939a..795f0382 100644 --- a/src/hooks/api/profile/index.ts +++ b/src/hooks/api/profile/index.ts @@ -13,6 +13,16 @@ export function useMyInfo() { return response; } +export function useMyUser() { + const response = useCoreQuery(queryKey.myInfo, () => getMyInfo(), { + suspense: true, + onError: (err) => { + console.log(err); + }, + }); + return response; +} + export function useUserInfo(id: string) { const response = useCoreQuery(queryKey.userInfo(id), () => getUserInfo(id), { suspense: true, From b42481c486aa7081e34480a022e67118b5587f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sun, 20 Nov 2022 02:50:17 +0900 Subject: [PATCH 11/12] feat - add ErrorBoundary renderCondition --- src/api/login/index.ts | 4 ++-- src/components/Main/organisms/UserDropDown/index.tsx | 8 +++++++- src/components/shared/templates/ErrorBoundary.tsx | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/api/login/index.ts b/src/api/login/index.ts index a73a9b14..a1dbe6c5 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -27,8 +27,8 @@ export const logout = async () => { export const logoutUtil = () => { toastSuccess({ message: '로그아웃되었습니다.' }); deleteAccessToken(); - queryClient.invalidateQueries(['userInfo']); - queryClient.invalidateQueries(queryKey.myInfo); + queryClient.removeQueries(['userInfo']); + queryClient.removeQueries(queryKey.myInfo); }; export const authTest = async () => { diff --git a/src/components/Main/organisms/UserDropDown/index.tsx b/src/components/Main/organisms/UserDropDown/index.tsx index ade0a5bc..23e6481f 100644 --- a/src/components/Main/organisms/UserDropDown/index.tsx +++ b/src/components/Main/organisms/UserDropDown/index.tsx @@ -39,7 +39,13 @@ function UserDropDown() { name: '계정 정보 수정', onClick: () => router.push('/mypage/setting/user'), }, - { name: '로그아웃', onClick: () => logoutUtil() }, + { + name: '로그아웃', + onClick: () => { + logoutUtil(); + router.replace('/'); + }, + }, ]; return ( diff --git a/src/components/shared/templates/ErrorBoundary.tsx b/src/components/shared/templates/ErrorBoundary.tsx index d8ee5146..c855c3bf 100644 --- a/src/components/shared/templates/ErrorBoundary.tsx +++ b/src/components/shared/templates/ErrorBoundary.tsx @@ -82,8 +82,11 @@ class ErrorBoundary extends React.Component { const { children, otherRenderComponent, includedStatusCodes } = this.props; if (isInstanceOfAPIError(error)) { - const { redirectUrl, notFound } = error; - const renderCondition = !redirectUrl || otherRenderComponent; + const { redirectUrl, notFound, status } = error; + const isIncludeOtherStatus = includedStatusCodes?.some( + (code) => code === status, + ); + const renderCondition = !redirectUrl || isIncludeOtherStatus; if (redirectUrl && !otherRenderComponent) { router.replace(redirectUrl); } From c50c1e9c936c93c8c3ba80def87c9fc948f5af72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=99=EB=8F=99=EC=9D=B4?= Date: Sun, 20 Nov 2022 04:00:08 +0900 Subject: [PATCH 12/12] feat - change redirect condition & removeQueries when logout --- src/api/login/index.ts | 1 + src/components/shared/templates/ErrorBoundary.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api/login/index.ts b/src/api/login/index.ts index a1dbe6c5..421313f5 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -29,6 +29,7 @@ export const logoutUtil = () => { deleteAccessToken(); queryClient.removeQueries(['userInfo']); queryClient.removeQueries(queryKey.myInfo); + queryClient.removeQueries(['myItemList']); }; export const authTest = async () => { diff --git a/src/components/shared/templates/ErrorBoundary.tsx b/src/components/shared/templates/ErrorBoundary.tsx index c855c3bf..1bb1275b 100644 --- a/src/components/shared/templates/ErrorBoundary.tsx +++ b/src/components/shared/templates/ErrorBoundary.tsx @@ -87,7 +87,7 @@ class ErrorBoundary extends React.Component { (code) => code === status, ); const renderCondition = !redirectUrl || isIncludeOtherStatus; - if (redirectUrl && !otherRenderComponent) { + if (redirectUrl && !isIncludeOtherStatus) { router.replace(redirectUrl); } if (notFound) {