Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/admin/AdminRoute.tsx
Original file line number Diff line number Diff line change
@@ -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 <Navigate to='/login' replace />;
} else if (!allowedRoles.includes(userInfo.role)) {
}

// 역할이 허용되지 않은 경우
if (!allowedRoles.includes(userInfo.role)) {
return <Navigate to='/' replace />;
}
Comment on lines +14 to +22
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위의 else if는 실수겠죠? 😄

404페이지가 있다면 거기로 넘겨버려도 괜찮을지도 모르겠네요.

덤으로 파일 이름도 AdminRoute가 아닌 ProtectedRoute로 바꾸면 조금 더 혼란이 적어질 것 같아요~


return <>{children}</>; // 자식 요소 렌더링
};

export default ProtectedRoute;
30 changes: 22 additions & 8 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -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 = () => (
<HeaderContainer>
<HeaderWrapper>
<img src={logo} alt='Logo' />
</HeaderWrapper>
<MenuButton />
</HeaderContainer>
);
const Header = () => {
const navigate = useNavigate();

const handleLogoClick = () => {
navigate('/'); // 메인 페이지로 이동
};

return (
<HeaderContainer>
<HeaderWrapper>
<Logo src={logo} alt='Logo' onClick={handleLogoClick} />
<MenuButton />
</HeaderWrapper>
</HeaderContainer>
);
};

export default Header;

Expand All @@ -28,3 +37,8 @@ const HeaderWrapper = styled.div`
align-items: center;
justify-content: space-between;
`;

// 클릭 가능한 스타일을 추가한 로고
const Logo = styled.img`
cursor: pointer; // 커서를 클릭 가능한 손가락 모양으로 변경
`;
40 changes: 30 additions & 10 deletions src/components/MenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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('/');
};

Expand All @@ -56,7 +61,18 @@ const MenuButton = () => {
{isOpen && (
<DropdownMenu>
<ul>
<li onClick={isLoggedIn ? () => {} : handleLogin}>
<li
onClick={() => {
setIsOpen(false); // 드롭다운 먼저 닫기
if (isLoggedIn) {
role === 'admin'
? navigate('/adminpage')
: navigate('/mypage');
} else {
handleLogin();
}
}}
>
{/* 아바타 표시 */}
<AvatarContainer>
<Avatar
Expand All @@ -74,7 +90,11 @@ const MenuButton = () => {
</li>
{isLoggedIn ? (
<>
<li onClick={handleMyPage}>마이페이지</li>
{role === 'admin' ? (
<li onClick={handleAdminPage}>관리자페이지</li>
) : (
<li onClick={handleMyPage}>마이페이지</li>
)}
<li>문의하기</li>
<li>서비스 소개</li>
<li onClick={handleLogout}>로그아웃</li>
Expand Down
10 changes: 10 additions & 0 deletions src/pages/AdminPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const AdminPage = () => {
return (
<div className='p-8'>
<h1 className='text-2xl font-bold'>어드민 페이지</h1>
<p>이 페이지는 관리자만 접근할 수 있습니다.</p>
</div>
);
};

export default AdminPage;
10 changes: 10 additions & 0 deletions src/routes/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
{
Expand Down Expand Up @@ -34,6 +36,14 @@ const router = [
},
],
},
{
path: '/adminpage',
element: (
<ProtectedRoute allowedRoles={['admin']}>
<AdminPage />
</ProtectedRoute>
),
},
],
},
{
Expand Down