From 60b8a81919b444ea38ccd144eae90bd8c3f60521 Mon Sep 17 00:00:00 2001 From: hyunho Date: Wed, 25 Mar 2026 12:42:45 +0900 Subject: [PATCH] =?UTF-8?q?=ED=97=A4=EB=8D=94=20=ED=83=AD=20=EC=A0=84?= =?UTF-8?q?=ED=99=98=20=EA=B5=AC=EC=A1=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/app.js | 39 +++++++++++++++++++++++++-- frontend/public/index.html | 25 +++++++++++------ frontend/public/styles.css | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 10 deletions(-) diff --git a/frontend/public/app.js b/frontend/public/app.js index f14196e..f4f238e 100755 --- a/frontend/public/app.js +++ b/frontend/public/app.js @@ -6,6 +6,18 @@ const loginForm = document.getElementById("login-form"); const loginMessage = document.getElementById("login-message"); const logoutBtn = document.getElementById("logout-btn"); const userBadge = document.getElementById("user-badge"); +const currentViewTitle = document.getElementById("current-view-title"); +const navButtons = Array.from(document.querySelectorAll(".header-center [data-view]")); +const stages = Array.from(document.querySelectorAll(".main-stage[data-stage]")); + +const viewLabels = { + ledger: "사업관리대장", + project: "프로젝트별 분석", + team: "팀/개인별 분석", + organization: "조직 현황", +}; + +let currentView = "organization"; function getSession() { try { @@ -23,14 +35,30 @@ function clearSession() { sessionStorage.removeItem(sessionKey); } +function setActiveView(view) { + currentView = view in viewLabels ? view : "organization"; + if (currentViewTitle) { + currentViewTitle.textContent = viewLabels[currentView]; + } + navButtons.forEach((button) => { + const active = button.dataset.view === currentView; + button.classList.toggle("active", active); + button.classList.toggle("muted", !active); + }); + stages.forEach((stage) => { + stage.hidden = stage.dataset.stage !== currentView; + }); +} + function renderAuth() { const session = getSession(); const authenticated = Boolean(session?.user?.display_name); loginPanel.classList.toggle("hidden", authenticated); dashboardPanel.classList.toggle("hidden", !authenticated); if (authenticated) { - userBadge.textContent = "내 정보"; - userBadge.title = `${session.user.display_name} / ${session.user.role}`; + const displayName = session.user.display_name || "접속자"; + userBadge.innerHTML = `${displayName}-`; + userBadge.title = `${displayName} / -`; } } @@ -62,4 +90,11 @@ if (logoutBtn) { }); } +navButtons.forEach((button) => { + button.addEventListener("click", () => { + setActiveView(button.dataset.view || "organization"); + }); +}); + +setActiveView(currentView); renderAuth(); diff --git a/frontend/public/index.html b/frontend/public/index.html index 29c0348..465b812 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -39,24 +39,33 @@

MH Dashboard

-

조직현황 메인

+

조직 현황

- 사업관리대장 - 프로젝트별 분석 - 팀/개인별 분석 - + + + +
- - + +
-
+ + + +
diff --git a/frontend/public/styles.css b/frontend/public/styles.css index d3d7f8c..5d28bb4 100644 --- a/frontend/public/styles.css +++ b/frontend/public/styles.css @@ -229,6 +229,55 @@ background: #f8fafc; } +.user-chip { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 0 10px; +} + +.user-chip-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + border-radius: 50%; + background: #e2e8f0; + color: #475569; + font-size: 10px; + font-weight: 900; + flex: 0 0 auto; +} + +.user-chip-text { + display: flex; + align-items: baseline; + gap: 6px; + white-space: nowrap; +} + +.user-chip-text strong, +.user-chip-text em { + font-size: 11px; + font-style: normal; +} + +.user-chip-text strong { + color: var(--color-text); +} + +.user-chip-text em { + color: var(--color-text-muted); +} + +.icon-button { + width: 34px; + padding: 0; + justify-content: center; + font-size: 13px; +} + .dashboard-main { flex: 1; min-height: calc(100vh - 68px); @@ -254,6 +303,12 @@ background: #fff; } +.stage-empty { + flex: 1; + min-height: 0; + background: transparent; +} + @media (max-width: 1180px) { .dashboard-header { grid-template-columns: 1fr;