Skip to content

Commit

Permalink
Feat: 404, 500 페이지 구현 및 에러 처리 (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
gahyuun authored Jan 25, 2024
1 parent 2078e92 commit 5244600
Show file tree
Hide file tree
Showing 20 changed files with 501 additions and 203 deletions.
120 changes: 103 additions & 17 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,52 +56,138 @@ function App() {
path={ROUTES.SIGNUP_SUCCESS}
element={accessToken ? <Navigate to="/" /> : <SignUpSuccess />}
/>
<Route path={ROUTES.TOSS_SUCCESS} element={<TossSuccess />} />
<Route path={ROUTES.TOSS_FAIL} element={<TossFail />} />
<Route path={ROUTES.INIT} element={<Init />} />
<Route element={<InitLayout />}>
<Route
path={ROUTES.TOSS_SUCCESS}
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <TossSuccess />
}
/>
<Route
path={ROUTES.TOSS_FAIL}
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <TossFail />
}
/>
<Route
path={ROUTES.INIT}
element={!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <Init />}
/>
<Route
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <InitLayout />
}
>
<Route
path={ROUTES.INIT_ACCOMMODATION_REGISTRATION}
element={<InitAccommodationRegistration />}
element={
!accessToken ? (
<Navigate to={ROUTES.SIGNIN} />
) : (
<InitAccommodationRegistration />
)
}
/>
<Route
path={ROUTES.INIT_ROOM_REGISTRATION}
element={<InitRoomRegistration />}
element={
!accessToken ? (
<Navigate to={ROUTES.SIGNIN} />
) : (
<InitRoomRegistration />
)
}
/>
<Route
path={ROUTES.INIT_INFO_CONFIRMATION}
element={<InitInfoConfirmation />}
element={
!accessToken ? (
<Navigate to={ROUTES.SIGNIN} />
) : (
<InitInfoConfirmation />
)
}
/>
</Route>
{/* 레이아웃 적용 페이지 */}
<Route element={<RootLayout />}>
<Route path={ROUTES.POINT_DETAIL} element={<PointDetail />} />
<Route
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <RootLayout />
}
>
<Route
path={ROUTES.POINT_DETAIL}
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <PointDetail />
}
/>
<Route
path={`/:accommodationId${ROUTES.COUPON}`}
element={<Coupon />}
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <Coupon />
}
/>
<Route
path={'/'}
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <MainRedirect />
}
/>
<Route path={'/'} element={<MainRedirect />} />
<Route
path={`/:accommodationId${ROUTES.COUPON_REGISTRATION}`}
element={<CouponRegistration />}
element={
!accessToken ? (
<Navigate to={ROUTES.SIGNIN} />
) : (
<CouponRegistration />
)
}
/>

<Route path={`/:accommodationId${ROUTES.MAIN}`} element={<Main />} />
<Route path={`/:accommodationId${ROUTES.ROOM}`} element={<Room />} />
<Route
path={`/:accommodationId${ROUTES.MAIN}`}
element={!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <Main />}
/>
<Route
path={`/:accommodationId${ROUTES.ROOM}`}
element={!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <Room />}
/>
<Route element={<RoomLayout />}>
<Route
path={`/:accommodationId${ROUTES.ROOM_REGISTRATION}`}
element={<RoomRegistration />}
element={
!accessToken ? (
<Navigate to={ROUTES.SIGNIN} />
) : (
<RoomRegistration />
)
}
/>
</Route>
<Route element={<RoomLayout />}>
<Route
path={`/:accommodationId/:roomId${ROUTES.ROOM_UPDATE}`}
element={<RoomUpdate />}
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <RoomUpdate />
}
/>
</Route>
<Route path={ROUTES.USER_GUIDE} element={<UserGuide />} />
<Route
path={ROUTES.USER_GUIDE}
element={
!accessToken ? <Navigate to={ROUTES.SIGNIN} /> : <UserGuide />
}
/>
</Route>
<Route
path={'/*'}
element={
!accessToken ? (
<Navigate to={ROUTES.SIGNIN} />
) : (
<RootLayout isError={true} />
)
}
/>
</Routes>
</Router>
);
Expand Down
1 change: 0 additions & 1 deletion src/api/coupon/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Response } from '@/types/api';
import { instance } from '..';
import {
BuyCouponData,
Expand Down
49 changes: 27 additions & 22 deletions src/api/index.tsx → src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import axios from 'axios';
import { HTTP_STATUS_CODE } from '../constants/api';
import { HTTP_STATUS_CODE, RESPONSE_CODE } from '../constants/api';
import { getCookie, removeCookie, setCookie } from '@hooks/sign-in/useSignIn';
import { REFRESH_API } from './refresh';
import { message } from 'antd';
import { ROUTES } from '@/constants/routes';
import { isAccessTokenExpired } from '@/utils/refresh';

export const instance = axios.create({
// baseURL: '',
baseURL: process.env.REACT_APP_SERVER_URL,
timeout: 5000,
headers: {
Expand All @@ -28,34 +25,42 @@ instance.interceptors.request.use(
async (config) => {
const accessToken = getCookie('accessToken');
if (accessToken) {
const isTokenExpired = isAccessTokenExpired(accessToken);
if (isTokenExpired) {
try {
const res = await REFRESH_API.postRefresh({
accessToken: accessToken,
refreshToken: getCookie('refreshToken') as string,
});
config.headers['Authorization'] = `Bearer ${res.data.accessToken}`;
setCookie('accessToken', res.data.accessToken);
setCookie('refreshToken', res.data.refreshToken);
} catch (refreshError) {
console.log('재발급 실패');
}
} else {
config.headers['Authorization'] = `Bearer ${accessToken}`;
}
config.headers['Authorization'] = `Bearer ${accessToken}`;
}
return config;
},
(error) => {
// 여기 뺐습니다.
return Promise.reject(error);
},
);

instance.interceptors.response.use(
(response) => response,
(error) => {
async (error) => {
if (error.response?.status === HTTP_STATUS_CODE.UNAUTHORIZED) {
if (error.response?.data && 'code' in error.response.data) {
// 리프레시 토큰이 유효하지 않을 때
if (error.response.data.code === RESPONSE_CODE.INVALID_REFRESH_TOKEN) {
message.error('로그인 만료 입니다.');
handleUnauthorized();
}
} else {
const accessToken = getCookie('accessToken');
if (accessToken) {
const res = await REFRESH_API.postRefresh({
accessToken: accessToken,
refreshToken: getCookie('refreshToken') as string,
});
setCookie('accessToken', res.data.accessToken);
setCookie('refreshToken', res.data.refreshToken);
} else {
removeCookie('accessToken');
removeCookie('refreshToken');
removeCookie('accommodationId');
window.location.replace('/signin');
}
}
}
return Promise.reject(error);
},
);
14 changes: 13 additions & 1 deletion src/components/coupon/not-found-coupon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { ROUTES } from '@/constants/routes';
import { TextBox } from '@components/text-box';
import { Button } from 'antd';
import { useNavigate, useParams } from 'react-router-dom';
import styled from 'styled-components';

export const NotFoundCoupon = () => {
const navigate = useNavigate();
const { accommodationId } = useParams();
const handleNavigateCouponRegistration = () => {
navigate(`/${accommodationId}${ROUTES.COUPON_REGISTRATION}`);
};
return (
<StyledLayout>
<StyledTextBox>
Expand All @@ -14,7 +21,12 @@ export const NotFoundCoupon = () => {
</TextBox>
</StyledTextBox>
<StyledButton type="primary">
<TextBox fontWeight={700} typography="h5" color="white">
<TextBox
fontWeight={700}
typography="h5"
color="white"
onClick={handleNavigateCouponRegistration}
>
쿠폰 만들기
</TextBox>
</StyledButton>
Expand Down
80 changes: 80 additions & 0 deletions src/components/error/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { ROUTES } from '@/constants/routes';
import { ACCOMMODATION_API } from '@api/accommodation';
import { TextBox } from '@components/text-box';
import { getCookie, setCookie } from '@hooks/sign-in/useSignIn';
import { Button } from 'antd';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';

export const NotFound = () => {
const navigate = useNavigate();
const handleNavigate = async () => {
const accommodationId = getCookie('accommodationId');
if (accommodationId) {
navigate(`/${accommodationId}${ROUTES.MAIN}`);
return;
}
const { data } = await ACCOMMODATION_API.getAccommodationList();
const hasAccommodationData = data.accommodations.length > 0;
const accommodationIdData = data.accommodations[0].id;
if (hasAccommodationData && accommodationIdData) {
setCookie('accommodationId', accommodationIdData.toString());
navigate(`/${accommodationIdData}${ROUTES.MAIN}`);
return;
}
navigate(ROUTES.INIT);
};
return (
<StyledLayout>
<StyledContainer>
<div>
<TextBox typography="h2" fontWeight={700} color="primary">
빨리잡아!&nbsp;
</TextBox>
<TextBox typography="h2" fontWeight={700}>
쿠폰센터
</TextBox>
</div>
<TextBox typography="h3" fontWeight={400} color="black700">
페이지를 찾을 수 없습니다.
</TextBox>
</StyledContainer>
<StyledButton type="primary">
<TextBox
typography="h5"
fontWeight={700}
color="white"
onClick={handleNavigate}
>
홈화면으로 이동
</TextBox>
</StyledButton>
</StyledLayout>
);
};

const StyledLayout = styled.main`
margin: 0 auto;
width: 374px;
height: calc(100vh - 56px);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 48px;
`;

const StyledContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
`;

const StyledButton = styled(Button)`
width: 100%;
height: 54px;
padding: 12px 32px;
`;
Loading

0 comments on commit 5244600

Please sign in to comment.