diff --git a/src/admin/AdminRoute.tsx b/src/admin/AdminRoute.tsx new file mode 100644 index 0000000..47118d5 --- /dev/null +++ b/src/admin/AdminRoute.tsx @@ -0,0 +1,27 @@ +import { Navigate } from 'react-router'; +import { useSelector } from 'react-redux'; +import { RootState } from '@/store/rootReducer'; + +interface ProtectedRouteProps { + allowedRoles: string[]; + children: React.ReactNode; +} + +const ProtectedRoute = ({ allowedRoles, children }: ProtectedRouteProps) => { + const { userInfo } = useSelector((state: RootState) => state.user); + + // 로그인하지 않은 경우 + if (!userInfo) { + return ; + } else if (!allowedRoles.includes(userInfo.role)) { + } + + // 역할이 허용되지 않은 경우 + if (!allowedRoles.includes(userInfo.role)) { + return ; + } + + return <>{children}; // 자식 요소 렌더링 +}; + +export default ProtectedRoute; diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 690cda9..b31e1f2 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,15 +1,24 @@ import styled from 'styled-components'; import logo from '@/assets/logo.svg'; import MenuButton from './MenuButton'; +import { useNavigate } from 'react-router'; -const Header = () => ( - - - Logo - - - -); +const Header = () => { + const navigate = useNavigate(); + + const handleLogoClick = () => { + navigate('/'); // 메인 페이지로 이동 + }; + + return ( + + + + + + + ); +}; export default Header; @@ -28,3 +37,8 @@ const HeaderWrapper = styled.div` align-items: center; justify-content: space-between; `; + +// 클릭 가능한 스타일을 추가한 로고 +const Logo = styled.img` + cursor: pointer; // 커서를 클릭 가능한 손가락 모양으로 변경 +`; diff --git a/src/components/MenuButton.tsx b/src/components/MenuButton.tsx index e78fe03..02705db 100644 --- a/src/components/MenuButton.tsx +++ b/src/components/MenuButton.tsx @@ -14,22 +14,27 @@ const MenuButton = () => { const navigate = useNavigate(); const dispatch = useDispatch(); const isLoggedIn = useSelector((state: RootState) => state.user.isLoggedIn); - - const handleLogin = () => { - // 로그인 페이지로 이동 - navigate('/login'); - }; + const role = useSelector((state: RootState) => state.user.userInfo?.role); const handleMyPage = () => { + setIsOpen(false); // 드롭다운 먼저 닫기 navigate('/mypage'); }; + const handleAdminPage = () => { + setIsOpen(false); // 드롭다운 먼저 닫기 + navigate('/adminpage'); + }; + + const handleLogin = () => { + setIsOpen(false); // 드롭다운 먼저 닫기 + navigate('/login'); + }; + const handleLogout = () => { - // Redux 상태 초기화 dispatch(logout()); - // 토큰 제거 removeToken(); - // 로그아웃 후 메인 페이지 이동(필요하다면) + setIsOpen(false); navigate('/'); }; @@ -56,7 +61,18 @@ const MenuButton = () => { {isOpen && (
    -
  • {} : handleLogin}> +
  • { + setIsOpen(false); // 드롭다운 먼저 닫기 + if (isLoggedIn) { + role === 'admin' + ? navigate('/adminpage') + : navigate('/mypage'); + } else { + handleLogin(); + } + }} + > {/* 아바타 표시 */} {
  • {isLoggedIn ? ( <> -
  • 마이페이지
  • + {role === 'admin' ? ( +
  • 관리자페이지
  • + ) : ( +
  • 마이페이지
  • + )}
  • 문의하기
  • 서비스 소개
  • 로그아웃
  • diff --git a/src/pages/AdminPage.tsx b/src/pages/AdminPage.tsx new file mode 100644 index 0000000..b1c6f4d --- /dev/null +++ b/src/pages/AdminPage.tsx @@ -0,0 +1,10 @@ +const AdminPage = () => { + return ( +
    +

    어드민 페이지

    +

    이 페이지는 관리자만 접근할 수 있습니다.

    +
    + ); +}; + +export default AdminPage; diff --git a/src/routes/router.tsx b/src/routes/router.tsx index 49bab7a..3718e99 100644 --- a/src/routes/router.tsx +++ b/src/routes/router.tsx @@ -2,10 +2,12 @@ import Layout from '@/components/layout/Layout'; import Scraps from '@/components/my-page/Scraps'; import UserContents from '@/components/my-page/UserContents'; import UserPosts from '@/components/my-page/UserPosts'; +import AdminPage from '@/pages/AdminPage'; import HomePage from '@/pages/HomePage'; import JoinPage from '@/pages/JoinPage'; import LoginPage from '@/pages/LoginPage'; import MyPage from '@/pages/MyPage'; +import ProtectedRoute from '@/admin/AdminRoute'; const router = [ { @@ -34,6 +36,14 @@ const router = [ }, ], }, + { + path: '/adminpage', + element: ( + + + + ), + }, ], }, {