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() {
- {/* 사용자 메뉴 */} -