수정
This commit is contained in:
@@ -5,7 +5,6 @@ import 'swiper/css';
|
|||||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||||
import { UserFavorite } from '@/entities/user/model/types';
|
import { UserFavorite } from '@/entities/user/model/types';
|
||||||
import { useStore } from '@/shared/model/store';
|
import { useStore } from '@/shared/model/store';
|
||||||
import { useLocation } from 'react-router';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||||
import { useStore } from '@/shared/model/store';
|
import { useStore } from '@/shared/model/store';
|
||||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
|
||||||
import { UserFavorite } from '@/entities/user/model/types';
|
import { UserFavorite } from '@/entities/user/model/types';
|
||||||
import { RefObject, useEffect, useState } from 'react';
|
import { RefObject, useEffect, useState } from 'react';
|
||||||
import { useLocation } from 'react-router';
|
|
||||||
import { MenuItem } from '../model/types';
|
import { MenuItem } from '../model/types';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { MenuItems } from '@/entities/common/model/constant';
|
import { MenuItems } from '@/entities/common/model/constant';
|
||||||
@@ -35,7 +33,6 @@ export const MenuCategory = ({
|
|||||||
}: MenuCategoryProps) => {
|
}: MenuCategoryProps) => {
|
||||||
const { navigate } = useNavigate();
|
const { navigate } = useNavigate();
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
// const location = useLocation();
|
|
||||||
|
|
||||||
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]);
|
const [favoriteItems, setFavoriteItems] = useState<Array<UserFavorite>>([]);
|
||||||
const [menuIds, setMenuIds] = useState<Array<number | undefined>>([]);
|
const [menuIds, setMenuIds] = useState<Array<number | undefined>>([]);
|
||||||
@@ -85,9 +82,7 @@ export const MenuCategory = ({
|
|||||||
useStore.getState().UserStore.setUserFavorite(userFavorite);
|
useStore.getState().UserStore.setUserFavorite(userFavorite);
|
||||||
setChangeMenuId(`${menuId}-${checked}`);
|
setChangeMenuId(`${menuId}-${checked}`);
|
||||||
callFavoiteItems();
|
callFavoiteItems();
|
||||||
// if(location.pathname === PATHS.home){
|
|
||||||
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const callFavoiteItems = () => {
|
const callFavoiteItems = () => {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
getLocalStorage,
|
getLocalStorage,
|
||||||
setLocalStorage
|
setLocalStorage
|
||||||
} from '@/shared/lib';
|
} from '@/shared/lib';
|
||||||
import { finalizeConfig } from './utils';
|
|
||||||
import { appBridge } from '@/utils/appBridge';
|
import { appBridge } from '@/utils/appBridge';
|
||||||
import { LoginResponse } from '@/entities/user/model/types';
|
import { LoginResponse } from '@/entities/user/model/types';
|
||||||
import { getHeaderUserAgent } from '@/shared/constants/url';
|
import { getHeaderUserAgent } from '@/shared/constants/url';
|
||||||
@@ -14,7 +13,16 @@ import { useAppBridge } from '@/hooks';
|
|||||||
import { useUserInfo } from '@/entities/user/lib/use-user-info';
|
import { useUserInfo } from '@/entities/user/lib/use-user-info';
|
||||||
import { useStore } from '@/shared/model/store';
|
import { useStore } from '@/shared/model/store';
|
||||||
import { login } from '@/entities/user/api/use-login-mutation';
|
import { login } from '@/entities/user/api/use-login-mutation';
|
||||||
import { useNavigate } from 'react-router';
|
import { useNavigate } from '@/shared/lib/hooks';
|
||||||
|
|
||||||
|
const finalizeConfig = (config: InternalAxiosRequestConfig) => {
|
||||||
|
const { params, data } = config;
|
||||||
|
return {
|
||||||
|
...config,
|
||||||
|
params,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const onRequestFulfilled = (config: InternalAxiosRequestConfig) => {
|
const onRequestFulfilled = (config: InternalAxiosRequestConfig) => {
|
||||||
config.headers['Content-Type'] = 'application/json;charset=UTF-8';
|
config.headers['Content-Type'] = 'application/json;charset=UTF-8';
|
||||||
@@ -37,6 +45,7 @@ const onRequestFulfilled = (config: InternalAxiosRequestConfig) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onRequestRejected = (error: any) => {
|
const onRequestRejected = (error: any) => {
|
||||||
|
console.log('onRequestRejected --> ', error);
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,14 +56,11 @@ const onResponseFulfilled = (response: AxiosResponse) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const onResponseRejected = (error: AxiosError) => {
|
const onResponseRejected = (error: AxiosError) => {
|
||||||
|
|
||||||
console.log('onResponseRejected --> ', error);
|
console.log('onResponseRejected --> ', error);
|
||||||
console.log('error?.status -> ', error?.status, error?.status === 401)
|
|
||||||
|
|
||||||
if(error?.status === 401){
|
if(error?.status === 401){
|
||||||
if(appBridge.isNativeEnvironment()){
|
if(appBridge.isNativeEnvironment()){
|
||||||
appBridge.safeCall(() => appBridge.requestRefreshToken()).then((token: LoginResponse) => {
|
return appBridge.safeCall(() => appBridge.requestRefreshToken()).then((token: LoginResponse) => {
|
||||||
setLocalStorage(StorageKeys.TokenType, token.tokenType);
|
setLocalStorage(StorageKeys.TokenType, token.tokenType);
|
||||||
setLocalStorage(StorageKeys.AccessToken, token.accessToken);
|
setLocalStorage(StorageKeys.AccessToken, token.accessToken);
|
||||||
setLocalStorage(StorageKeys.RefreshToken, token.refreshToken);
|
setLocalStorage(StorageKeys.RefreshToken, token.refreshToken);
|
||||||
@@ -81,9 +87,7 @@ export const onResponseRejected = (error: AxiosError) => {
|
|||||||
id: 'woowahan5',
|
id: 'woowahan5',
|
||||||
password: 'nictest00'
|
password: 'nictest00'
|
||||||
};
|
};
|
||||||
login(params).then((result: LoginResponse) => {
|
return login(params).then((result: LoginResponse) => {
|
||||||
result.usrid = params.id;
|
|
||||||
|
|
||||||
setLocalStorage(StorageKeys.TokenType, result.tokenType);
|
setLocalStorage(StorageKeys.TokenType, result.tokenType);
|
||||||
setLocalStorage(StorageKeys.AccessToken, result.accessToken);
|
setLocalStorage(StorageKeys.AccessToken, result.accessToken);
|
||||||
setLocalStorage(StorageKeys.RefreshToken, result.refreshToken);
|
setLocalStorage(StorageKeys.RefreshToken, result.refreshToken);
|
||||||
@@ -92,7 +96,7 @@ export const onResponseRejected = (error: AxiosError) => {
|
|||||||
setLocalStorage(StorageKeys.MenuGrants, result.menuGrants);
|
setLocalStorage(StorageKeys.MenuGrants, result.menuGrants);
|
||||||
setLocalStorage(StorageKeys.ClientAddressIP, result.clientAddressIP);
|
setLocalStorage(StorageKeys.ClientAddressIP, result.clientAddressIP);
|
||||||
setLocalStorage(StorageKeys.Requires2FA, result.requires2FA);
|
setLocalStorage(StorageKeys.Requires2FA, result.requires2FA);
|
||||||
setLocalStorage(StorageKeys.Usrid, result.usrid);
|
setLocalStorage(StorageKeys.Usrid, params.id);
|
||||||
|
|
||||||
if(appBridge.isNativeEnvironment()){
|
if(appBridge.isNativeEnvironment()){
|
||||||
setLocalStorage(StorageKeys.DeviceId, result.deviceId);
|
setLocalStorage(StorageKeys.DeviceId, result.deviceId);
|
||||||
@@ -102,12 +106,13 @@ export const onResponseRejected = (error: AxiosError) => {
|
|||||||
useStore.getState().UserStore.setUserInfo({
|
useStore.getState().UserStore.setUserInfo({
|
||||||
...result
|
...result
|
||||||
});
|
});
|
||||||
location.reload();
|
return error.config? axios.request(error.config): null;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((_resolve, reject) => {
|
return new Promise((_resolve, reject) => {
|
||||||
if(checkIsAxiosError(error)){
|
if(checkIsAxiosError(error)){
|
||||||
// iOS의 경우 window에서 unload event가 일어날때 네트워크 에러가 발생하곤 해서 이런 케이스를 방지하기 위해 지연시킴
|
// iOS의 경우 window에서 unload event가 일어날때 네트워크 에러가 발생하곤 해서 이런 케이스를 방지하기 위해 지연시킴
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
import { InternalAxiosRequestConfig } from 'axios';
|
|
||||||
|
|
||||||
export const finalizeConfig = (config: InternalAxiosRequestConfig) => {
|
|
||||||
const { params, data } = config;
|
|
||||||
return {
|
|
||||||
...config,
|
|
||||||
params,
|
|
||||||
data,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -9,6 +9,7 @@ const globalQueryClient = new QueryClient({
|
|||||||
throwOnError: true,
|
throwOnError: true,
|
||||||
// suspense: true,
|
// suspense: true,
|
||||||
networkMode: 'always',
|
networkMode: 'always',
|
||||||
|
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
throwOnError: true,
|
throwOnError: true,
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ export const CommonErrorBoundary = (props: Props) => {
|
|||||||
const { reset } = useQueryErrorResetBoundary();
|
const { reset } = useQueryErrorResetBoundary();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary FallbackComponent={FallbackComponent} onReset={reset}>
|
<ErrorBoundary
|
||||||
{children}
|
FallbackComponent={ FallbackComponent }
|
||||||
</ErrorBoundary>
|
onReset={ reset }
|
||||||
|
>{ children }</ErrorBoundary>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { useQueryErrorResetBoundary } from '@tanstack/react-query';
|
|||||||
import { PropsWithChildren } from 'react';
|
import { PropsWithChildren } from 'react';
|
||||||
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
|
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
import { APIError } from '@/widgets/fallbacks/api-error';
|
import { APIError } from '@/widgets/fallbacks/api-error';
|
||||||
import { KickOutError } from '@/widgets/fallbacks/kick-out-error';
|
import { KickOutError } from '@/widgets/fallbacks/kick-out-error';
|
||||||
import { checkIsAxiosError, checkIsKickOutError } from '@/shared/lib/error';
|
import { checkIsAxiosError, checkIsKickOutError } from '@/shared/lib/error';
|
||||||
@@ -15,17 +14,26 @@ import { checkIsAxiosError, checkIsKickOutError } from '@/shared/lib/error';
|
|||||||
* - network
|
* - network
|
||||||
* - common
|
* - common
|
||||||
*/
|
*/
|
||||||
function FallbackComponent({ error, resetErrorBoundary }: FallbackProps) {
|
function FallbackComponent({
|
||||||
|
error,
|
||||||
|
resetErrorBoundary
|
||||||
|
}: FallbackProps) {
|
||||||
// api 에러가 아닌 경우 상위 에러 바운더리로 위임
|
// api 에러가 아닌 경우 상위 에러 바운더리로 위임
|
||||||
if(!checkIsAxiosError(error)){
|
if(!checkIsAxiosError(error)){
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(checkIsKickOutError(error)){
|
if(checkIsKickOutError(error)){
|
||||||
return <KickOutError error={error} />;
|
return (
|
||||||
|
<KickOutError error={ error } />
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
return (
|
||||||
return <APIError error={error} resetErrorBoundary={resetErrorBoundary} />;
|
<APIError
|
||||||
|
error={ error }
|
||||||
|
resetErrorBoundary={ resetErrorBoundary }
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = PropsWithChildren;
|
type Props = PropsWithChildren;
|
||||||
@@ -34,8 +42,10 @@ export const GlobalAPIErrorBoundary = ({ children }: Props) => {
|
|||||||
const { reset } = useQueryErrorResetBoundary();
|
const { reset } = useQueryErrorResetBoundary();
|
||||||
const { key } = useLocation();
|
const { key } = useLocation();
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary onReset={reset} resetKeys={[key]} FallbackComponent={FallbackComponent}>
|
<ErrorBoundary
|
||||||
{children}
|
onReset={ reset }
|
||||||
</ErrorBoundary>
|
resetKeys={ [key] }
|
||||||
|
FallbackComponent={ FallbackComponent }
|
||||||
|
>{ children }</ErrorBoundary>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,5 +6,7 @@ import { CommonError } from '@/widgets/fallbacks/common-error';
|
|||||||
type Props = PropsWithChildren;
|
type Props = PropsWithChildren;
|
||||||
|
|
||||||
export const GlobalErrorBoundary = ({ children }: Props) => {
|
export const GlobalErrorBoundary = ({ children }: Props) => {
|
||||||
return <CommonErrorBoundary FallbackComponent={CommonError}>{children}</CommonErrorBoundary>;
|
return (
|
||||||
|
<CommonErrorBoundary FallbackComponent={ CommonError }>{ children }</CommonErrorBoundary>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,12 @@ import { Dialog, DialogProps } from '@/shared/ui/dialogs/dialog';
|
|||||||
type CommonErrorProps = FallbackProps & {
|
type CommonErrorProps = FallbackProps & {
|
||||||
height?: number;
|
height?: number;
|
||||||
};
|
};
|
||||||
export const APIError = ({ error, resetErrorBoundary }: CommonErrorProps) => {
|
export const APIError = ({
|
||||||
|
error,
|
||||||
|
resetErrorBoundary
|
||||||
|
}: CommonErrorProps) => {
|
||||||
|
console.log('APIError --> ', error);
|
||||||
|
|
||||||
const { navigateBack } = useNavigate();
|
const { navigateBack } = useNavigate();
|
||||||
const msg = useMemo(() => {
|
const msg = useMemo(() => {
|
||||||
let message: Partial<DialogProps> = {
|
let message: Partial<DialogProps> = {
|
||||||
|
|||||||
@@ -6,12 +6,17 @@ import { Dialog, DialogProps } from '@/shared/ui/dialogs/dialog';
|
|||||||
type CommonErrorProps = FallbackProps & {
|
type CommonErrorProps = FallbackProps & {
|
||||||
height?: number;
|
height?: number;
|
||||||
};
|
};
|
||||||
export const CommonError = ({ error, resetErrorBoundary }: CommonErrorProps) => {
|
export const CommonError = ({
|
||||||
|
error,
|
||||||
|
resetErrorBoundary
|
||||||
|
}: CommonErrorProps) => {
|
||||||
|
console.log('CommonError --> ', error);
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(true);
|
const [isOpen, setIsOpen] = useState(true);
|
||||||
const msg = useMemo(() => {
|
const msg = useMemo(() => {
|
||||||
let message: Partial<DialogProps> = {
|
let message: Partial<DialogProps> = {
|
||||||
title: '일시적인 오류가 발생하였습니다.',
|
title: '일시적인 오류가 발생하였습니다.',
|
||||||
message: '잠시 후 다시 시도해주세요.',
|
message: '잠시 후 다시 시도해주세요.'
|
||||||
};
|
};
|
||||||
if(error?.response?.data?.message){
|
if(error?.response?.data?.message){
|
||||||
message = { message: error.response.data.message };
|
message = { message: error.response.data.message };
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ import { useEffect, useMemo } from 'react';
|
|||||||
import { NiceAxiosFallbackProps } from '@/shared/@types/error';
|
import { NiceAxiosFallbackProps } from '@/shared/@types/error';
|
||||||
import { Dialog, DialogProps } from '@/shared/ui/dialogs/dialog';
|
import { Dialog, DialogProps } from '@/shared/ui/dialogs/dialog';
|
||||||
|
|
||||||
export const KickOutError = ({ error, resetErrorBoundary }: NiceAxiosFallbackProps) => {
|
export const KickOutError = ({
|
||||||
|
error,
|
||||||
|
resetErrorBoundary
|
||||||
|
}: NiceAxiosFallbackProps) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.error('[ErrorBoundary] Kickout Error', JSON.stringify(error.response?.data));
|
console.error('[ErrorBoundary] Kickout Error', JSON.stringify(error.response?.data));
|
||||||
// clearAuthData();
|
// clearAuthData();
|
||||||
@@ -15,7 +18,9 @@ export const KickOutError = ({ error, resetErrorBoundary }: NiceAxiosFallbackPro
|
|||||||
message: '잠시 후 다시 시도해주세요.',
|
message: '잠시 후 다시 시도해주세요.',
|
||||||
};
|
};
|
||||||
if(error?.response?.data?.message){
|
if(error?.response?.data?.message){
|
||||||
message = { message: error.response.data.message };
|
message = {
|
||||||
|
message: error.response.data.message
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}, [error]);
|
}, [error]);
|
||||||
@@ -37,6 +42,7 @@ export const KickOutError = ({ error, resetErrorBoundary }: NiceAxiosFallbackPro
|
|||||||
onConfirmClick={ handleConfirm }
|
onConfirmClick={ handleConfirm }
|
||||||
onCancelClick={ handleCancel }
|
onCancelClick={ handleCancel }
|
||||||
message={ msg.message }
|
message={ msg.message }
|
||||||
|
buttonLabel={ ['취소', '재시도'] }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import { Suspense } from 'react';
|
|
||||||
|
|
||||||
import { Loading } from '@/widgets/loading/loading';
|
|
||||||
|
|
||||||
export const Loadable = (Component: React.ComponentType<any>) => {
|
|
||||||
const LoadableComponent = (props: any) => {
|
|
||||||
return (
|
|
||||||
<Suspense fallback={<Loading />}>
|
|
||||||
<Component {...props} />
|
|
||||||
</Suspense>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
LoadableComponent.displayName = `Loadable(${Component.displayName || Component.name || 'Component'})`;
|
|
||||||
|
|
||||||
return LoadableComponent;
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user