From 521446d56ba33b152d4497eb2c299791f7a621e3 Mon Sep 17 00:00:00 2001
From: Hyungi Ahn
Date: Tue, 14 Oct 2025 07:51:16 +0900
Subject: [PATCH] =?UTF-8?q?=F0=9F=94=94=20=ED=9A=8C=EC=9B=90=EA=B0=80?=
=?UTF-8?q?=EC=9E=85=20=EC=8A=B9=EC=9D=B8=20=EC=95=8C=EB=9E=8C=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
- 상단 헤더에 🔔 알람 버튼 추가 (관리자 전용)
- 승인 대기 중인 사용자 수를 빨간 뱃지로 표시
- 클릭 시 사용자 관리 페이지로 이동
- 30초마다 자동 갱신
- 노란색 배경 + pulse 애니메이션으로 눈에 잘 띄게
- 마우스 오버 시 확대 효과
기능:
- GET /auth/signup-requests로 대기 수 조회
- 관리자(admin, system)만 표시
- 실시간 업데이트
---
frontend/src/App.css | 11 ++++++
frontend/src/App.jsx | 89 +++++++++++++++++++++++++++++++++++++++++---
2 files changed, 94 insertions(+), 6 deletions(-)
diff --git a/frontend/src/App.css b/frontend/src/App.css
index 90c0c6c..0c24079 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -71,6 +71,17 @@ body {
100% { transform: rotate(360deg); }
}
+@keyframes pulse {
+ 0%, 100% {
+ opacity: 1;
+ transform: scale(1);
+ }
+ 50% {
+ opacity: 0.8;
+ transform: scale(1.05);
+ }
+}
+
/* 접근 거부 페이지 */
.access-denied-container {
display: flex;
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 219b4d7..4c2117a 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -27,6 +27,19 @@ function App() {
const [newProjectCode, setNewProjectCode] = useState('');
const [newProjectName, setNewProjectName] = useState('');
const [newClientName, setNewClientName] = useState('');
+ const [pendingSignupCount, setPendingSignupCount] = useState(0);
+
+ // 승인 대기 중인 회원가입 수 조회
+ const loadPendingSignups = async () => {
+ try {
+ const response = await api.get('/auth/signup-requests');
+ if (response.data && response.data.requests) {
+ setPendingSignupCount(response.data.count || 0);
+ }
+ } catch (error) {
+ // 에러 무시 (관리자가 아니면 403)
+ }
+ };
// 프로젝트 목록 로드
const loadProjects = async () => {
@@ -104,8 +117,18 @@ function App() {
if (token && userData) {
setIsAuthenticated(true);
- setUser(JSON.parse(userData));
+ const userObj = JSON.parse(userData);
+ setUser(userObj);
loadProjects(); // 프로젝트 목록 로드
+
+ // 관리자인 경우 승인 대기 수 조회
+ if (userObj.role === 'admin' || userObj.role === 'system') {
+ loadPendingSignups();
+
+ // 30초마다 갱신
+ const interval = setInterval(loadPendingSignups, 30000);
+ return () => clearInterval(interval);
+ }
}
setIsLoading(false);
@@ -247,11 +270,65 @@ function App() {
- {/* 사용자 메뉴 */}
-
-