From 9e1d682fc4ca59aff0f63ac12e61f47c285c6242 Mon Sep 17 00:00:00 2001 From: Sangyoon98 Date: Tue, 22 Jul 2025 08:08:37 +0900 Subject: [PATCH] =?UTF-8?q?[FEAT]=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8,=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83,=20=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 99 ++++++++----- src/components/Header.tsx | 1 + src/pages/admin/components/OptionsMenu.tsx | 155 +++++++++++---------- src/pages/user/social/KakaoRedirect.tsx | 1 + 4 files changed, 150 insertions(+), 106 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 76a3bd7..0301b5f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,11 @@ import * as React from "react"; -import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom"; +import { + BrowserRouter, + Routes, + Route, + useLocation, + Navigate, +} from "react-router-dom"; import Login from "./pages/user/social/Login"; import Home from "./pages/user/Home"; import Signup from "./pages/user/social/Signup"; @@ -30,43 +36,68 @@ const AppContent: React.FC = () => { location.pathname === "/admin/report" || location.pathname === "/admin/member"; + // authority 값 가져오기 + const authority = localStorage.getItem("authority"); + return ( <> {!hideHeader &&
} - {/*User*/} - } /> - } /> - } /> - } /> - } /> - } /> - } - /> - } /> - } /> - } /> - } /> - } /> - } - /> - } - /> - } - /> - - {/*Admin*/} - } /> - } /> - } /> + {/* Redirect Logic */} + {authority === "ROLE_ADMIN" ? ( + <> + } /> + } /> + } /> + {/* Admin이 유저 페이지 접근 시 리디렉션 */} + } + /> + + ) : ( + <> + {/*User or default fallback*/} + } /> + } /> + } /> + } /> + } /> + } + /> + } + /> + } + /> + } /> + } /> + } /> + } /> + } + /> + } + /> + } + /> + {/* User 또는 권한 없는 사용자가 어드민 페이지 접근 시 리디렉션 */} + } + /> + + )} ); diff --git a/src/components/Header.tsx b/src/components/Header.tsx index c12a952..4a50f23 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -208,6 +208,7 @@ const Header: React.FC = () => { await memberApi().logout(); localStorage.removeItem("accessToken"); localStorage.removeItem("refreshToken"); + localStorage.removeItem("authority"); setMenuOpen(false); setLogoutDialogOpen(false); navigate("/", { replace: true }); diff --git a/src/pages/admin/components/OptionsMenu.tsx b/src/pages/admin/components/OptionsMenu.tsx index 0912404..28aba9f 100644 --- a/src/pages/admin/components/OptionsMenu.tsx +++ b/src/pages/admin/components/OptionsMenu.tsx @@ -1,78 +1,89 @@ -import * as React from 'react'; -import { styled } from '@mui/material/styles'; -import Divider, { dividerClasses } from '@mui/material/Divider'; -import Menu from '@mui/material/Menu'; -import MuiMenuItem from '@mui/material/MenuItem'; -import { paperClasses } from '@mui/material/Paper'; -import { listClasses } from '@mui/material/List'; -import ListItemText from '@mui/material/ListItemText'; -import ListItemIcon, { listItemIconClasses } from '@mui/material/ListItemIcon'; -import LogoutRoundedIcon from '@mui/icons-material/LogoutRounded'; -import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded'; -import MenuButton from './MenuButton'; +import * as React from "react"; +import { styled } from "@mui/material/styles"; +import { dividerClasses } from "@mui/material/Divider"; +import Menu from "@mui/material/Menu"; +import MuiMenuItem from "@mui/material/MenuItem"; +import { paperClasses } from "@mui/material/Paper"; +import { listClasses } from "@mui/material/List"; +import ListItemText from "@mui/material/ListItemText"; +import LogoutRoundedIcon from "@mui/icons-material/LogoutRounded"; +import MoreVertRoundedIcon from "@mui/icons-material/MoreVertRounded"; +import MenuButton from "./MenuButton"; +import { memberApi } from "../../../api/memberApi"; const MenuItem = styled(MuiMenuItem)({ - margin: '2px 0', + margin: "2px 0", + minWidth: "200px", + color: "red", +}); + +const ListItemIcon = styled(MuiMenuItem)({ + color: "red", }); export default function OptionsMenu() { - const [anchorEl, setAnchorEl] = React.useState(null); - const open = Boolean(anchorEl); - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - const handleClose = () => { - setAnchorEl(null); - }; - return ( - - - - - - Profile - My account - - Add another account - - - Logout - - - - - - - ); + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const handleLogout = async () => { + try { + await memberApi().logout(); + localStorage.removeItem("accessToken"); + localStorage.removeItem("refreshToken"); + localStorage.removeItem("authority"); + + window.location.replace("/"); + } catch (err) { + console.error("Logout failed", err); + } + }; + return ( + + + + + + {/*Profile + My account + + Add another account + */} + + 로그아웃 + + + + + + + ); } diff --git a/src/pages/user/social/KakaoRedirect.tsx b/src/pages/user/social/KakaoRedirect.tsx index cabf097..032425d 100644 --- a/src/pages/user/social/KakaoRedirect.tsx +++ b/src/pages/user/social/KakaoRedirect.tsx @@ -58,6 +58,7 @@ const KakaoRedirect: React.FC = () => { if (accessToken && refreshToken) { localStorage.setItem("accessToken", accessToken); localStorage.setItem("refreshToken", refreshToken); + localStorage.setItem("authority", "ROLE_USER"); navigate("/", { replace: true }); window.location.replace("/");