From 2d8ac924045fc23af0db0e553819307e2f00f5d8 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Sat, 14 Mar 2026 09:51:40 +0900 Subject: [PATCH] =?UTF-8?q?fix(ux):=20=EB=8D=B0=EC=8A=A4=ED=81=AC=ED=83=91?= =?UTF-8?q?=20UX=20=EC=9D=BC=EA=B4=84=20=EA=B0=9C=EC=84=A0=20=E2=80=94=20f?= =?UTF-8?q?ade-in=C2=B7ESC=C2=B7=EC=8A=A4=ED=81=AC=EB=A1=A4=EC=9E=A0?= =?UTF-8?q?=EA=B8=88=C2=B7z-index=C2=B7sticky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A1: fade-in querySelectorAll 전환 (5개 core.js) — 복수 요소 모두 표시 A2: 모달 ESC 키 닫기 (5개 core.js) A3: 모바일 메뉴 body 스크롤 잠금 (tkfb-core.js) A4: Gateway 대시보드 max-width 800→1080px B1: 모달 z-index 50→60 — 헤더 위에 표시 (4개 CSS) B3: 테이블 sticky header (tkfb.css, tkpurchase.css) Co-Authored-By: Claude Opus 4.6 --- gateway/html/dashboard.html | 2 +- system1-factory/web/static/css/tkfb.css | 3 ++- system1-factory/web/static/js/tkfb-core.js | 11 ++++++++++- tkpurchase/web/static/css/tkpurchase.css | 3 ++- tkpurchase/web/static/js/tkpurchase-core.js | 10 +++++++++- tksafety/web/static/css/tksafety.css | 2 +- tksafety/web/static/js/tksafety-core.js | 10 +++++++++- tksupport/web/static/css/tksupport.css | 2 +- tksupport/web/static/js/tksupport-core.js | 10 +++++++++- user-management/web/static/js/tkuser-core.js | 10 +++++++++- 10 files changed, 53 insertions(+), 10 deletions(-) diff --git a/gateway/html/dashboard.html b/gateway/html/dashboard.html index 627f0c8..1ca90d6 100644 --- a/gateway/html/dashboard.html +++ b/gateway/html/dashboard.html @@ -112,7 +112,7 @@ .btn-logout:hover { background: rgba(255,255,255,0.3); } .container { - max-width: 800px; + max-width: 1080px; margin: 0 auto; padding: 24px 16px 40px; } diff --git a/system1-factory/web/static/css/tkfb.css b/system1-factory/web/static/css/tkfb.css index cf89ec2..3dd0d83 100644 --- a/system1-factory/web/static/css/tkfb.css +++ b/system1-factory/web/static/css/tkfb.css @@ -29,6 +29,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b /* Table */ .data-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; } .data-table th { background: #f1f5f9; padding: 0.625rem 0.75rem; text-align: left; font-weight: 600; color: #475569; white-space: nowrap; border-bottom: 2px solid #e2e8f0; } +.data-table thead th { position: sticky; top: 56px; z-index: 10; } .data-table td { padding: 0.625rem 0.75rem; border-bottom: 1px solid #f1f5f9; vertical-align: middle; } .data-table tr:hover { background: #f8fafc; } @@ -47,7 +48,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b .collapsible-content.open { max-height: 500px; } /* Modal */ -.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 1rem; } +.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 60; padding: 1rem; } .modal-content { background: white; border-radius: 0.75rem; max-width: 40rem; width: 100%; max-height: 90vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,0.2); } /* Responsive */ diff --git a/system1-factory/web/static/js/tkfb-core.js b/system1-factory/web/static/js/tkfb-core.js index 0fb835f..ae62145 100644 --- a/system1-factory/web/static/js/tkfb-core.js +++ b/system1-factory/web/static/js/tkfb-core.js @@ -221,6 +221,7 @@ function toggleMobileMenu() { const isOpen = nav.classList.contains('mobile-open'); nav.classList.toggle('mobile-open'); if (overlay) overlay.classList.toggle('hidden', isOpen); + document.body.style.overflow = isOpen ? '' : 'hidden'; } /* ===== State ===== */ @@ -285,7 +286,7 @@ async function initAuth() { // 알림 벨 로드 _loadNotificationBell(); - setTimeout(() => document.querySelector('.fade-in')?.classList.add('visible'), 50); + setTimeout(() => document.querySelectorAll('.fade-in').forEach(el => el.classList.add('visible')), 50); return true; } @@ -295,3 +296,11 @@ function _loadNotificationBell() { s.src = (location.hostname.includes('technicalkorea.net') ? 'https://tkds.technicalkorea.net' : location.protocol + '//' + location.hostname + ':30000') + '/shared/notification-bell.js?v=3'; document.head.appendChild(s); } + +/* ===== Modal ESC 닫기 ===== */ +document.addEventListener('keydown', e => { + if (e.key === 'Escape') { + document.querySelectorAll('.modal-overlay:not(.hidden)') + .forEach(m => m.classList.add('hidden')); + } +}); diff --git a/tkpurchase/web/static/css/tkpurchase.css b/tkpurchase/web/static/css/tkpurchase.css index c558ad7..ed7d4ff 100644 --- a/tkpurchase/web/static/css/tkpurchase.css +++ b/tkpurchase/web/static/css/tkpurchase.css @@ -21,6 +21,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b /* Table */ .visit-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; } .visit-table th { background: #f1f5f9; padding: 0.625rem 0.75rem; text-align: left; font-weight: 600; color: #475569; white-space: nowrap; border-bottom: 2px solid #e2e8f0; } +.visit-table thead th { position: sticky; top: 56px; z-index: 10; } .visit-table td { padding: 0.625rem 0.75rem; border-bottom: 1px solid #f1f5f9; vertical-align: middle; } .visit-table tr:hover { background: #f8fafc; } @@ -48,7 +49,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b .collapsible-content.open { max-height: 500px; } /* Modal */ -.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 1rem; } +.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 60; padding: 1rem; } .modal-content { background: white; border-radius: 0.75rem; max-width: 40rem; width: 100%; max-height: 90vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,0.2); } /* Safety warning */ diff --git a/tkpurchase/web/static/js/tkpurchase-core.js b/tkpurchase/web/static/js/tkpurchase-core.js index e6cf166..8011c38 100644 --- a/tkpurchase/web/static/js/tkpurchase-core.js +++ b/tkpurchase/web/static/js/tkpurchase-core.js @@ -149,7 +149,7 @@ function initAuth() { // 알림 벨 로드 _loadNotificationBell(); - setTimeout(() => document.querySelector('.fade-in')?.classList.add('visible'), 50); + setTimeout(() => document.querySelectorAll('.fade-in').forEach(el => el.classList.add('visible')), 50); return true; } @@ -159,3 +159,11 @@ function _loadNotificationBell() { s.src = (location.hostname.includes('technicalkorea.net') ? 'https://tkds.technicalkorea.net' : location.protocol + '//' + location.hostname + ':30000') + '/shared/notification-bell.js?v=3'; document.head.appendChild(s); } + +/* ===== Modal ESC 닫기 ===== */ +document.addEventListener('keydown', e => { + if (e.key === 'Escape') { + document.querySelectorAll('.modal-overlay:not(.hidden)') + .forEach(m => m.classList.add('hidden')); + } +}); diff --git a/tksafety/web/static/css/tksafety.css b/tksafety/web/static/css/tksafety.css index a741cb9..193c430 100644 --- a/tksafety/web/static/css/tksafety.css +++ b/tksafety/web/static/css/tksafety.css @@ -47,7 +47,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b .collapsible-content.open { max-height: 500px; } /* Modal */ -.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 1rem; } +.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 60; padding: 1rem; } .modal-content { background: white; border-radius: 0.75rem; max-width: 40rem; width: 100%; max-height: 90vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,0.2); } /* Safety warning */ diff --git a/tksafety/web/static/js/tksafety-core.js b/tksafety/web/static/js/tksafety-core.js index f5249c4..b60f643 100644 --- a/tksafety/web/static/js/tksafety-core.js +++ b/tksafety/web/static/js/tksafety-core.js @@ -140,7 +140,7 @@ function initAuth() { // 알림 벨 로드 _loadNotificationBell(); - setTimeout(() => document.querySelector('.fade-in')?.classList.add('visible'), 50); + setTimeout(() => document.querySelectorAll('.fade-in').forEach(el => el.classList.add('visible')), 50); return true; } @@ -150,3 +150,11 @@ function _loadNotificationBell() { s.src = (location.hostname.includes('technicalkorea.net') ? 'https://tkds.technicalkorea.net' : location.protocol + '//' + location.hostname + ':30000') + '/shared/notification-bell.js?v=3'; document.head.appendChild(s); } + +/* ===== Modal ESC 닫기 ===== */ +document.addEventListener('keydown', e => { + if (e.key === 'Escape') { + document.querySelectorAll('.modal-overlay:not(.hidden)') + .forEach(m => m.classList.add('hidden')); + } +}); diff --git a/tksupport/web/static/css/tksupport.css b/tksupport/web/static/css/tksupport.css index 8ee0cb6..9d2926d 100644 --- a/tksupport/web/static/css/tksupport.css +++ b/tksupport/web/static/css/tksupport.css @@ -34,7 +34,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b .badge-purple { background: #f5f3ff; color: #7c3aed; } /* Modal */ -.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 1rem; } +.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 60; padding: 1rem; } .modal-content { background: white; border-radius: 0.75rem; max-width: 40rem; width: 100%; max-height: 90vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,0.2); } /* Empty state */ diff --git a/tksupport/web/static/js/tksupport-core.js b/tksupport/web/static/js/tksupport-core.js index f002538..c0de452 100644 --- a/tksupport/web/static/js/tksupport-core.js +++ b/tksupport/web/static/js/tksupport-core.js @@ -132,7 +132,7 @@ function initAuth() { // 알림 벨 로드 _loadNotificationBell(); - setTimeout(() => document.querySelector('.fade-in')?.classList.add('visible'), 50); + setTimeout(() => document.querySelectorAll('.fade-in').forEach(el => el.classList.add('visible')), 50); return true; } @@ -142,3 +142,11 @@ function _loadNotificationBell() { s.src = (location.hostname.includes('technicalkorea.net') ? 'https://tkds.technicalkorea.net' : location.protocol + '//' + location.hostname + ':30000') + '/shared/notification-bell.js?v=3'; document.head.appendChild(s); } + +/* ===== Modal ESC 닫기 ===== */ +document.addEventListener('keydown', e => { + if (e.key === 'Escape') { + document.querySelectorAll('.modal-overlay:not(.hidden)') + .forEach(m => m.classList.add('hidden')); + } +}); diff --git a/user-management/web/static/js/tkuser-core.js b/user-management/web/static/js/tkuser-core.js index 7d8149c..9253d80 100644 --- a/user-management/web/static/js/tkuser-core.js +++ b/user-management/web/static/js/tkuser-core.js @@ -186,7 +186,7 @@ async function init() { // 알림 벨 로드 _loadNotificationBell(); - setTimeout(() => document.querySelector('.fade-in').classList.add('visible'), 50); + setTimeout(() => document.querySelectorAll('.fade-in').forEach(el => el.classList.add('visible')), 50); } /* ===== 알림 벨 ===== */ @@ -195,3 +195,11 @@ function _loadNotificationBell() { s.src = (location.hostname.includes('technicalkorea.net') ? 'https://tkds.technicalkorea.net' : location.protocol + '//' + location.hostname + ':30000') + '/shared/notification-bell.js?v=3'; document.head.appendChild(s); } + +/* ===== Modal ESC 닫기 ===== */ +document.addEventListener('keydown', e => { + if (e.key === 'Escape') { + document.querySelectorAll('.modal-overlay:not(.hidden)') + .forEach(m => m.classList.add('hidden')); + } +});