From fa50961c62425a6db0686a4e9ef943816918dbda Mon Sep 17 00:00:00 2001 From: seyun31 <2ne1jenna@naver.com> Date: Tue, 9 Sep 2025 21:43:20 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20SideBar=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/auth/logout.ts | 56 ++++++++++++++++++++++++++++++++++++++ src/components/Header.tsx | 26 ++++++++++++++---- src/components/SideBar.tsx | 44 ++++++++++++++++++++++++++++++ src/page/event.tsx | 19 +++++++++---- src/page/home.tsx | 6 ++-- 5 files changed, 139 insertions(+), 12 deletions(-) create mode 100644 src/api/auth/logout.ts diff --git a/src/api/auth/logout.ts b/src/api/auth/logout.ts new file mode 100644 index 0000000..be0e373 --- /dev/null +++ b/src/api/auth/logout.ts @@ -0,0 +1,56 @@ +// 쿠키 삭제 함수 +function deleteCookie(name: string, path: string = '/', domain?: string) { + let cookieString = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path};`; + + if (domain) { + cookieString += ` domain=${domain};`; + } + + document.cookie = cookieString; +} + +// 모든 쿠키 삭제 함수 +function deleteAllCookies() { + const cookies = document.cookie.split(';'); + + cookies.forEach(cookie => { + const eqPos = cookie.indexOf('='); + const name = eqPos > -1 ? cookie.substr(0, eqPos).trim() : cookie.trim(); + + if (name) { + // 다양한 경로와 도메인으로 쿠키 삭제 시도 + deleteCookie(name, '/'); + deleteCookie(name, '/', window.location.hostname); + deleteCookie(name, '/', `.${window.location.hostname}`); + } + }); +} + +export async function logout(): Promise { + try { + // 모든 쿠키 삭제 + deleteAllCookies(); + + // 세션 스토리지와 로컬 스토리지도 정리 + sessionStorage.clear(); + localStorage.removeItem('currentActivityId'); // 기존에 사용된 로컬스토리지 항목만 삭제 + + console.log("로그아웃 완료 - 모든 쿠키와 세션 정보가 삭제되었습니다."); + return true; + } catch (err) { + console.error("로그아웃 처리 실패:", err); + return false; + } +} + +// 특정 쿠키만 삭제하고 싶을 때 사용 +export function logoutWithSpecificCookie(cookieName: string): boolean { + try { + deleteCookie(cookieName); + console.log(`쿠키 '${cookieName}'이(가) 삭제되었습니다.`); + return true; + } catch (err) { + console.error("쿠키 삭제 실패:", err); + return false; + } +} \ No newline at end of file diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 2cbb02b..cd250da 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,6 +1,7 @@ import { IoLogOutOutline } from "react-icons/io5"; import AegisLogo from '../assets/logos/aegis.svg'; import { useNavigate } from "react-router-dom"; +import { logout } from '../api/auth/logout'; const Header: React.FC = () => { const navigate = useNavigate(); @@ -9,19 +10,34 @@ const Header: React.FC = () => { navigate("/"); } + const handleLogout = async () => { + if (confirm('로그아웃 하시겠습니까?')) { + const success = await logout(); + if (success) { + alert('로그아웃 되었습니다.'); + window.location.href = '/login'; + } else { + alert('로그아웃 중 오류가 발생했습니다.'); + } + } + } + return( <> -
-
+
Aegis Logo

Aegis

-
diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index e69de29..e961e95 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -0,0 +1,44 @@ +import { NavLink } from "react-router-dom"; +import { FiHome } from "react-icons/fi"; +import { IoCalendarNumberOutline } from "react-icons/io5"; +import { TbRosetteDiscount } from "react-icons/tb"; +import { LuBadgeDollarSign } from "react-icons/lu"; + +const MENU = [ + { to: "/", label: "홈 화면", icon: }, + { to: "/event", label: "행사", icon: }, + { to: "/coupon", label: "쿠폰", icon: }, + { to: "/point", label: "포인트", icon: }, +]; + +const Sidebar: React.FC = () => { + return ( + + ); +}; + +export default Sidebar; diff --git a/src/page/event.tsx b/src/page/event.tsx index f681b15..fab3da0 100644 --- a/src/page/event.tsx +++ b/src/page/event.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; import EventTable from "../components/EventTable"; import Header from "../components/Header"; +import Sidebar from '../components/SideBar'; import SearchBar from "../components/Search"; import { useAuthGuard } from '../hooks/useAuthGuard'; import { GetActivities, type Activity } from '../api/activity/get-activities'; @@ -56,11 +57,19 @@ const Event: React.FC = () => { }; return( - <>
-
-
- - + <> +
+
+ +
+
+
+ +
+
+ +
+
diff --git a/src/page/home.tsx b/src/page/home.tsx index 4ed81d9..59fa77e 100644 --- a/src/page/home.tsx +++ b/src/page/home.tsx @@ -1,4 +1,5 @@ import Header from "../components/Header"; +import Sidebar from "../components/SideBar"; import { useAuthGuard } from '../hooks/useAuthGuard'; const Home: React.FC = () => { @@ -18,8 +19,9 @@ const Home: React.FC = () => { return( <> -
-
+
+
+
) From de70cec56eb5e763b3fffcbd8d780d790832ede2 Mon Sep 17 00:00:00 2001 From: seyun31 <2ne1jenna@naver.com> Date: Tue, 9 Sep 2025 21:49:46 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EC=97=90=EC=84=9C=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90=20=ED=99=95=EC=9D=B8=20=EC=95=8C=EB=A6=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/auth/logout.ts | 2 +- src/api/auth/members.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/api/auth/logout.ts b/src/api/auth/logout.ts index be0e373..0fdbca6 100644 --- a/src/api/auth/logout.ts +++ b/src/api/auth/logout.ts @@ -32,7 +32,7 @@ export async function logout(): Promise { deleteAllCookies(); // 세션 스토리지와 로컬 스토리지도 정리 - sessionStorage.clear(); + sessionStorage.clear(); // 환영 메시지 플래그도 함께 삭제됨 localStorage.removeItem('currentActivityId'); // 기존에 사용된 로컬스토리지 항목만 삭제 console.log("로그아웃 완료 - 모든 쿠키와 세션 정보가 삭제되었습니다."); diff --git a/src/api/auth/members.ts b/src/api/auth/members.ts index ac40c3d..846c06b 100644 --- a/src/api/auth/members.ts +++ b/src/api/auth/members.ts @@ -18,7 +18,15 @@ export async function Members(): Promise { const data = await res.json(); if (data.role === "ADMIN") { - alert(`안녕하세요 ${data.name} 관리자님!`); + // 세션 스토리지에서 환영 메시지 표시 여부 확인 + const hasShownWelcome = sessionStorage.getItem('hasShownWelcome'); + + if (!hasShownWelcome) { + alert(`안녕하세요 ${data.name} 관리자님!`); + // 환영 메시지를 표시했다는 것을 세션 스토리지에 저장 + sessionStorage.setItem('hasShownWelcome', 'true'); + } + return true; } else { alert("로그인 실패! 관리자만 접근 가능합니다.");