From 00ca43e4cda42c6fec0e3ffa30dbeb202e914e35 Mon Sep 17 00:00:00 2001 From: hyunho Date: Wed, 25 Mar 2026 10:50:28 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A1=B0=EC=A7=81=EB=8F=84=20=EC=A4=91?= =?UTF-8?q?=EC=8B=AC=20=EB=A9=94=EC=9D=B8=20=ED=99=94=EB=A9=B4=20=EC=83=98?= =?UTF-8?q?=ED=94=8C=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/app.js | 13 +- frontend/public/index.html | 129 +++++----- frontend/public/styles.css | 483 ++++++++++++++++++++++++------------- 3 files changed, 394 insertions(+), 231 deletions(-) mode change 100755 => 100644 frontend/public/index.html mode change 100755 => 100644 frontend/public/styles.css diff --git a/frontend/public/app.js b/frontend/public/app.js index a43b19e..bcfee09 100755 --- a/frontend/public/app.js +++ b/frontend/public/app.js @@ -7,7 +7,6 @@ const loginMessage = document.getElementById("login-message"); const logoutBtn = document.getElementById("logout-btn"); const userBadge = document.getElementById("user-badge"); const healthStatus = document.getElementById("health-status"); -const refreshHealthBtn = document.getElementById("refresh-health-btn"); function getSession() { try { @@ -38,14 +37,15 @@ function renderAuth() { async function refreshHealth() { if (!healthStatus) return; - healthStatus.textContent = "서버 상태를 확인하는 중입니다."; + healthStatus.textContent = "서버 상태 확인 중"; try { const response = await fetch("/api/health"); if (!response.ok) throw new Error("unhealthy"); const payload = await response.json(); - healthStatus.textContent = `API 상태: ${payload.status}`; + const count = typeof payload.member_count === "number" ? ` / ${payload.member_count}명` : ""; + healthStatus.textContent = `API ${payload.status}${count}`; } catch (error) { - healthStatus.textContent = "API에 연결할 수 없습니다. backend 컨테이너를 확인해주세요."; + healthStatus.textContent = "API 연결 실패"; } } @@ -77,9 +77,4 @@ if (logoutBtn) { }); } -if (refreshHealthBtn) { - refreshHealthBtn.addEventListener("click", refreshHealth); -} - renderAuth(); - diff --git a/frontend/public/index.html b/frontend/public/index.html old mode 100755 new mode 100644 index ab9d195..f52a3ad --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -3,77 +3,84 @@ - MH Dashboard Hub + MH 조직현황 대시보드 - + -
-
-
-

Intranet Preview

-

MH Dashboard Hub

-

- 현재 단계에서는 화면상 로그인만 우선 적용합니다. 로그인 후 조직도 레거시 화면과 - 서버 준비 상태를 한 곳에서 확인할 수 있습니다. -

+ +
- + + -
-
-

Legacy Module

-

조직도 관리

-

기존 단일 HTML 조직도 도구를 보존한 상태로 연결했습니다.

- 레거시 조직도 열기 -
- -
-

API Readiness

-

서버 상태

-

서버 상태를 확인하는 중입니다.

- -
- -
-

Roadmap

-

다음 단계

-
    -
  • 프로필 사진 업로드 API 연결
  • -
  • 좌석 배치도 좌표 저장 기능 연결
  • -
  • 월말 스냅샷 자동화
  • -
-
-
-
-
- diff --git a/frontend/public/styles.css b/frontend/public/styles.css old mode 100755 new mode 100644 index 7d06f46..84c5594 --- a/frontend/public/styles.css +++ b/frontend/public/styles.css @@ -1,210 +1,371 @@ :root { - --bg: #eef4f1; - --panel: rgba(255, 255, 255, 0.86); - --line: rgba(15, 23, 42, 0.08); - --text: #173028; - --muted: #5f746d; - --accent: #0f766e; - --accent-soft: #d7f3ee; - --shadow: 0 24px 60px rgba(14, 48, 41, 0.12); + --bg: #f1f5f9; + --bg-strong: #e2e8f0; + --panel: rgba(255, 255, 255, 0.92); + --line: rgba(148, 163, 184, 0.35); + --text: #0f172a; + --muted: #64748b; + --header: #1e293b; + --accent: #4f46e5; + --accent-soft: #e0e7ff; + --shadow: 0 24px 60px rgba(15, 23, 42, 0.16); } * { box-sizing: border-box; } +html, body { margin: 0; - min-height: 100vh; - font-family: "SUIT", sans-serif; + min-height: 100%; + font-family: "Pretendard", sans-serif; color: var(--text); background: - radial-gradient(circle at top left, rgba(15, 118, 110, 0.22), transparent 28%), - radial-gradient(circle at bottom right, rgba(20, 184, 166, 0.18), transparent 24%), - linear-gradient(135deg, #f5fbf7 0%, #e9f0fb 100%); + radial-gradient(circle at top left, rgba(79, 70, 229, 0.12), transparent 22%), + radial-gradient(circle at bottom right, rgba(148, 163, 184, 0.18), transparent 28%), + var(--bg); } -.app-shell { - max-width: 1240px; - margin: 0 auto; - padding: 48px 20px 56px; -} - -.panel { - background: var(--panel); - border: 1px solid var(--line); - border-radius: 28px; - box-shadow: var(--shadow); - backdrop-filter: blur(12px); -} - -.hero { - display: grid; - gap: 28px; - grid-template-columns: 1.2fr 0.8fr; - padding: 36px; -} - -.eyebrow { - margin: 0 0 10px; - color: var(--accent); - font-size: 12px; - font-weight: 800; - letter-spacing: 0.14em; - text-transform: uppercase; -} - -.hero h1, -.topbar h2, -.card h3 { - margin: 0; -} - -.hero h1 { - font-size: clamp(2.3rem, 5vw, 4.5rem); - line-height: 0.95; -} - -.hero-text, -.card p, -.helper-text, -.roadmap { - color: var(--muted); - line-height: 1.6; -} - -.login-card { - display: grid; - gap: 16px; - padding: 24px; - border-radius: 24px; - background: rgba(255, 255, 255, 0.92); - border: 1px solid rgba(15, 23, 42, 0.06); -} - -.login-card label, -.topbar { - display: flex; - flex-direction: column; - gap: 8px; +body { + min-height: 100vh; } +button, input, -button, -.anchor-button, -.primary-link { +a { font: inherit; } -input { - border: 1px solid rgba(15, 23, 42, 0.12); - border-radius: 14px; - padding: 14px 16px; - background: #fff; -} - -button, -.primary-link, -.anchor-button { - display: inline-flex; - justify-content: center; - align-items: center; - gap: 8px; - min-height: 48px; - border-radius: 14px; - border: none; - cursor: pointer; - font-weight: 800; - text-decoration: none; -} - -button, -.primary-link { - background: var(--accent); - color: #fff; -} - -.secondary, -.anchor-button { - background: var(--accent-soft); - color: var(--accent); -} - .hidden { display: none !important; } -.topbar { - flex-direction: row; - justify-content: space-between; +.eyebrow { + margin: 0 0 10px; + color: var(--accent); + font-size: 11px; + font-weight: 900; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +.login-screen { + min-height: 100vh; + display: grid; + grid-template-columns: 1.15fr 0.85fr; + gap: 28px; + padding: 32px; +} + +.login-hero, +.login-card { + border: 1px solid var(--line); + border-radius: 30px; + background: var(--panel); + box-shadow: var(--shadow); + backdrop-filter: blur(14px); +} + +.login-hero { + padding: 44px; + display: flex; + flex-direction: column; + justify-content: center; + min-height: calc(100vh - 64px); +} + +.login-hero h1, +.login-card h2, +.dashboard-header h2, +.stage-topline h3 { + margin: 0; +} + +.login-hero h1 { + font-size: clamp(2.4rem, 5vw, 4.8rem); + line-height: 0.96; + letter-spacing: -0.04em; +} + +.hero-text, +.helper-text { + color: var(--muted); + line-height: 1.7; +} + +.hero-text { + max-width: 680px; + margin: 20px 0 0; + font-size: 16px; +} + +.hero-points { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 28px; +} + +.hero-points span { + padding: 12px 16px; + border-radius: 999px; + background: #fff; + border: 1px solid rgba(79, 70, 229, 0.12); + color: #334155; + font-size: 13px; + font-weight: 800; +} + +.login-card { + align-self: center; + padding: 28px; + display: grid; + gap: 16px; +} + +.login-card-head { + margin-bottom: 8px; +} + +.login-card label { + display: flex; + flex-direction: column; + gap: 8px; + font-size: 13px; + font-weight: 800; + color: #475569; +} + +.login-card input { + min-height: 52px; + border: 1px solid rgba(148, 163, 184, 0.45); + border-radius: 16px; + padding: 14px 16px; + background: #fff; + outline: none; +} + +.login-card input:focus { + border-color: rgba(79, 70, 229, 0.55); + box-shadow: 0 0 0 4px rgba(79, 70, 229, 0.1); +} + +.login-card button, +.ghost-button, +.stage-link { + display: inline-flex; align-items: center; - margin-bottom: 24px; + justify-content: center; + min-height: 48px; + border-radius: 14px; + font-weight: 800; + text-decoration: none; + cursor: pointer; } -.topbar.compact { - max-width: 1240px; - margin: 0 auto; - padding: 28px 20px 0; +.login-card button { + margin-top: 8px; + border: none; + color: #fff; + background: var(--accent); } -.topbar-actions { +.helper-text { + margin: 0; + font-size: 13px; +} + +.dashboard-shell { + min-height: 100vh; + display: flex; + flex-direction: column; +} + +.dashboard-header { + min-height: 88px; + background: rgba(30, 41, 59, 0.96); + color: #fff; + border-bottom: 1px solid rgba(148, 163, 184, 0.2); + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: 20px; + padding: 18px 26px; + position: sticky; + top: 0; + z-index: 50; + backdrop-filter: blur(16px); +} + +.dashboard-header .eyebrow { + color: #a5b4fc; + margin-bottom: 6px; +} + +.header-center { + display: flex; + justify-content: center; + gap: 10px; + flex-wrap: wrap; +} + +.nav-pill { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 40px; + padding: 0 16px; + border-radius: 999px; + border: 1px solid rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.08); + color: #e2e8f0; + font-size: 13px; + font-weight: 800; +} + +.nav-pill.active { + background: var(--accent); + border-color: transparent; + color: #fff; + box-shadow: 0 10px 24px rgba(79, 70, 229, 0.3); +} + +.nav-pill.muted { + color: #94a3b8; +} + +.header-actions { display: flex; align-items: center; gap: 12px; } -.badge { - padding: 10px 14px; +.status-badge, +.user-badge { + display: inline-flex; + align-items: center; + min-height: 40px; + padding: 0 14px; border-radius: 999px; - background: rgba(15, 118, 110, 0.12); + font-size: 12px; + font-weight: 800; +} + +.status-badge { + background: rgba(79, 70, 229, 0.18); + color: #c7d2fe; +} + +.user-badge { + background: rgba(255, 255, 255, 0.1); + color: #fff; +} + +.ghost-button { + border: 1px solid rgba(255, 255, 255, 0.16); + background: transparent; + color: #fff; + padding: 0 16px; +} + +.dashboard-main { + flex: 1; + min-height: calc(100vh - 88px); + padding: 18px; +} + +.main-stage { + height: calc(100vh - 124px); + display: flex; + flex-direction: column; + gap: 14px; +} + +.stage-topline { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 18px; + padding: 0 8px; +} + +.stage-label { + margin: 0 0 6px; + color: var(--muted); + font-size: 11px; + font-weight: 900; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +.stage-topline h3 { + font-size: 28px; + line-height: 1; + letter-spacing: -0.03em; +} + +.stage-link { + padding: 0 16px; color: var(--accent); - font-weight: 700; + border: 1px solid rgba(79, 70, 229, 0.18); + background: rgba(255, 255, 255, 0.78); } -.grid { - display: grid; - gap: 20px; - grid-template-columns: repeat(3, minmax(0, 1fr)); -} - -.card { - padding: 24px; -} - -.roadmap { - padding-left: 18px; - margin: 0; -} - -.iframe-wrap { - max-width: 1240px; - margin: 0 auto; - padding: 20px; -} - -.iframe-wrap iframe { - width: 100%; - min-height: calc(100vh - 130px); - border: 1px solid var(--line); - border-radius: 24px; - background: #fff; +.stage-frame { + flex: 1; + min-height: 0; + border-radius: 28px; + border: 1px solid rgba(148, 163, 184, 0.26); + background: rgba(255, 255, 255, 0.85); box-shadow: var(--shadow); + overflow: hidden; } -.subpage-body { - padding-bottom: 20px; +.stage-frame iframe { + width: 100%; + height: 100%; + border: 0; + background: #fff; } -@media (max-width: 920px) { - .hero, - .grid { +@media (max-width: 1180px) { + .dashboard-header { grid-template-columns: 1fr; + align-items: flex-start; } - .topbar, - .topbar-actions { + .header-center { + justify-content: flex-start; + } + + .header-actions { + flex-wrap: wrap; + } +} + +@media (max-width: 980px) { + .login-screen { + grid-template-columns: 1fr; + padding: 20px; + } + + .login-hero { + min-height: auto; + } +} + +@media (max-width: 720px) { + .dashboard-main { + padding: 12px; + } + + .main-stage { + height: calc(100vh - 170px); + } + + .stage-topline { flex-direction: column; align-items: flex-start; } } -