Skip to content

Commit

Permalink
[Feature] - 상수화 작업 진행 (#188)
Browse files Browse the repository at this point in the history
* refactor: route path 상수화 추가

1. 여행 계획, 여행기에 대한 route path 형태 변경(optional 형태로 id를 받는 함수 형태)

2. navigate 함수 내 하드 코딩 된 url 값 상수화

3. ROUTE_PATHS_MAP으로 변경

* refactor: storage key 상수화

* refactor: api endpoint 상수화

* refactor: status code 관련 map(record) constants 디렉터리로 이동

* refactor: 쿼리키 상수화

* refactor: api endpoint 내 detail 네이밍 빠진 부분 추가

* refactor: 에러 메시지 상수화
  • Loading branch information
jinyoung234 authored Aug 2, 2024
1 parent 94ab563 commit e3c65c7
Show file tree
Hide file tree
Showing 27 changed files with 147 additions and 74 deletions.
18 changes: 6 additions & 12 deletions frontend/src/apis/ApiError.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from "axios";

const HTTP_STATUS = {
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
INTERNAL_SERVER_ERROR: 500,
} as const;
import { HTTP_STATUS_CODE_MAP } from "@constants/httpStatusCode";

class ApiError<T = unknown> extends Error implements AxiosError<T> {
config: InternalAxiosRequestConfig;
Expand All @@ -23,23 +17,23 @@ class ApiError<T = unknown> extends Error implements AxiosError<T> {
const errorStatus = error.response?.status || 0;
let name = "ApiError";

if (errorStatus === HTTP_STATUS.BAD_REQUEST) {
if (errorStatus === HTTP_STATUS_CODE_MAP.BAD_REQUEST) {
name = "ApiBadRequestError";
}

if (errorStatus === HTTP_STATUS.UNAUTHORIZED) {
if (errorStatus === HTTP_STATUS_CODE_MAP.UNAUTHORIZED) {
name = "ApiUnauthorizedError";
}

if (errorStatus === HTTP_STATUS.FORBIDDEN) {
if (errorStatus === HTTP_STATUS_CODE_MAP.FORBIDDEN) {
name = "ApiForbiddenError";
}

if (errorStatus === HTTP_STATUS.NOT_FOUND) {
if (errorStatus === HTTP_STATUS_CODE_MAP.NOT_FOUND) {
name = "ApiNotFoundError";
}

if (errorStatus === HTTP_STATUS.INTERNAL_SERVER_ERROR) {
if (errorStatus === HTTP_STATUS_CODE_MAP.INTERNAL_SERVER_ERROR) {
name = "ApiInternalServerError";
}

Expand Down
10 changes: 6 additions & 4 deletions frontend/src/apis/interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import type { User } from "@type/domain/user";

import ApiError from "@apis/ApiError";

import { ROUTE_PATHS } from "@constants/route";
import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";
import { ROUTE_PATHS_MAP } from "@constants/route";
import { STORAGE_KEYS_MAP } from "@constants/storage";

export const checkAccessToken = (
config: InternalAxiosRequestConfig,
accessToken: string | null,
) => {
if (!accessToken) {
alert("로그인이 필요합니다.");
window.location.href = ROUTE_PATHS.login;
alert(ERROR_MESSAGE_MAP.api.login);
window.location.href = ROUTE_PATHS_MAP.login;
}

return config;
Expand All @@ -32,7 +34,7 @@ export const setAuthorizationHeader = (
};

export const handlePreviousRequest = (config: InternalAxiosRequestConfig) => {
const user: User | null = JSON.parse(localStorage.getItem("tourootUser") ?? "{}");
const user: User | null = JSON.parse(localStorage.getItem(STORAGE_KEYS_MAP.user) ?? "{}");
let newConfig = { ...config };

newConfig = checkAccessToken(config, user?.accessToken ?? null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { createContext, useContext } from "react";

import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";

export const AccordionItemContext = createContext<string>("");

export const useAccordionItemContext = () => {
const context = useContext(AccordionItemContext);
if (!context) {
throw new Error("Provider 바깥에 존재합니다!");
throw new Error(ERROR_MESSAGE_MAP.provider);
}

return context;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { createContext, useContext } from "react";

import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";

interface AccordionContextConfig {
value: Set<string>;
handleToggleAccordion: (item: string) => void;
Expand All @@ -10,7 +12,7 @@ export const AccordionContext = createContext<AccordionContextConfig | null>(nul
export const useAccordionContext = () => {
const context = useContext(AccordionContext);
if (!context) {
throw new Error("Provider 바깥에 존재합니다!");
throw new Error(ERROR_MESSAGE_MAP.provider);
}

return context;
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/common/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { createContext, useContext, useState } from "react";

import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";

import * as S from "./Drawer.styled";

interface DrawerContextType {
Expand All @@ -14,7 +16,7 @@ const DrawerContext = createContext<DrawerContextType | undefined>(undefined);
const useDrawerContext = () => {
const context = useContext(DrawerContext);
if (!context) {
throw new Error("Drawer Provider가 없습니다.");
throw new Error(ERROR_MESSAGE_MAP.provider);
}
return context;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useNavigate } from "react-router-dom";
// import { UserContext } from "@contexts/UserProvider";
import Icon from "@components/common/Icon/Icon";

import { ROUTE_PATHS } from "@constants/route";
import { ROUTE_PATHS_MAP } from "@constants/route";

import { PRIMITIVE_COLORS } from "@styles/tokens";

Expand All @@ -26,7 +26,7 @@ const FloatingButton = () => {
// alert("여행기 작성 전 로그인을 먼저 해주세요!");
// return;
// }
navigate(ROUTE_PATHS.travelogueRegister);
navigate(ROUTE_PATHS_MAP.travelogueRegister);
};

const handleClickShareButton = () => {};
Expand Down
16 changes: 8 additions & 8 deletions frontend/src/components/common/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import IconButton from "@components/common/IconButton/IconButton";

import useUser from "@hooks/useUser";

import { ROUTE_PATHS } from "@constants/route";
import { ROUTE_PATHS_MAP } from "@constants/route";

import theme from "@styles/theme";
import { PRIMITIVE_COLORS } from "@styles/tokens";
Expand All @@ -21,21 +21,21 @@ const Header = () => {
const navigate = useNavigate();

const handleClickButton =
pathName === ROUTE_PATHS.root || pathName === ROUTE_PATHS.login
? () => navigate(ROUTE_PATHS.root)
: () => navigate(-1);
pathName === ROUTE_PATHS_MAP.root || pathName === ROUTE_PATHS_MAP.login
? () => navigate(ROUTE_PATHS_MAP.root)
: () => navigate(ROUTE_PATHS_MAP.back);

const { user } = useUser();

return (
<Drawer>
<S.HeaderLayout>
<IconButton
color={pathName === ROUTE_PATHS.root ? theme.colors.primary : PRIMITIVE_COLORS.black}
color={pathName === ROUTE_PATHS_MAP.root ? theme.colors.primary : PRIMITIVE_COLORS.black}
onClick={handleClickButton}
iconType={pathName === ROUTE_PATHS.root ? "korean-logo" : "back-icon"}
iconType={pathName === ROUTE_PATHS_MAP.root ? "korean-logo" : "back-icon"}
/>
{pathName === ROUTE_PATHS.login ? (
{pathName === ROUTE_PATHS_MAP.login ? (
<>
<S.HeaderTitle>로그인</S.HeaderTitle>
<S.HiddenDiv />
Expand Down Expand Up @@ -67,7 +67,7 @@ const Header = () => {
) : (
<S.MenuItem
onClick={() => {
navigate(ROUTE_PATHS.login);
navigate(ROUTE_PATHS_MAP.login);
}}
>
로그인
Expand Down
16 changes: 9 additions & 7 deletions frontend/src/components/pages/login/KakaoCallbackPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { SaveUserContext } from "@contexts/UserProvider";

import { client } from "@apis/client";

import { ROUTE_PATHS } from "@constants/route";
import { API_ENDPOINT_MAP } from "@constants/endpoint";
import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";
import { ROUTE_PATHS_MAP } from "@constants/route";

const KakaoCallbackPage = () => {
const navigate = useNavigate();
Expand All @@ -17,18 +19,18 @@ const KakaoCallbackPage = () => {

if (code) {
client
.post(`${ROUTE_PATHS.loginOauth}?code=${code}`)
.get(API_ENDPOINT_MAP.loginOauth(code))
.then((res) => {
saveUser(res.data);
navigate(ROUTE_PATHS.root);
navigate(ROUTE_PATHS_MAP.root);
})
.catch(() => {
alert("로그인에 실패하였습니다. 다시 시도해주세요!");
navigate(ROUTE_PATHS.login);
alert(ERROR_MESSAGE_MAP.loginFailed);
navigate(ROUTE_PATHS_MAP.login);
});
} else {
alert("로그인에 실패하였습니다. 다시 시도해주세요!");
navigate(ROUTE_PATHS.login);
alert(ERROR_MESSAGE_MAP.loginFailed);
navigate(ROUTE_PATHS_MAP.login);
}
}, [navigate]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { AvatarCircle, FallbackImage } from "@components/common";

import useImageError from "@hooks/useImageError";

import { ROUTE_PATHS_MAP } from "@constants/route";

import { EmptyHeart } from "@assets/svg";

import * as S from "./TravelogueCard.styled";
Expand All @@ -21,7 +23,7 @@ const TravelogueCard = ({
const { imageError, handleImageError } = useImageError({ imageUrl: thumbnail });

const handleCardClick = () => {
navigate(`/travelogue/${id}`);
navigate(ROUTE_PATHS_MAP.travelogue(id));
};

const handleLikeClick = (e: React.MouseEvent) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import DateRangePicker from "@components/common/DateRangePicker/DateRangePicker"
import { useTravelDays } from "@hooks/pages/useTravelDays";
import useUser from "@hooks/useUser";

import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";
import { ROUTE_PATHS_MAP } from "@constants/route";

import * as S from "./TravelPlanRegisterPage.styled";

const MAX_TITLE_LENGTH = 20;
Expand Down Expand Up @@ -74,9 +77,9 @@ const TravelPlanRegisterPage = () => {
handleAddTravelPlan(
{ title, startDate: formattedStartDate, days: travelDays },
{
onSuccess: ({ data }) => {
onSuccess: ({ data: { id } }) => {
handleCloseBottomSheet();
navigate(`/travel-plans/${data.id}`);
navigate(ROUTE_PATHS_MAP.travelPlan(id));
},
},
);
Expand All @@ -89,8 +92,8 @@ const TravelPlanRegisterPage = () => {

useEffect(() => {
if (!user?.accessToken) {
alert("로그인이 필요합니다.");
navigate("/login");
alert(ERROR_MESSAGE_MAP.api.login);
navigate(ROUTE_PATHS_MAP.login);
}
}, [user?.accessToken, navigate]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import TravelogueMultiImageUpload from "@components/pages/travelogueRegister/Tra
import { useTravelDays } from "@hooks/pages/useTravelDays";
import useUser from "@hooks/useUser";

import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";
import { ROUTE_PATHS_MAP } from "@constants/route";

import * as S from "./TravelogueRegisterPage.styled";

const MAX_TITLE_LENGTH = 20;
Expand Down Expand Up @@ -77,9 +80,9 @@ const TravelogueRegisterPage = () => {
handleRegisterTravelogue(
{ title, thumbnail, days: travelDays },
{
onSuccess: ({ data }) => {
onSuccess: ({ data: { id } }) => {
handleCloseBottomSheet();
navigate(`/travelogue/${data.id}`);
navigate(ROUTE_PATHS_MAP.travelogue(id));
},
},
);
Expand All @@ -91,8 +94,8 @@ const TravelogueRegisterPage = () => {

useEffect(() => {
if (!user?.accessToken) {
alert("로그인이 필요합니다.");
navigate("/login");
alert(ERROR_MESSAGE_MAP.api.login);
navigate(ROUTE_PATHS_MAP.login);
}
}, [user?.accessToken, navigate]);

Expand Down
8 changes: 8 additions & 0 deletions frontend/src/constants/endpoint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const API_ENDPOINT_MAP = {
loginOauth: (code: string) => `/login/oauth/kakao?code=${code}`,
travelogueDetail: (id: number) => `/travelogues/${id}`,
travelPlanDetail: (id: number) => `travel-plans/${id}`,
travelogues: "/travelogues",
travelPlans: "/travel-plans",
image: "/image",
} as const;
7 changes: 7 additions & 0 deletions frontend/src/constants/errorMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const ERROR_MESSAGE_MAP = {
api: {
login: "로그인을 해주세요.",
},
loginFailed: "로그인에 실패하였습니다. 다시 시도해주세요!",
provider: "provider 바깥에 존재합니다!",
} as const;
7 changes: 7 additions & 0 deletions frontend/src/constants/httpStatusCode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const HTTP_STATUS_CODE_MAP = {
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
INTERNAL_SERVER_ERROR: 500,
} as const;
10 changes: 10 additions & 0 deletions frontend/src/constants/queryKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const QUERY_KEYS_MAP = {
travelogue: {
all: ["travelogues"],
detail: (id: string) => [...QUERY_KEYS_MAP.travelogue.all, id],
},
travelPlan: {
all: ["travel-plans"],
detail: (id: string) => [...QUERY_KEYS_MAP.travelPlan.all, id],
},
};
9 changes: 5 additions & 4 deletions frontend/src/constants/route.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
export const ROUTE_PATHS = {
export const ROUTE_PATHS_MAP = {
back: -1,
root: "/",
travelogue: "/travelogue/:id",
travelogue: (id?: number) => (id ? `/travelogue/${id}` : "/travelogue/:id"),
travelPlan: (id?: number) => (id ? `/travel-plan/${id}` : "/travel-plan/:id"),
travelogueRegister: "/travelogue/register",
travelPlans: "/travel-plans/:id",
travelPlansRegister: "/travel-plans/register",
travelPlanRegister: "/travel-plan/register",
login: "/login",
loginCallback: "/oauth",
loginOauth: "/login/oauth/kakao",
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/constants/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const STORAGE_KEYS_MAP = {
user: "tourootUser",
} as const;
7 changes: 5 additions & 2 deletions frontend/src/contexts/TravelTransformDetailProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import type { TravelTransformDetail } from "@type/domain/travelTransform";

import useUser from "@hooks/useUser";

import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";
import { ROUTE_PATHS_MAP } from "@constants/route";

const TravelogueContext = createContext<TravelTransformDetail | null>(null);
const SaveTravelogueContext = createContext<(travelogue: TravelTransformDetail) => void>(() => {});

Expand Down Expand Up @@ -40,8 +43,8 @@ export const useTravelTransformDetailContext = () => {
travelTransformDetail?: TravelTransformDetail,
) => {
if (isEmptyObject(user ?? {})) {
alert("로그인 후 이용이 가능합니다.");
navigate("/login");
alert(ERROR_MESSAGE_MAP.api.login);
navigate(ROUTE_PATHS_MAP.login);
} else if (travelTransformDetail) {
saveTransformDetail(travelTransformDetail);
navigate(redirectUrl);
Expand Down
Loading

0 comments on commit e3c65c7

Please sign in to comment.