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 ( - logo + logo 로그인
diff --git a/src/routes/AppRoutes.tsx b/src/routes/AppRoutes.tsx index 1c309e4d..0a26c8d3 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/routes'; +import { ADMIN_ROUTE, ROUTES } from '../constants/routes'; const Login = lazy(() => import('../pages/login/Login')); const LoginSuccess = lazy(() => import('../pages/login/LoginSuccess')); @@ -383,18 +383,6 @@ export const AppRoutes = () => { }; }); - // const router = createBrowserRouter([ - // { - // element: ( - // - // - // - // ), - - // children: [...newRouteList, { path: '*', element: }], - // }, - // ]); - return newRouteList; }; diff --git a/src/routes/MergeRoutes.tsx b/src/routes/MergeRoutes.tsx index 7fb6d4d6..dd084465 100644 --- a/src/routes/MergeRoutes.tsx +++ b/src/routes/MergeRoutes.tsx @@ -4,31 +4,26 @@ import AppRoutes from './AppRoutes'; import NotFoundPage from '../pages/notFoundPage/NotFoundPage'; import { ToastProvider } from '../components/common/Toast/ToastProvider'; import ProtectAdminRoute from './ProtectAdminRoute'; -import ProtectRoute from '../components/common/ProtectRoute'; -import { ROUTES } from '../constants/routes'; export default function MergeRoutes() { const router = createBrowserRouter([ { element: ( - - - - - + + + ), - children: [...AppRoutes(), { path: '*', element: }], + children: [...AppRoutes()], }, { element: ( - - - + ), - children: [...AdminRoutes(), { path: '*', element: }], + children: [...AdminRoutes()], }, + { path: '*', element: }, ]); return ; diff --git a/src/routes/ProtectAdminRoute.tsx b/src/routes/ProtectAdminRoute.tsx index 2a918fc4..cfe01688 100644 --- a/src/routes/ProtectAdminRoute.tsx +++ b/src/routes/ProtectAdminRoute.tsx @@ -1,9 +1,10 @@ import { useNavigate } from 'react-router-dom'; import useAuthStore from '../store/authStore'; -import { ADMIN_ROUTE } from '../constants/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'; +import { MODAL_MESSAGE } from '../constants/user/modalMessage'; interface ProtectAdminRouteProps { children: ReactNode; @@ -22,6 +23,13 @@ export default function ProtectAdminRoute({ const { isOpen, message, handleModalOpen, handleModalClose } = useModal(); useEffect(() => { + if (isLoggedIn && !isAdmin) { + handleModalOpen(MODAL_MESSAGE.needAuth); + setTimeout(() => { + navigate(ROUTES.main); + }, 200); + return; + } if (isLoggedIn && isAdmin && !redirectAdminBool) { navigate(ADMIN_ROUTE.admin); replace(); diff --git a/src/store/authStore.ts b/src/store/authStore.ts index a0d8981d..3511827d 100644 --- a/src/store/authStore.ts +++ b/src/store/authStore.ts @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import { createJSONStorage, persist } from 'zustand/middleware'; +import { persist } from 'zustand/middleware'; import { decryptData, encryptData } from '../util/cryptoUtils'; import type { UserData } from '../models/auth'; @@ -13,11 +13,6 @@ interface AuthState { replace: () => void; } -export const getStoredUserData = () => { - const encryptedData = localStorage.getItem('userData'); - return encryptedData ? decryptData(encryptedData) : null; -}; - export const getTokens = () => { const accessToken = localStorage.getItem('accessToken'); const refreshToken = localStorage.getItem('refreshToken'); From 1a0039a680d70ae39d99f0569f382587bb742b10 Mon Sep 17 00:00:00 2001 From: YouD0313 <102004480+YouD0313@users.noreply.github.com> Date: Thu, 29 May 2025 19:11:27 +0900 Subject: [PATCH 5/5] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=EC=84=B1?= =?UTF-8?q?=EA=B0=9C=EC=84=B1=20=EB=A6=AC=EB=B7=B0=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/admin/sidebar/AdminSidebar.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/common/admin/sidebar/AdminSidebar.tsx b/src/components/common/admin/sidebar/AdminSidebar.tsx index fdb73dd0..e91064f6 100644 --- a/src/components/common/admin/sidebar/AdminSidebar.tsx +++ b/src/components/common/admin/sidebar/AdminSidebar.tsx @@ -23,7 +23,12 @@ export default function AdminSidebar() { - + Logout