From c9100566b9df78865274d5f30db4419c4e5f933a Mon Sep 17 00:00:00 2001
From: YouD0313 <102004480+YouD0313@users.noreply.github.com>
Date: Thu, 29 May 2025 00:05:17 +0900
Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?=
=?UTF-8?q?=EA=B6=8C=ED=95=9C=20=ED=8C=90=EB=B3=84=20=EB=9D=BC=EC=9A=B0?=
=?UTF-8?q?=ED=84=B0,=20=EC=82=AC=EC=9D=B4=EB=93=9C=EB=B0=94=20=EB=A0=88?=
=?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/App.tsx | 4 +-
.../admin/sidebar/AdminSidebar.styled.ts | 20 +++++++
.../common/admin/sidebar/AdminSidebar.tsx | 21 +++++++
.../sidebarList/AdminSidebarList.styled.ts | 35 +++++++++++
.../sidebar/sidebarList/AdminSidebarList.tsx | 58 +++++++++++++++++++
src/components/common/header/Header.tsx | 8 ++-
src/constants/admin/sidebar.ts | 55 ++++++++++++++++++
src/constants/user/routes.ts | 12 ++++
src/hooks/useAuth.ts | 4 +-
src/routes/AdminRoutes.tsx | 30 ++++++++++
src/routes/AppRoutes.tsx | 26 ++++-----
src/routes/MergeRoutes.tsx | 33 +++++++++++
src/routes/ProtectAdminRoute.tsx | 58 +++++++++++++++++++
src/store/authStore.ts | 17 +++++-
14 files changed, 361 insertions(+), 20 deletions(-)
create mode 100644 src/components/common/admin/sidebar/AdminSidebar.styled.ts
create mode 100644 src/components/common/admin/sidebar/AdminSidebar.tsx
create mode 100644 src/components/common/admin/sidebar/sidebarList/AdminSidebarList.styled.ts
create mode 100644 src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx
create mode 100644 src/constants/admin/sidebar.ts
create mode 100644 src/routes/AdminRoutes.tsx
create mode 100644 src/routes/MergeRoutes.tsx
create mode 100644 src/routes/ProtectAdminRoute.tsx
diff --git a/src/App.tsx b/src/App.tsx
index f450a916..0251c267 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,10 +1,10 @@
-import AppRoutes from './routes/AppRoutes';
import { ThemeProvider } from 'styled-components';
import { GlobalStyle } from './style/global';
import { defaultTheme } from './style/theme';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { SearchFilteringProvider } from './context/SearchFilteringContext';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
+import MergeRoutes from './routes/MergeRoutes';
const queryClient = new QueryClient({
defaultOptions: {
@@ -22,7 +22,7 @@ function App() {
-
+
diff --git a/src/components/common/admin/sidebar/AdminSidebar.styled.ts b/src/components/common/admin/sidebar/AdminSidebar.styled.ts
new file mode 100644
index 00000000..4553f307
--- /dev/null
+++ b/src/components/common/admin/sidebar/AdminSidebar.styled.ts
@@ -0,0 +1,20 @@
+import styled from 'styled-components';
+
+export const SidebarContainer = styled.section`
+ padding: 1rem;
+ width: 15rem;
+`;
+
+export const SidebarLogoWrapper = styled.div`
+ margin-bottom: 1.5rem;
+`;
+
+export const SidebarLogoImg = styled.img`
+ width: 5rem;
+`;
+
+export const MovedListContainerAll = styled.nav`
+ margin-top: 1.5rem;
+ display: grid;
+ gap: 1.5rem;
+`;
diff --git a/src/components/common/admin/sidebar/AdminSidebar.tsx b/src/components/common/admin/sidebar/AdminSidebar.tsx
new file mode 100644
index 00000000..b84bfc1c
--- /dev/null
+++ b/src/components/common/admin/sidebar/AdminSidebar.tsx
@@ -0,0 +1,21 @@
+import { SIDEBAR_LIST } from '../../../../constants/admin/sidebar';
+import * as S from './AdminSidebar.styled';
+import logo from '../../../../assets/mainlogo.svg';
+import AdminSidebarList from './sidebarList/AdminSidebarList';
+import ContentBorder from '../../contentBorder/ContentBorder';
+
+export default function AdminSidebar() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.styled.ts b/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.styled.ts
new file mode 100644
index 00000000..de625e0a
--- /dev/null
+++ b/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.styled.ts
@@ -0,0 +1,35 @@
+import { Link } from 'react-router-dom';
+import styled from 'styled-components';
+
+export const MovedListContainer = styled.nav``;
+
+export const MovedListLink = styled(Link)`
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 0.8rem;
+
+ &:hover {
+ color: ${({ theme }) => theme.color.deepGrey};
+ }
+`;
+
+export const MovedListIcon = styled.div`
+ display: flex;
+ align-items: center;
+
+ svg {
+ width: 1.5rem;
+ }
+`;
+
+export const MovedList = styled.div`
+ font-size: 1.2rem;
+`;
+
+export const MovedListTitleWrapper = styled.div``;
+
+export const MovedListTitle = styled.h3`
+ padding: 0.5rem;
+ color: ${({ theme }) => theme.color.deepGrey};
+`;
diff --git a/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx b/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx
new file mode 100644
index 00000000..7ac8d0b2
--- /dev/null
+++ b/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx
@@ -0,0 +1,58 @@
+import { literal } from 'zod';
+import { SIDEBAR_LIST } from '../../../../../constants/admin/sidebar';
+import * as S from './AdminSidebarList.styled';
+import {
+ ArrowRightStartOnRectangleIcon,
+ ChatBubbleBottomCenterTextIcon,
+ EnvelopeIcon,
+ ExclamationCircleIcon,
+ ExclamationTriangleIcon,
+ HomeIcon,
+ MegaphoneIcon,
+ NewspaperIcon,
+ PhotoIcon,
+ TagIcon,
+ UserGroupIcon,
+} from '@heroicons/react/24/outline';
+
+const iconMap = {
+ mainPage: ,
+ movedSite: ,
+ notice: ,
+ banner: ,
+ tags: ,
+ allUser: ,
+ reports: ,
+ inquiries: ,
+ manage: ,
+};
+
+type IconKey = keyof typeof iconMap;
+
+interface AdminSidebarListProps {
+ title: string;
+ list: readonly { name: IconKey; title: string; router: string }[];
+}
+
+export default function AdminSidebarList({
+ title,
+ list,
+}: AdminSidebarListProps) {
+ return (
+
+
+ {title && {title}}
+
+ {list.map((list) => (
+
+ {iconMap[list.name]}
+ {list.title}
+
+ ))}
+
+ );
+}
diff --git a/src/components/common/header/Header.tsx b/src/components/common/header/Header.tsx
index a8c6c482..34881562 100644
--- a/src/components/common/header/Header.tsx
+++ b/src/components/common/header/Header.tsx
@@ -26,6 +26,12 @@ function Header() {
const isLoggedIn = useAuthStore((state) => state.isLoggedIn);
const { myData, isLoading } = useMyProfileInfo();
+ const handleClickLogout = () => {
+ userLogout();
+ useAuthStore.persist.clearStorage();
+ localStorage.clear();
+ };
+
// const { signalData, setSignalData } = useNotification();
// useEffect(() => {
@@ -100,7 +106,7 @@ function Header() {
e.preventDefault()}>
로그아웃
diff --git a/src/constants/admin/sidebar.ts b/src/constants/admin/sidebar.ts
new file mode 100644
index 00000000..d3e2c777
--- /dev/null
+++ b/src/constants/admin/sidebar.ts
@@ -0,0 +1,55 @@
+import { ADMIN_ROUTE } from '../user/routes';
+
+export const SIDEBAR_LIST = {
+ main: [
+ {
+ name: 'mainPage',
+ title: '메인페이지',
+ router: ADMIN_ROUTE.admin,
+ },
+ {
+ name: 'movedSite',
+ title: '사이트 이동',
+ router: ADMIN_ROUTE.devPals,
+ },
+ ],
+ service: [
+ {
+ name: 'notice',
+ title: '공지사항',
+ router: ADMIN_ROUTE.notice,
+ },
+ {
+ name: 'banner',
+ title: '배너관리',
+ router: ADMIN_ROUTE.banner,
+ },
+ {
+ name: 'tags',
+ title: '태그관리',
+ router: ADMIN_ROUTE.tags,
+ },
+ ],
+ user: [
+ {
+ name: 'allUser',
+ title: '전체 회원 조회',
+ router: ADMIN_ROUTE.main,
+ },
+ {
+ name: 'reports',
+ title: '신고검토',
+ router: ADMIN_ROUTE.reports,
+ },
+ {
+ name: 'inquiries',
+ title: '문의확인',
+ router: ADMIN_ROUTE.inquiries,
+ },
+ {
+ name: 'manage',
+ title: '공고/댓글 관리',
+ router: ADMIN_ROUTE.manage,
+ },
+ ],
+} as const;
diff --git a/src/constants/user/routes.ts b/src/constants/user/routes.ts
index 020f9f6e..bb969fac 100644
--- a/src/constants/user/routes.ts
+++ b/src/constants/user/routes.ts
@@ -30,3 +30,15 @@ export const ROUTES = {
evaluation: '/evaluation',
loginSuccess: '/oauth-redirect',
} as const;
+
+export const ADMIN_ROUTE = {
+ admin: '/admin',
+ devPals: '/main',
+ notice: '/notice',
+ banner: '/banner',
+ tags: '/tags',
+ allUser: '/all-user',
+ reports: '/reports',
+ inquiries: '/inquires',
+ manage: '/manage',
+};
diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts
index 259e4883..a0f69e42 100644
--- a/src/hooks/useAuth.ts
+++ b/src/hooks/useAuth.ts
@@ -95,10 +95,10 @@ export const useAuth = (handleModalOpen: (message: string) => void) => {
};
const userLogout = () => {
- logout();
queryClient.removeQueries({ queryKey: myInfoKey.myProfile });
- useAuthStore.persist.clearStorage();
+ // useAuthStore.persist.clearStorage();
handleModalOpen(MODAL_MESSAGE.logout);
+ logout();
setTimeout(() => {
navigate(ROUTES.main);
}, 1000);
diff --git a/src/routes/AdminRoutes.tsx b/src/routes/AdminRoutes.tsx
new file mode 100644
index 00000000..59ae35bc
--- /dev/null
+++ b/src/routes/AdminRoutes.tsx
@@ -0,0 +1,30 @@
+import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom';
+import NotFoundPage from '../pages/notFoundPage/NotFoundPage';
+import { lazy } from 'react';
+import { ADMIN_ROUTE } from '../constants/user/routes';
+import ProtectAdminRoute from './ProtectAdminRoute';
+
+const Sidebar = lazy(
+ () => import('../components/common/admin/sidebar/AdminSidebar')
+);
+
+export const AdminRoutes = () => {
+ const routeList = [
+ {
+ path: ADMIN_ROUTE.admin,
+ element: (
+
+
+
+ ),
+ },
+ ];
+
+ const newAdminRoutes = routeList.map((items) => {
+ return { ...items, errorElement: };
+ });
+
+ return newAdminRoutes;
+};
+
+export default AdminRoutes;
diff --git a/src/routes/AppRoutes.tsx b/src/routes/AppRoutes.tsx
index 12365b63..ef4aa7d4 100644
--- a/src/routes/AppRoutes.tsx
+++ b/src/routes/AppRoutes.tsx
@@ -11,8 +11,8 @@ import useAuthStore from '../store/authStore';
import ProtectRoute from '../components/common/ProtectRoute';
import NotFoundPage from '../pages/notFoundPage/NotFoundPage';
import QueryErrorBoundary from '../components/common/error/QueryErrorBoundary';
-import { ToastProvider } from '../components/common/Toast/ToastProvider';
import { ROUTES } from '../constants/user/routes';
+
const Login = lazy(() => import('../pages/login/Login'));
const LoginSuccess = lazy(() => import('../pages/login/LoginSuccess'));
const LoginApi = lazy(() => import('../pages/login/LoginApi'));
@@ -101,7 +101,7 @@ const ModifyProject = lazy(
);
const Evaluation = lazy(() => import('../pages/user/evaluation/Evaluation'));
-const AppRoutes = () => {
+export const AppRoutes = () => {
const isLoggedIn = useAuthStore((state) => state.isLoggedIn);
const routeList = [
@@ -383,19 +383,19 @@ const AppRoutes = () => {
};
});
- const router = createBrowserRouter([
- {
- element: (
-
-
-
- ),
+ // const router = createBrowserRouter([
+ // {
+ // element: (
+ //
+ //
+ //
+ // ),
- children: [...newRouteList, { path: '*', element: }],
- },
- ]);
+ // children: [...newRouteList, { path: '*', element: }],
+ // },
+ // ]);
- return ;
+ return newRouteList;
};
export default AppRoutes;
diff --git a/src/routes/MergeRoutes.tsx b/src/routes/MergeRoutes.tsx
new file mode 100644
index 00000000..a4df1eac
--- /dev/null
+++ b/src/routes/MergeRoutes.tsx
@@ -0,0 +1,33 @@
+import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom';
+import AdminRoutes from './AdminRoutes';
+import AppRoutes from './AppRoutes';
+import NotFoundPage from '../pages/notFoundPage/NotFoundPage';
+import { ToastProvider } from '../components/common/Toast/ToastProvider';
+import ProtectAdminRoute from './ProtectAdminRoute';
+import useAuthStore from '../store/authStore';
+
+export default function MergeRoutes() {
+ const isAdmin = useAuthStore((state) => state.userData?.admin) || false;
+
+ const user = (
+
+
+
+ );
+
+ const router = createBrowserRouter([
+ {
+ element: (
+ {isAdmin ? : user}
+ ),
+
+ children: [
+ ...AdminRoutes(),
+ ...AppRoutes(),
+ { path: '*', element: },
+ ],
+ },
+ ]);
+
+ return ;
+}
diff --git a/src/routes/ProtectAdminRoute.tsx b/src/routes/ProtectAdminRoute.tsx
new file mode 100644
index 00000000..44642e31
--- /dev/null
+++ b/src/routes/ProtectAdminRoute.tsx
@@ -0,0 +1,58 @@
+import { useNavigate } from 'react-router-dom';
+import useAuthStore from '../store/authStore';
+import { ADMIN_ROUTE, ROUTES } from '../constants/user/routes';
+import { ReactNode, useEffect } from 'react';
+import { useModal } from '../hooks/useModal';
+import Modal from '../components/common/modal/Modal';
+import { MODAL_MESSAGE } from '../constants/user/modalMessage';
+
+interface ProtectAdminRouteProps {
+ children: ReactNode;
+}
+
+export default function ProtectAdminRoute({
+ children,
+}: ProtectAdminRouteProps) {
+ const isLoggedIn = useAuthStore((state) => state.isLoggedIn) ?? false;
+ const isAdmin = useAuthStore((state) => state.userData?.admin) ?? false;
+ const logout = useAuthStore((state) => state.logout);
+ const replace = useAuthStore((state) => state.replace);
+ const redirectAdminBool =
+ useAuthStore((state) => state.redirectAdmin) || false;
+ const navigate = useNavigate();
+ const { isOpen, message, handleModalOpen, handleModalClose } = useModal();
+
+ useEffect(() => {
+ (async () => {
+ if (isLoggedIn && isAdmin && !redirectAdminBool) {
+ navigate(ADMIN_ROUTE.admin);
+ replace();
+ return;
+ } else if (!isLoggedIn || (!isLoggedIn && !isAdmin)) {
+ logout();
+ handleModalOpen(MODAL_MESSAGE.isNotLoggedIn);
+ setTimeout(() => {
+ navigate(ROUTES.main);
+ }, 1000);
+ return (
+
+ {message}
+
+ );
+ }
+ })();
+ }, [
+ redirectAdminBool,
+ isLoggedIn,
+ isAdmin,
+ replace,
+ navigate,
+ logout,
+ isOpen,
+ message,
+ handleModalOpen,
+ handleModalClose,
+ ]);
+
+ return children;
+}
diff --git a/src/store/authStore.ts b/src/store/authStore.ts
index 25416c9a..2bf281ae 100644
--- a/src/store/authStore.ts
+++ b/src/store/authStore.ts
@@ -4,11 +4,13 @@ import { decryptData, encryptData } from '../util/cryptoUtils';
import type { UserData } from '../models/auth';
interface AuthState {
+ redirectAdmin: boolean;
isLoggedIn: boolean;
userData: UserData | null;
accessToken: string | null;
login: (accessToken: string, userData: UserData | null) => void;
logout: () => void;
+ replace: () => void;
}
export const getStoredUserData = () => {
@@ -26,10 +28,16 @@ export const getTokens = () => {
const useAuthStore = create(
persist(
(set) => ({
+ redirectAdmin: false,
isLoggedIn: false,
accessToken: null,
userData: null,
+ replace: () => {
+ set({
+ redirectAdmin: true,
+ });
+ },
login: (accessToken: string, userData: UserData | null) => {
set({
isLoggedIn: true,
@@ -38,12 +46,17 @@ const useAuthStore = create(
});
},
logout: () => {
- set({ isLoggedIn: false, accessToken: null, userData: null });
+ // set({
+ // redirectAdmin: false,
+ // isLoggedIn: false,
+ // accessToken: null,
+ // userData: null,
+ // });
+ useAuthStore.persist.clearStorage();
},
}),
{
name: 'auth-storage', // 로컬스토리지에 저장될 이름
- storage: createJSONStorage(() => localStorage),
}
)
);
From 482d1ec1a6ee69a055c6e1e79d310068589cbba7 Mon Sep 17 00:00:00 2001
From: YouD0313 <102004480+YouD0313@users.noreply.github.com>
Date: Thu, 29 May 2025 00:08:20 +0900
Subject: [PATCH 2/5] =?UTF-8?q?fix:=20routes.ts=20=ED=8C=8C=EC=9D=BC=20?=
=?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EC=9D=B4=EB=8F=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/common/header/Header.tsx | 2 +-
src/components/common/header/Notification/Notification.tsx | 2 +-
.../commentComponent/commentComponent/CommentComponent.tsx | 2 +-
src/components/user/comment/replyComponent/ReplyComponent.tsx | 2 +-
src/components/user/customerService/MoveInquiredLink.tsx | 2 +-
.../customerService/noticeDetail/bottom/button/ListButton.tsx | 2 +-
.../noticeDetail/bottom/button/OtherNoticeButton.tsx | 2 +-
src/components/user/home/projectCardLists/ProjectCardLists.tsx | 2 +-
src/components/user/manageProjects/Card.tsx | 2 +-
src/components/user/manageProjects/CardList.tsx | 2 +-
src/components/user/mypage/ContentTab.tsx | 2 +-
src/components/user/mypage/joinedProject/MyJoinProjects.tsx | 2 +-
src/components/user/mypage/joinedProject/Project.tsx | 2 +-
src/components/user/mypage/myProfile/MyProfile.tsx | 2 +-
.../user/mypage/myProfile/editProfile/EditProfile.tsx | 2 +-
src/components/user/mypage/myProfile/profile/Profile.tsx | 2 +-
.../mypage/notifications/appliedProjects/AppliedProjects.tsx | 2 +-
.../user/userPage/userProjectList/UserProjectList.tsx | 2 +-
src/constants/admin/sidebar.ts | 2 +-
src/constants/{user => }/routes.ts | 0
src/constants/sidebarItems.tsx | 2 +-
src/constants/user/myPageFilter.ts | 2 +-
src/hooks/useAuth.ts | 2 +-
src/hooks/user/ProjectHooks/useApplyProject.ts | 2 +-
src/hooks/user/ProjectHooks/useCreateProject.ts | 2 +-
src/hooks/user/ProjectHooks/useUpdateProject.ts | 2 +-
src/hooks/user/useMyInfo.ts | 2 +-
src/pages/login/Login.tsx | 2 +-
src/pages/login/LoginApi.tsx | 2 +-
src/pages/login/LoginSuccess.tsx | 2 +-
src/pages/user/changePassword/ChangePassword.tsx | 2 +-
src/pages/user/customerService/notice/Notice.tsx | 2 +-
src/pages/user/main/HeroSection.tsx | 2 +-
src/pages/user/mypage/MyPage.tsx | 2 +-
src/pages/user/projectDetail/ProjectDetail.tsx | 2 +-
src/pages/user/register/Register.tsx | 2 +-
src/pages/user/userpage/UserPage.tsx | 2 +-
src/routes/AdminRoutes.tsx | 2 +-
src/routes/AppRoutes.tsx | 2 +-
src/routes/ProtectAdminRoute.tsx | 2 +-
40 files changed, 39 insertions(+), 39 deletions(-)
rename src/constants/{user => }/routes.ts (100%)
diff --git a/src/components/common/header/Header.tsx b/src/components/common/header/Header.tsx
index 34881562..3bd8513a 100644
--- a/src/components/common/header/Header.tsx
+++ b/src/components/common/header/Header.tsx
@@ -17,7 +17,7 @@ import { formatImgPath } from '../../../util/formatImgPath';
// import { useEffect } from 'react';
// import { testLiveAlarm } from '../../../api/alarm.api';
import { useMyProfileInfo } from '../../../hooks/user/useMyInfo';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
function Header() {
const location = useLocation();
diff --git a/src/components/common/header/Notification/Notification.tsx b/src/components/common/header/Notification/Notification.tsx
index cf8daa84..8265e347 100644
--- a/src/components/common/header/Notification/Notification.tsx
+++ b/src/components/common/header/Notification/Notification.tsx
@@ -5,7 +5,7 @@ import LoadingSpinner from '../../loadingSpinner/LoadingSpinner';
import useAlarmList from '../../../../hooks/user/useAlarmList';
import arrow_right from '../../../../assets/ArrowRight.svg';
import { useNavigate } from 'react-router-dom';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
const Notification = () => {
const navigate = useNavigate();
diff --git a/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx b/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx
index 69cccde1..721403f8 100644
--- a/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx
+++ b/src/components/user/comment/commentComponent/commentComponent/CommentComponent.tsx
@@ -4,7 +4,7 @@ import chat from '../../../../../assets/chat.svg';
import { Link } from 'react-router-dom';
import CommentInput from '../../commentInput/CommentInput';
import type { CommentType } from '../../../../../models/comment';
-import { ROUTES } from '../../../../../constants/user/routes';
+import { ROUTES } from '../../../../../constants/routes';
import Avatar from '../../../../common/avatar/Avatar';
interface CommentComponentProps {
diff --git a/src/components/user/comment/replyComponent/ReplyComponent.tsx b/src/components/user/comment/replyComponent/ReplyComponent.tsx
index 5cd9b6ae..fe2af8b7 100644
--- a/src/components/user/comment/replyComponent/ReplyComponent.tsx
+++ b/src/components/user/comment/replyComponent/ReplyComponent.tsx
@@ -8,7 +8,7 @@ import CommentInput from '../commentInput/CommentInput';
import useGetReply from '../../../../hooks/user/CommentHooks/useGetReply';
import LoadingSpinner from '../../../common/loadingSpinner/LoadingSpinner';
import { Link } from 'react-router-dom';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
import dropdownButton from '../../../../assets/dropdownButton.svg';
interface ReplyComponentProps {
diff --git a/src/components/user/customerService/MoveInquiredLink.tsx b/src/components/user/customerService/MoveInquiredLink.tsx
index a3ada3b7..e0a06092 100644
--- a/src/components/user/customerService/MoveInquiredLink.tsx
+++ b/src/components/user/customerService/MoveInquiredLink.tsx
@@ -1,5 +1,5 @@
import { useLocation } from 'react-router-dom';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import * as S from './MoveInquiredLink.styled';
export default function MovedInquiredLink() {
diff --git a/src/components/user/customerService/noticeDetail/bottom/button/ListButton.tsx b/src/components/user/customerService/noticeDetail/bottom/button/ListButton.tsx
index 1cae25b3..609094f9 100644
--- a/src/components/user/customerService/noticeDetail/bottom/button/ListButton.tsx
+++ b/src/components/user/customerService/noticeDetail/bottom/button/ListButton.tsx
@@ -1,4 +1,4 @@
-import { ROUTES } from '../../../../../../constants/user/routes';
+import { ROUTES } from '../../../../../../constants/routes';
import ContentBorder from '../../../../../common/contentBorder/ContentBorder';
import * as S from './ListButton.styled';
diff --git a/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx b/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx
index 7c98295d..1cd3478d 100644
--- a/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx
+++ b/src/components/user/customerService/noticeDetail/bottom/button/OtherNoticeButton.tsx
@@ -1,4 +1,4 @@
-import { ROUTES } from '../../../../../../constants/user/routes';
+import { ROUTES } from '../../../../../../constants/routes';
import type { OtherNotice } from '../../../../../../models/customerService';
import { formatDate } from '../../../../../../util/format';
import * as S from './OtherNoticeButton.styled';
diff --git a/src/components/user/home/projectCardLists/ProjectCardLists.tsx b/src/components/user/home/projectCardLists/ProjectCardLists.tsx
index 3c62ab01..45783e36 100644
--- a/src/components/user/home/projectCardLists/ProjectCardLists.tsx
+++ b/src/components/user/home/projectCardLists/ProjectCardLists.tsx
@@ -3,7 +3,7 @@ import { useProjectCardListData } from '../../../../hooks/user/useProjectCardLis
import CardList from './cardList/CardList';
import * as S from './ProjectCardLists.styled';
import { Link } from 'react-router-dom';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
import EmptyLoading from '../../../common/emptyLoading/EmptyLoading';
import NoResult from '../../../common/noResult/NoResult';
import { useSaveSearchFiltering } from '../../../../hooks/user/useSaveSearchFiltering';
diff --git a/src/components/user/manageProjects/Card.tsx b/src/components/user/manageProjects/Card.tsx
index ab5cfcab..10da8a64 100644
--- a/src/components/user/manageProjects/Card.tsx
+++ b/src/components/user/manageProjects/Card.tsx
@@ -2,7 +2,7 @@ import * as S from './Card.styled';
import type { ManagedProject } from '../../../models/manageMyProject';
import AvatarList from '../../common/avatar/AvatarList';
import { formatDate } from '../../../util/formatDate';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
interface CardProps {
project: ManagedProject;
}
diff --git a/src/components/user/manageProjects/CardList.tsx b/src/components/user/manageProjects/CardList.tsx
index 544775b4..ca0c3b58 100644
--- a/src/components/user/manageProjects/CardList.tsx
+++ b/src/components/user/manageProjects/CardList.tsx
@@ -2,7 +2,7 @@ import * as S from './CardList.styled';
import type { ManagedProject } from '../../../models/manageMyProject';
import Card from './Card';
import CreateButton from '../../../assets/createProjectButton.svg';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
interface CardListProps {
projects: ManagedProject[];
diff --git a/src/components/user/mypage/ContentTab.tsx b/src/components/user/mypage/ContentTab.tsx
index 35b32858..51d99bf3 100644
--- a/src/components/user/mypage/ContentTab.tsx
+++ b/src/components/user/mypage/ContentTab.tsx
@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import * as S from './ContentTab.styled';
import { Link, Outlet, useLocation } from 'react-router-dom';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import ScrollWrapper from './ScrollWrapper';
import MovedInquiredLink from '../customerService/MoveInquiredLink';
diff --git a/src/components/user/mypage/joinedProject/MyJoinProjects.tsx b/src/components/user/mypage/joinedProject/MyJoinProjects.tsx
index 4774c168..0dc4fc7b 100644
--- a/src/components/user/mypage/joinedProject/MyJoinProjects.tsx
+++ b/src/components/user/mypage/joinedProject/MyJoinProjects.tsx
@@ -4,7 +4,7 @@ import Project from './Project';
import Spinner from '../Spinner';
import ScrollWrapper from '../ScrollWrapper';
import { useMyJoinedProjectList } from '../../../../hooks/user/useMyInfo';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
import NoContent from '../../../common/noContent/NoContent';
const MyJoinProjects = () => {
diff --git a/src/components/user/mypage/joinedProject/Project.tsx b/src/components/user/mypage/joinedProject/Project.tsx
index 42d2f66d..5dac04cc 100644
--- a/src/components/user/mypage/joinedProject/Project.tsx
+++ b/src/components/user/mypage/joinedProject/Project.tsx
@@ -2,7 +2,7 @@ import * as S from './Project.styled';
import { EllipsisHorizontalIcon } from '@heroicons/react/24/outline';
import type { JoinedProject } from '../../../../models/userProject';
import beginner from '../../../../assets/beginner.svg';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
interface ProjectProps {
project: JoinedProject;
diff --git a/src/components/user/mypage/myProfile/MyProfile.tsx b/src/components/user/mypage/myProfile/MyProfile.tsx
index 39a98518..ab665932 100644
--- a/src/components/user/mypage/myProfile/MyProfile.tsx
+++ b/src/components/user/mypage/myProfile/MyProfile.tsx
@@ -7,7 +7,7 @@ import { useRef } from 'react';
import ScrollWrapper from '../ScrollWrapper';
import { useModal } from '../../../../hooks/useModal';
import { useMyProfileInfo } from '../../../../hooks/user/useMyInfo';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
import Modal from '../../../common/modal/Modal';
const MyProfile = () => {
diff --git a/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx b/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx
index 6ebceb14..d89ead01 100644
--- a/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx
+++ b/src/components/user/mypage/myProfile/editProfile/EditProfile.tsx
@@ -13,7 +13,7 @@ import type { UserInfo } from '../../../../../models/userInfo';
import { useSearchFilteringSkillTag } from '../../../../../hooks/user/useSearchFilteringSkillTag';
import { useEditMyProfileInfo } from '../../../../../hooks/user/useMyInfo';
import useNickNameVerification from '../../../../../hooks/user/useNicknameVerification';
-import { ROUTES } from '../../../../../constants/user/routes';
+import { ROUTES } from '../../../../../constants/routes';
import Button from '../../../../common/Button/Button';
import {
ERROR_MESSAGES,
diff --git a/src/components/user/mypage/myProfile/profile/Profile.tsx b/src/components/user/mypage/myProfile/profile/Profile.tsx
index 5e73c62e..dbe1c1f2 100644
--- a/src/components/user/mypage/myProfile/profile/Profile.tsx
+++ b/src/components/user/mypage/myProfile/profile/Profile.tsx
@@ -6,7 +6,7 @@ import { useEffect } from 'react';
import MyProfileWrapper from '../MyProfileWrapper';
import type { UserInfo } from '../../../../../models/userInfo';
import { PROFILE_DEFAULT_MESSAGE } from '../../../../../constants/user/myPageProfile';
-import { ROUTES } from '../../../../../constants/user/routes';
+import { ROUTES } from '../../../../../constants/routes';
import 'chart.js/auto';
import { chartOptions } from '../../../../../constants/evaluationChartData';
diff --git a/src/components/user/mypage/notifications/appliedProjects/AppliedProjects.tsx b/src/components/user/mypage/notifications/appliedProjects/AppliedProjects.tsx
index f84c37eb..4454ca87 100644
--- a/src/components/user/mypage/notifications/appliedProjects/AppliedProjects.tsx
+++ b/src/components/user/mypage/notifications/appliedProjects/AppliedProjects.tsx
@@ -4,7 +4,7 @@ import Spinner from '../../Spinner';
import AppliedProjectsStatus from './appliedProjectsStatus/AppliedProjectsStatus';
import NoContent from '../../../../common/noContent/NoContent';
import { useMyAppliedStatusList } from '../../../../../hooks/user/useMyInfo';
-import { ROUTES } from '../../../../../constants/user/routes';
+import { ROUTES } from '../../../../../constants/routes';
export default function AppliedProjects() {
const { myAppliedStatusListData, isLoading } = useMyAppliedStatusList();
diff --git a/src/components/user/userPage/userProjectList/UserProjectList.tsx b/src/components/user/userPage/userProjectList/UserProjectList.tsx
index 9742d612..829b60b6 100644
--- a/src/components/user/userPage/userProjectList/UserProjectList.tsx
+++ b/src/components/user/userPage/userProjectList/UserProjectList.tsx
@@ -1,6 +1,6 @@
import { Link } from 'react-router-dom';
import * as S from '../../mypage/joinedProject/MyJoinProjects.styled';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
import NoContent from '../../../common/noContent/NoContent';
import ScrollWrapper from '../../mypage/ScrollWrapper';
import Spinner from '../../mypage/Spinner';
diff --git a/src/constants/admin/sidebar.ts b/src/constants/admin/sidebar.ts
index d3e2c777..b179e173 100644
--- a/src/constants/admin/sidebar.ts
+++ b/src/constants/admin/sidebar.ts
@@ -1,4 +1,4 @@
-import { ADMIN_ROUTE } from '../user/routes';
+import { ADMIN_ROUTE } from '../routes';
export const SIDEBAR_LIST = {
main: [
diff --git a/src/constants/user/routes.ts b/src/constants/routes.ts
similarity index 100%
rename from src/constants/user/routes.ts
rename to src/constants/routes.ts
diff --git a/src/constants/sidebarItems.tsx b/src/constants/sidebarItems.tsx
index ee3a9571..dd76a964 100644
--- a/src/constants/sidebarItems.tsx
+++ b/src/constants/sidebarItems.tsx
@@ -1,4 +1,4 @@
-import { ROUTES } from './user/routes';
+import { ROUTES } from './routes';
import {
UserGroupIcon,
PencilSquareIcon,
diff --git a/src/constants/user/myPageFilter.ts b/src/constants/user/myPageFilter.ts
index 67c6edbe..eeab4fb6 100644
--- a/src/constants/user/myPageFilter.ts
+++ b/src/constants/user/myPageFilter.ts
@@ -1,4 +1,4 @@
-import { ROUTES } from './routes';
+import { ROUTES } from '../routes';
export const NOTIFICATION_FILTER = [
{ title: '전체', url: ``, id: 0 },
diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts
index a0f69e42..387bda3d 100644
--- a/src/hooks/useAuth.ts
+++ b/src/hooks/useAuth.ts
@@ -7,7 +7,7 @@ import type { LoginResponse } from '../models/auth';
import { AxiosError } from 'axios';
import { myInfoKey } from './queries/user/keys';
import { MODAL_MESSAGE } from '../constants/user/modalMessage';
-import { ROUTES } from '../constants/user/routes';
+import { ROUTES } from '../constants/routes';
import { registerFormValues } from '../pages/user/register/Register';
import { changePasswordFormValues } from '../pages/user/changePassword/ChangePassword';
diff --git a/src/hooks/user/ProjectHooks/useApplyProject.ts b/src/hooks/user/ProjectHooks/useApplyProject.ts
index 7b7daf9c..c925ac94 100644
--- a/src/hooks/user/ProjectHooks/useApplyProject.ts
+++ b/src/hooks/user/ProjectHooks/useApplyProject.ts
@@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
import { postApplicantProject } from '../../../api/joinProject.api';
import { joinProject } from '../../../models/joinProject';
import { MODAL_MESSAGE } from '../../../constants/user/modalMessage';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
interface UseApplyProjectProps {
id: number;
diff --git a/src/hooks/user/ProjectHooks/useCreateProject.ts b/src/hooks/user/ProjectHooks/useCreateProject.ts
index b90a4829..403f6a7a 100644
--- a/src/hooks/user/ProjectHooks/useCreateProject.ts
+++ b/src/hooks/user/ProjectHooks/useCreateProject.ts
@@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom';
import { postProject } from '../../../api/joinProject.api';
import { MODAL_MESSAGE } from '../../../constants/user/modalMessage';
import { managedProjectKey } from '../../queries/user/keys';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import type { FormData } from '../../../models/createProject';
interface UseCreateProjectProps {
diff --git a/src/hooks/user/ProjectHooks/useUpdateProject.ts b/src/hooks/user/ProjectHooks/useUpdateProject.ts
index 60dc103b..a1ea85a6 100644
--- a/src/hooks/user/ProjectHooks/useUpdateProject.ts
+++ b/src/hooks/user/ProjectHooks/useUpdateProject.ts
@@ -4,7 +4,7 @@ import { putProject } from '../../../api/joinProject.api';
import { managedProjectKey } from '../../queries/user/keys';
import type { FormData } from '../../../models/createProject';
import { MODAL_MESSAGE } from '../../../constants/user/modalMessage';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
interface UseUpdateProjectProps {
id: number;
diff --git a/src/hooks/user/useMyInfo.ts b/src/hooks/user/useMyInfo.ts
index 08ce923f..c0ebecbc 100644
--- a/src/hooks/user/useMyInfo.ts
+++ b/src/hooks/user/useMyInfo.ts
@@ -12,7 +12,7 @@ import {
putMyInfo,
} from '../../api/mypage.api';
import { MODAL_MESSAGE } from '../../constants/user/modalMessage';
-import { ROUTES } from '../../constants/user/routes';
+import { ROUTES } from '../../constants/routes';
import type {
ApiAppliedProject,
ApiJoinedProject,
diff --git a/src/pages/login/Login.tsx b/src/pages/login/Login.tsx
index 632497bb..d9d960ed 100644
--- a/src/pages/login/Login.tsx
+++ b/src/pages/login/Login.tsx
@@ -12,7 +12,7 @@ import {
OAUTH_PROVIDERS,
} from '../../constants/user/authConstants';
import { useAuth } from '../../hooks/useAuth';
-import { ROUTES } from '../../constants/user/routes';
+import { ROUTES } from '../../constants/routes';
import { useModal } from '../../hooks/useModal';
import Modal from '../../components/common/modal/Modal';
import InputText from '../../components/user/auth/InputText';
diff --git a/src/pages/login/LoginApi.tsx b/src/pages/login/LoginApi.tsx
index 502dd79a..29562201 100644
--- a/src/pages/login/LoginApi.tsx
+++ b/src/pages/login/LoginApi.tsx
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import useAuthStore from '../../store/authStore';
-import { ROUTES } from '../../constants/user/routes';
+import { ROUTES } from '../../constants/routes';
import * as S from './Login.styled';
import { Spinner } from '../../components/common/loadingSpinner/LoadingSpinner.styled';
import Modal from '../../components/common/modal/Modal';
diff --git a/src/pages/login/LoginSuccess.tsx b/src/pages/login/LoginSuccess.tsx
index 9bc05d1d..1a26f4c0 100644
--- a/src/pages/login/LoginSuccess.tsx
+++ b/src/pages/login/LoginSuccess.tsx
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import useAuthStore from '../../store/authStore';
-import { ROUTES } from '../../constants/user/routes';
+import { ROUTES } from '../../constants/routes';
import * as S from './Login.styled';
import { Spinner } from '../../components/common/loadingSpinner/LoadingSpinner.styled';
import Modal from '../../components/common/modal/Modal';
diff --git a/src/pages/user/changePassword/ChangePassword.tsx b/src/pages/user/changePassword/ChangePassword.tsx
index 2f58dc4f..5d7d8903 100644
--- a/src/pages/user/changePassword/ChangePassword.tsx
+++ b/src/pages/user/changePassword/ChangePassword.tsx
@@ -9,7 +9,7 @@ import { ERROR_MESSAGES } from '../../../constants/user/authConstants';
import { useAuth } from '../../../hooks/useAuth';
import { useModal } from '../../../hooks/useModal';
import useEmailVerification from '../../../hooks/user/useEmailVerification';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import InputText from '../../../components/user/auth/InputText';
import Button from '../../../components/common/Button/Button';
import Modal from '../../../components/common/modal/Modal';
diff --git a/src/pages/user/customerService/notice/Notice.tsx b/src/pages/user/customerService/notice/Notice.tsx
index c46ffcba..d52184aa 100644
--- a/src/pages/user/customerService/notice/Notice.tsx
+++ b/src/pages/user/customerService/notice/Notice.tsx
@@ -5,7 +5,7 @@ import { useGetNotice } from '../../../../hooks/user/useGetNotice';
import { Spinner } from '../../../../components/common/loadingSpinner/LoadingSpinner.styled';
import CustomerServiceHeader from '../../../../components/user/customerService/CustomerServiceHeader';
import ContentBorder from '../../../../components/common/contentBorder/ContentBorder';
-import { ROUTES } from '../../../../constants/user/routes';
+import { ROUTES } from '../../../../constants/routes';
import NoticeList from '../../../../components/user/customerService/notice/NoticeList';
import NoResult from '../../../../components/common/noResult/NoResult';
import Pagination from '../../../../components/common/pagination/Pagination';
diff --git a/src/pages/user/main/HeroSection.tsx b/src/pages/user/main/HeroSection.tsx
index a0a5e5c0..34836a97 100644
--- a/src/pages/user/main/HeroSection.tsx
+++ b/src/pages/user/main/HeroSection.tsx
@@ -2,7 +2,7 @@ import * as S from './HeroSection.styled';
import landimg from '../../../assets/landing.svg';
import DownArrow from '../../../assets/arrow.svg';
import { Link } from 'react-router-dom';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import Button from '../../../components/common/Button/Button';
interface HeroSectionProps {
handleScrollToSection: (sectionId: number) => void;
diff --git a/src/pages/user/mypage/MyPage.tsx b/src/pages/user/mypage/MyPage.tsx
index 8b5f107a..59705db3 100644
--- a/src/pages/user/mypage/MyPage.tsx
+++ b/src/pages/user/mypage/MyPage.tsx
@@ -7,7 +7,7 @@ import {
BellIcon,
} from '@heroicons/react/24/outline';
import loadingImg from '../../../assets/loadingImg.svg';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import { useMyProfileInfo } from '../../../hooks/user/useMyInfo';
import Sidebar from '../../../components/common/sidebar/Sidebar';
diff --git a/src/pages/user/projectDetail/ProjectDetail.tsx b/src/pages/user/projectDetail/ProjectDetail.tsx
index 95efed20..d395f152 100644
--- a/src/pages/user/projectDetail/ProjectDetail.tsx
+++ b/src/pages/user/projectDetail/ProjectDetail.tsx
@@ -8,7 +8,7 @@ import useAuthStore from '../../../store/authStore';
import { MODAL_MESSAGE } from '../../../constants/user/modalMessage';
import LoadingSpinner from '../../../components/common/loadingSpinner/LoadingSpinner';
import Modal from '../../../components/common/modal/Modal';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import Avatar from '../../../components/common/avatar/Avatar';
import { formatDate } from '../../../util/formatDate';
import ProjectInformation from '../../../components/user/projectFormComponents/projectInformationText/ProjectInformation';
diff --git a/src/pages/user/register/Register.tsx b/src/pages/user/register/Register.tsx
index 912db98a..d3f77148 100644
--- a/src/pages/user/register/Register.tsx
+++ b/src/pages/user/register/Register.tsx
@@ -15,7 +15,7 @@ import { useAuth } from '../../../hooks/useAuth';
import { useModal } from '../../../hooks/useModal';
import useEmailVerification from '../../../hooks/user/useEmailVerification';
import useNickNameVerification from '../../../hooks/user/useNicknameVerification';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import Title from '../../../components/common/title/Title';
import InputText from '../../../components/user/auth/InputText';
import Button from '../../../components/common/Button/Button';
diff --git a/src/pages/user/userpage/UserPage.tsx b/src/pages/user/userpage/UserPage.tsx
index d070afe9..d28ba3aa 100644
--- a/src/pages/user/userpage/UserPage.tsx
+++ b/src/pages/user/userpage/UserPage.tsx
@@ -2,7 +2,7 @@ import { Outlet, useParams } from 'react-router-dom';
import * as S from '../mypage/MyPage.styled';
import { DocumentTextIcon, UserIcon } from '@heroicons/react/24/outline';
import loadingImg from '../../../assets/loadingImg.svg';
-import { ROUTES } from '../../../constants/user/routes';
+import { ROUTES } from '../../../constants/routes';
import { useUserProfileInfo } from '../../../hooks/user/useUserInfo';
import Sidebar from '../../../components/common/sidebar/Sidebar';
diff --git a/src/routes/AdminRoutes.tsx b/src/routes/AdminRoutes.tsx
index 59ae35bc..9f06f4fe 100644
--- a/src/routes/AdminRoutes.tsx
+++ b/src/routes/AdminRoutes.tsx
@@ -1,7 +1,7 @@
import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom';
import NotFoundPage from '../pages/notFoundPage/NotFoundPage';
import { lazy } from 'react';
-import { ADMIN_ROUTE } from '../constants/user/routes';
+import { ADMIN_ROUTE } from '../constants/routes';
import ProtectAdminRoute from './ProtectAdminRoute';
const Sidebar = lazy(
diff --git a/src/routes/AppRoutes.tsx b/src/routes/AppRoutes.tsx
index ef4aa7d4..1c309e4d 100644
--- a/src/routes/AppRoutes.tsx
+++ b/src/routes/AppRoutes.tsx
@@ -11,7 +11,7 @@ import useAuthStore from '../store/authStore';
import ProtectRoute from '../components/common/ProtectRoute';
import NotFoundPage from '../pages/notFoundPage/NotFoundPage';
import QueryErrorBoundary from '../components/common/error/QueryErrorBoundary';
-import { ROUTES } from '../constants/user/routes';
+import { ROUTES } from '../constants/routes';
const Login = lazy(() => import('../pages/login/Login'));
const LoginSuccess = lazy(() => import('../pages/login/LoginSuccess'));
diff --git a/src/routes/ProtectAdminRoute.tsx b/src/routes/ProtectAdminRoute.tsx
index 44642e31..0b0f7190 100644
--- a/src/routes/ProtectAdminRoute.tsx
+++ b/src/routes/ProtectAdminRoute.tsx
@@ -1,6 +1,6 @@
import { useNavigate } from 'react-router-dom';
import useAuthStore from '../store/authStore';
-import { ADMIN_ROUTE, ROUTES } from '../constants/user/routes';
+import { ADMIN_ROUTE, ROUTES } from '../constants/routes';
import { ReactNode, useEffect } from 'react';
import { useModal } from '../hooks/useModal';
import Modal from '../components/common/modal/Modal';
From 2323cad39dbed8e5cb57660dd5cf07c7b0bd0a47 Mon Sep 17 00:00:00 2001
From: YouD0313 <102004480+YouD0313@users.noreply.github.com>
Date: Thu, 29 May 2025 14:33:37 +0900
Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=EB=B0=98?=
=?UTF-8?q?=EC=98=81,=20=EA=B4=80=EB=A6=AC=EC=9E=90=ED=8E=98=EC=9D=B4?=
=?UTF-8?q?=EC=A7=80=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=EB=B2=84?=
=?UTF-8?q?=ED=8A=BC=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/http.api.ts | 1 -
src/assets/logout.svg | 22 +++++++++++
.../admin/sidebar/AdminSidebar.styled.ts | 22 ++++++++++-
.../common/admin/sidebar/AdminSidebar.tsx | 8 ++++
.../sidebar/sidebarList/AdminSidebarList.tsx | 18 ++++-----
src/constants/admin/sidebar.ts | 2 +-
src/constants/routes.ts | 14 +++----
src/routes/AdminRoutes.tsx | 1 -
src/routes/MergeRoutes.tsx | 34 +++++++++--------
src/routes/ProtectAdminRoute.tsx | 38 +++++++------------
src/store/authStore.ts | 12 +++---
11 files changed, 104 insertions(+), 68 deletions(-)
create mode 100644 src/assets/logout.svg
diff --git a/src/api/http.api.ts b/src/api/http.api.ts
index 7df96e74..18e9ef22 100644
--- a/src/api/http.api.ts
+++ b/src/api/http.api.ts
@@ -67,7 +67,6 @@ export const createClient = (config?: AxiosRequestConfig) => {
// }
logout();
- useAuthStore.persist.clearStorage();
window.location.href = '/login';
return Promise.reject(error);
}
diff --git a/src/assets/logout.svg b/src/assets/logout.svg
new file mode 100644
index 00000000..299f084a
--- /dev/null
+++ b/src/assets/logout.svg
@@ -0,0 +1,22 @@
+
+
+
diff --git a/src/components/common/admin/sidebar/AdminSidebar.styled.ts b/src/components/common/admin/sidebar/AdminSidebar.styled.ts
index 4553f307..afe20ecf 100644
--- a/src/components/common/admin/sidebar/AdminSidebar.styled.ts
+++ b/src/components/common/admin/sidebar/AdminSidebar.styled.ts
@@ -6,13 +6,33 @@ export const SidebarContainer = styled.section`
`;
export const SidebarLogoWrapper = styled.div`
- margin-bottom: 1.5rem;
+ display: flex;
+ justify-content: space-around;
+ align-items: flex-end;
+ margin: 0 1.5rem 1.5rem 0;
`;
export const SidebarLogoImg = styled.img`
width: 5rem;
`;
+export const LogoutButton = styled.button`
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 0.3rem;
+`;
+
+export const LogoutImg = styled.img`
+ width: 2rem;
+ filter: invert(70%);
+`;
+
+export const LogoutSpan = styled.span`
+ font-size: 0.5rem;
+ color: ${({ theme }) => theme.color.deepGrey};
+ margin-left: -7px;
+`;
+
export const MovedListContainerAll = styled.nav`
margin-top: 1.5rem;
display: grid;
diff --git a/src/components/common/admin/sidebar/AdminSidebar.tsx b/src/components/common/admin/sidebar/AdminSidebar.tsx
index b84bfc1c..a0c67d20 100644
--- a/src/components/common/admin/sidebar/AdminSidebar.tsx
+++ b/src/components/common/admin/sidebar/AdminSidebar.tsx
@@ -1,14 +1,22 @@
import { SIDEBAR_LIST } from '../../../../constants/admin/sidebar';
import * as S from './AdminSidebar.styled';
import logo from '../../../../assets/mainlogo.svg';
+import logoutIcon from '../../../../assets/logout.svg';
import AdminSidebarList from './sidebarList/AdminSidebarList';
import ContentBorder from '../../contentBorder/ContentBorder';
+import useAuthStore from '../../../../store/authStore';
export default function AdminSidebar() {
+ const logout = useAuthStore((state) => state.logout);
+
return (
+
+
+ Logout
+
diff --git a/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx b/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx
index 7ac8d0b2..2544768d 100644
--- a/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx
+++ b/src/components/common/admin/sidebar/sidebarList/AdminSidebarList.tsx
@@ -1,15 +1,11 @@
-import { literal } from 'zod';
-import { SIDEBAR_LIST } from '../../../../../constants/admin/sidebar';
import * as S from './AdminSidebarList.styled';
import {
ArrowRightStartOnRectangleIcon,
ChatBubbleBottomCenterTextIcon,
EnvelopeIcon,
- ExclamationCircleIcon,
ExclamationTriangleIcon,
HomeIcon,
MegaphoneIcon,
- NewspaperIcon,
PhotoIcon,
TagIcon,
UserGroupIcon,
@@ -22,7 +18,7 @@ const iconMap = {
banner: ,
tags: ,
allUser: ,
- reports: ,
+ reports: ,
inquiries: ,
manage: ,
};
@@ -43,14 +39,14 @@ export default function AdminSidebarList({
{title && {title}}
- {list.map((list) => (
+ {list.map((item) => (
- {iconMap[list.name]}
- {list.title}
+ {iconMap[item.name]}
+ {item.title}
))}
diff --git a/src/constants/admin/sidebar.ts b/src/constants/admin/sidebar.ts
index b179e173..55535b2a 100644
--- a/src/constants/admin/sidebar.ts
+++ b/src/constants/admin/sidebar.ts
@@ -34,7 +34,7 @@ export const SIDEBAR_LIST = {
{
name: 'allUser',
title: '전체 회원 조회',
- router: ADMIN_ROUTE.main,
+ router: ADMIN_ROUTE.allUser,
},
{
name: 'reports',
diff --git a/src/constants/routes.ts b/src/constants/routes.ts
index bb969fac..fe64fdfd 100644
--- a/src/constants/routes.ts
+++ b/src/constants/routes.ts
@@ -34,11 +34,11 @@ export const ROUTES = {
export const ADMIN_ROUTE = {
admin: '/admin',
devPals: '/main',
- notice: '/notice',
- banner: '/banner',
- tags: '/tags',
- allUser: '/all-user',
- reports: '/reports',
- inquiries: '/inquires',
- manage: '/manage',
+ notice: 'notice',
+ banner: 'banner',
+ tags: 'tags',
+ allUser: 'all-user',
+ reports: 'reports',
+ inquiries: 'inquiries',
+ manage: 'manage',
};
diff --git a/src/routes/AdminRoutes.tsx b/src/routes/AdminRoutes.tsx
index 9f06f4fe..00efc712 100644
--- a/src/routes/AdminRoutes.tsx
+++ b/src/routes/AdminRoutes.tsx
@@ -1,4 +1,3 @@
-import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom';
import NotFoundPage from '../pages/notFoundPage/NotFoundPage';
import { lazy } from 'react';
import { ADMIN_ROUTE } from '../constants/routes';
diff --git a/src/routes/MergeRoutes.tsx b/src/routes/MergeRoutes.tsx
index a4df1eac..7fb6d4d6 100644
--- a/src/routes/MergeRoutes.tsx
+++ b/src/routes/MergeRoutes.tsx
@@ -4,28 +4,30 @@ import AppRoutes from './AppRoutes';
import NotFoundPage from '../pages/notFoundPage/NotFoundPage';
import { ToastProvider } from '../components/common/Toast/ToastProvider';
import ProtectAdminRoute from './ProtectAdminRoute';
-import useAuthStore from '../store/authStore';
+import ProtectRoute from '../components/common/ProtectRoute';
+import { ROUTES } from '../constants/routes';
export default function MergeRoutes() {
- const isAdmin = useAuthStore((state) => state.userData?.admin) || false;
-
- const user = (
-
-
-
- );
-
const router = createBrowserRouter([
{
element: (
- {isAdmin ? : user}
+
+
+
+
+
),
-
- children: [
- ...AdminRoutes(),
- ...AppRoutes(),
- { path: '*', element: },
- ],
+ children: [...AppRoutes(), { path: '*', element: }],
+ },
+ {
+ element: (
+
+
+
+
+
+ ),
+ children: [...AdminRoutes(), { path: '*', element: }],
},
]);
diff --git a/src/routes/ProtectAdminRoute.tsx b/src/routes/ProtectAdminRoute.tsx
index 0b0f7190..2a918fc4 100644
--- a/src/routes/ProtectAdminRoute.tsx
+++ b/src/routes/ProtectAdminRoute.tsx
@@ -1,10 +1,9 @@
import { useNavigate } from 'react-router-dom';
import useAuthStore from '../store/authStore';
-import { ADMIN_ROUTE, ROUTES } from '../constants/routes';
+import { ADMIN_ROUTE } from '../constants/routes';
import { ReactNode, useEffect } from 'react';
import { useModal } from '../hooks/useModal';
import Modal from '../components/common/modal/Modal';
-import { MODAL_MESSAGE } from '../constants/user/modalMessage';
interface ProtectAdminRouteProps {
children: ReactNode;
@@ -23,24 +22,11 @@ export default function ProtectAdminRoute({
const { isOpen, message, handleModalOpen, handleModalClose } = useModal();
useEffect(() => {
- (async () => {
- if (isLoggedIn && isAdmin && !redirectAdminBool) {
- navigate(ADMIN_ROUTE.admin);
- replace();
- return;
- } else if (!isLoggedIn || (!isLoggedIn && !isAdmin)) {
- logout();
- handleModalOpen(MODAL_MESSAGE.isNotLoggedIn);
- setTimeout(() => {
- navigate(ROUTES.main);
- }, 1000);
- return (
-
- {message}
-
- );
- }
- })();
+ if (isLoggedIn && isAdmin && !redirectAdminBool) {
+ navigate(ADMIN_ROUTE.admin);
+ replace();
+ return;
+ }
}, [
redirectAdminBool,
isLoggedIn,
@@ -48,11 +34,15 @@ export default function ProtectAdminRoute({
replace,
navigate,
logout,
- isOpen,
- message,
handleModalOpen,
- handleModalClose,
]);
- return children;
+ return (
+ <>
+ {children}
+
+ {message}
+
+ >
+ );
}
diff --git a/src/store/authStore.ts b/src/store/authStore.ts
index 2bf281ae..a0d8981d 100644
--- a/src/store/authStore.ts
+++ b/src/store/authStore.ts
@@ -46,12 +46,12 @@ const useAuthStore = create(
});
},
logout: () => {
- // set({
- // redirectAdmin: false,
- // isLoggedIn: false,
- // accessToken: null,
- // userData: null,
- // });
+ set({
+ redirectAdmin: false,
+ isLoggedIn: false,
+ accessToken: null,
+ userData: null,
+ });
useAuthStore.persist.clearStorage();
},
}),
From 47fe26c2de4d6f6620483f7f9b906cbd0732fb43 Mon Sep 17 00:00:00 2001
From: YouD0313 <102004480+YouD0313@users.noreply.github.com>
Date: Thu, 29 May 2025 19:05:34 +0900
Subject: [PATCH 4/5] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=EB=B0=98?=
=?UTF-8?q?=EC=98=81=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../admin/sidebar/AdminSidebar.styled.ts | 2 ++
.../common/admin/sidebar/AdminSidebar.tsx | 12 +++++++++++-
src/hooks/useAuth.ts | 10 ++++++++--
src/pages/login/Login.tsx | 4 ++--
src/routes/AppRoutes.tsx | 14 +-------------
src/routes/MergeRoutes.tsx | 19 +++++++------------
src/routes/ProtectAdminRoute.tsx | 10 +++++++++-
src/store/authStore.ts | 7 +------
8 files changed, 41 insertions(+), 37 deletions(-)
diff --git a/src/components/common/admin/sidebar/AdminSidebar.styled.ts b/src/components/common/admin/sidebar/AdminSidebar.styled.ts
index afe20ecf..f6de17c5 100644
--- a/src/components/common/admin/sidebar/AdminSidebar.styled.ts
+++ b/src/components/common/admin/sidebar/AdminSidebar.styled.ts
@@ -1,8 +1,10 @@
import styled from 'styled-components';
export const SidebarContainer = styled.section`
+ height: 100vh;
padding: 1rem;
width: 15rem;
+ border-right: 1px solid ${({ theme }) => theme.color.grey};
`;
export const SidebarLogoWrapper = styled.div`
diff --git a/src/components/common/admin/sidebar/AdminSidebar.tsx b/src/components/common/admin/sidebar/AdminSidebar.tsx
index a0c67d20..fdb73dd0 100644
--- a/src/components/common/admin/sidebar/AdminSidebar.tsx
+++ b/src/components/common/admin/sidebar/AdminSidebar.tsx
@@ -5,15 +5,25 @@ import logoutIcon from '../../../../assets/logout.svg';
import AdminSidebarList from './sidebarList/AdminSidebarList';
import ContentBorder from '../../contentBorder/ContentBorder';
import useAuthStore from '../../../../store/authStore';
+import { useNavigate } from 'react-router-dom';
+import { ROUTES } from '../../../../constants/routes';
export default function AdminSidebar() {
+ const navigate = useNavigate();
const logout = useAuthStore((state) => state.logout);
+ const handleClickLogout = () => {
+ logout();
+ setTimeout(() => {
+ navigate(ROUTES.main);
+ }, 1000);
+ };
+
return (
-
+
Logout
diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts
index 387bda3d..b8741ce0 100644
--- a/src/hooks/useAuth.ts
+++ b/src/hooks/useAuth.ts
@@ -1,3 +1,4 @@
+import { ADMIN_ROUTE } from './../constants/routes';
import { useNavigate } from 'react-router-dom';
import { postLogin, postResetPassword, postSignUp } from '../api/auth.api';
import { loginFormValues } from '../pages/login/Login';
@@ -67,10 +68,16 @@ export const useAuth = (handleModalOpen: (message: string) => void) => {
},
onSuccess: async (data) => {
const { accessToken, userData } = data;
+ const isAdmin = userData.admin;
+
handleModalOpen(MODAL_MESSAGE.loginSuccess);
setTimeout(() => {
login(accessToken, userData);
- navigate(ROUTES.main);
+ if (isAdmin) {
+ return navigate(ADMIN_ROUTE.admin);
+ } else {
+ return navigate(ROUTES.main);
+ }
}, 1000);
},
onError: () => {
@@ -96,7 +103,6 @@ export const useAuth = (handleModalOpen: (message: string) => void) => {
const userLogout = () => {
queryClient.removeQueries({ queryKey: myInfoKey.myProfile });
- // useAuthStore.persist.clearStorage();
handleModalOpen(MODAL_MESSAGE.logout);
logout();
setTimeout(() => {
diff --git a/src/pages/login/Login.tsx b/src/pages/login/Login.tsx
index d9d960ed..328dc22d 100644
--- a/src/pages/login/Login.tsx
+++ b/src/pages/login/Login.tsx
@@ -1,6 +1,6 @@
import { Link } from 'react-router-dom';
import * as S from './Login.styled';
-import Mainlogo from '../../assets/mainlogo.svg';
+import MainLogo from '../../assets/mainlogo.svg';
import { EnvelopeIcon, KeyIcon } from '@heroicons/react/24/outline';
import Title from '../../components/common/title/Title';
import { z } from 'zod';
@@ -53,7 +53,7 @@ const Login = () => {
return (
-
+
로그인