Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ Feat ] 에러 처리를 위한 Error-boundary 적용 #184

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"^@/shared/types/(.*)$",
"^@/shared/constants/(.*)$",
"^@/shared/assets/(.*)$",
"^@/router/(.*)$",
"^@/(.*)$",
"^[./]"
],
Expand Down
11 changes: 7 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import { Provider } from 'jotai';

import { RouterProvider } from 'react-router-dom';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { QueryClientProvider } from '@tanstack/react-query';

import { router } from './Router';
import { queryClient } from '@/shared/apis/queryClient';

const queryClient = new QueryClient();
import router from './router/Router';
import GlobalErrorBoundary from './shared/components/ErrorBoundary/GlobalErrorBoundary';

const App = () => {
return (
<QueryClientProvider client={queryClient}>
<Provider>
<RouterProvider router={router} />
<GlobalErrorBoundary>
<RouterProvider router={router} />
</GlobalErrorBoundary>
</Provider>
</QueryClientProvider>
);
Expand Down
33 changes: 0 additions & 33 deletions src/Router.tsx

This file was deleted.

24 changes: 13 additions & 11 deletions src/pages/HomePage/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import { getDailyCategoryTask, isTaskExist, splitTasksByCompletion } from '@/sha

import { Task } from '@/shared/types/home';

import { ROUTES } from '@/shared/constants/router';

import BellIcon from '@/shared/assets/svgs/bell.svg?react';
import FriendSettingIcon from '@/shared/assets/svgs/friend_setting.svg?react';
import LargePlusIcon from '@/shared/assets/svgs/large_plus.svg?react';

import { ROUTES_CONFIG } from '@/router/routesConfig';

import HomePageWrapper from '@/components/templates/HomePageWrapper';

import ButtonSVG from '../../shared/components/ButtonSVG';
Expand Down Expand Up @@ -126,7 +126,7 @@ const HomePage = () => {

createTodayTodos(dataToPost, {
onSuccess: () => {
navigate(ROUTES.timer.path);
navigate(ROUTES_CONFIG.timer.path);
},
});
};
Expand All @@ -148,6 +148,16 @@ const HomePage = () => {
<div className={addTodayTodoOverlayStyle}>
<SideBarHome />
</div>

<div className={`absolute right-[4.4rem] top-[5.4rem] flex gap-[0.8rem] ${addTodayTodoOverlayStyle}`}>
<button>
<FriendSettingIcon className="rounded-[1.6rem] hover:bg-gray-bg-04 active:bg-gray-bg-05" />
</button>
<button>
<BellIcon className="rounded-[1.6rem] hover:bg-gray-bg-04 active:bg-gray-bg-05" />
</button>
</div>

<div className="flex h-full w-full justify-between p-[4.2rem]">
<section>
<div className={addTodayTodoOverlayStyle}>
Expand Down Expand Up @@ -216,14 +226,6 @@ const HomePage = () => {
</section>
<section className="flex items-end justify-end">
<div className="flex flex-col">
<div className={`mb-[4.4rem] flex justify-end ${addTodayTodoOverlayStyle}`}>
<ButtonSVG>
<FriendSettingIcon className="rounded-[1.6rem] hover:bg-gray-bg-04 active:bg-gray-bg-05" />
</ButtonSVG>
<ButtonSVG>
<BellIcon className="rounded-[1.6rem] hover:bg-gray-bg-04 active:bg-gray-bg-05" />
</ButtonSVG>
</div>
<BoxTodayTodo
time={targetTime}
addingTodayTodoStatus={addingTodayTodoStatus}
Expand Down
44 changes: 44 additions & 0 deletions src/pages/NotFoundPage/NotFoundPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useNavigate } from 'react-router-dom';

import { HomeLargeBtnVariant } from '@/shared/types/global';

import NotFoundIcon from '@/shared/assets/svgs/404.svg?react';
import BellIcon from '@/shared/assets/svgs/bell.svg?react';
import FriendSettingIcon from '@/shared/assets/svgs/friend_setting.svg?react';

import HomeLargeBtn from '@/components/atoms/HomeLargeBtn';

import SideBarHome from '../HomePage/components/SideBarHome';

const NotFoundPage = () => {
const navigate = useNavigate();

return (
<div className="relative flex h-screen bg-gray-bg-01">
<SideBarHome />

<div className="absolute right-[4.4rem] top-[5.4rem] flex gap-[0.8rem]">
<button>
<FriendSettingIcon className="rounded-[1.6rem] hover:bg-gray-bg-04 active:bg-gray-bg-05" />
</button>
<button>
<BellIcon className="rounded-[1.6rem] hover:bg-gray-bg-04 active:bg-gray-bg-05" />
</button>
</div>

<div className="flex w-full flex-col items-center">
<NotFoundIcon className="mt-[35.65rem]" />
<h2 className="title-bold-36 mt-[7.75rem] text-white">페이지를 찾을 수 없습니다.</h2>
<p className="title-med-32 text-white">올바른 URL을 입력하였는지 확인하세요.</p>

<div className="mt-[4.4rem]">
<HomeLargeBtn onClick={() => navigate('/home')} variant={HomeLargeBtnVariant.LARGE}>
홈으로 돌아가기
</HomeLargeBtn>
</div>
</div>
</div>
);
};

export default NotFoundPage;
4 changes: 2 additions & 2 deletions src/pages/RedirectPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom';

// import { useLocation } from 'react-router-dom';
// import { useSignUp } from '@/shared/apis/auth/queries';
import { ROUTES } from '@/shared/constants/router';
import { ROUTES_CONFIG } from '@/router/routesConfig';

const RedirectPage = () => {
//Todo: 서버 이슈로 로그인 관련 로직 앱잼 끝나고 사용
Expand All @@ -29,7 +29,7 @@ const RedirectPage = () => {
// }, [error, navigate, data]);

useEffect(() => {
navigate(ROUTES.home.path, { replace: true });
navigate(ROUTES_CONFIG.home.path, { replace: true });
}, [navigate]);

return <div>RedirectPage</div>;
Expand Down
63 changes: 63 additions & 0 deletions src/router/Router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { Router } from '@remix-run/router';

import { Outlet, createBrowserRouter } from 'react-router-dom';

import HomePage from '@/pages/HomePage/HomePage';
import LoginPage from '@/pages/LoginPage';
import NotFoundPage from '@/pages/NotFoundPage/NotFoundPage';
import TimerPage from '@/pages/TimerPage/TimerPage';

import RedirectPage from '../pages/RedirectPage';
import { ROUTES_CONFIG } from './routesConfig';

const ProtectedRoute = () => {
//Todo: 개발이 진행되면 실제 토큰 상태를 받아서 login page로 이동 시킴
// const accessToken = getAccessTotken();
// if (!accessToken) {
// alert('로그인 해주세요');
// return <Navigate to="/login" replace />;
// }
return <Outlet />;
};

const router: Router = createBrowserRouter([
{
//public 라우트들
path: '/',
element: <Outlet />,
children: [
{
path: ROUTES_CONFIG.login.path,
element: <LoginPage />,
},
{
path: ROUTES_CONFIG.redirect.path,
element: <RedirectPage />,
},
],
},

{
//권한이 있어야 접근 가능한 라우트들
path: '/',
element: <ProtectedRoute />,
children: [
{
path: ROUTES_CONFIG.home.path,
element: <HomePage />,
},
{
path: ROUTES_CONFIG.timer.path,
element: <TimerPage />,
},
],
},

{
//404 페이지
path: '*',
element: <NotFoundPage />,
},
]);

export default router;
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
export const ROUTES = {
export const ROUTES_CONFIG = {
login: {
title: 'Login',
path: '/',
},
home: {
title: 'Home',
path: '/home',
},
timer: {
title: 'Timer',
path: '/timer',
},
redirect: {
title: 'Redirect',
path: '/redirect',
},
};
7 changes: 4 additions & 3 deletions src/shared/apis/client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';

import { ROUTES } from '@/shared/constants/router';
import { getAccessTotken } from '@/shared/utils/token';

import { ROUTES_CONFIG } from '@/router/routesConfig';

// import { reissueToken } from './auth/axios';

const API_URL = `${import.meta.env.VITE_BASE_URL}`;
Expand All @@ -29,7 +30,7 @@ const addAuthInterceptor = (axiosClient: AxiosInstance) => {
axiosClient.interceptors.request.use(async (config) => {
const accessToken = getAccessTotken();
if (!accessToken) {
window.location.href = ROUTES.login.path;
window.location.href = ROUTES_CONFIG.login.path;
}

config.headers.Authorization = `Bearer ${accessToken}`;
Expand All @@ -47,7 +48,7 @@ const addAuthInterceptor = (axiosClient: AxiosInstance) => {
// try {
// reissueToken();
// } catch (reissueError) {
// window.location.href = ROUTES.login.path;
// window.location.href = ROUTES_CONFIG.login.path;
// }
// }
// return Promise.reject(e);
Expand Down
12 changes: 12 additions & 0 deletions src/shared/apis/queryClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { QueryClient } from '@tanstack/react-query';

export const queryClient = new QueryClient({
defaultOptions: {
queries: {
throwOnError: true,
},
mutations: {
throwOnError: true,
},
},
});
14 changes: 14 additions & 0 deletions src/shared/assets/svgs/404.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/shared/assets/svgs/error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading