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() {

- {/* 사용자 메뉴 */} -
- + )} + + {/* 사용자 메뉴 */} +
+