style: 표/패널 UI 전면 통일 + 화면설명 드로어·글씨크기·탭 개선

표 디자인
- 모든 표를 가벼운 스타일로 통일(.data-table 경량화: 작은 회색 헤더·연한 구분선·hover)
- 표/패널 바깥 테두리 둥글게(rounded-lg) 일괄 적용, 표 래퍼에 패딩 카드(p-4) 통일
- 표 헤더·데이터 정렬을 전 화면 좌측 기준으로 통일
  - .data-table th/td text-align:left (전역), 흩어진 center/right 정렬 정리
  - 재디자인 Tailwind 표(포장단위·단가·기본코드·담당자·업체·판매대행소·무료대상자·지정판매소)도 셀 좌측화
- 기본정보관리 등 나머지 소메뉴 표를 기본 코드 관리 스타일(가벼운 표·상태 pill)로 재디자인

워크스페이스/공통
- "이 화면 설명" → 새 탭 대신 우측 드로어 팝업(현재 화면과 동시에 보기, Esc·드래그 폭조절)
- 상단바 글씨 크기 조절(A−/A+), 작업 내용에 zoom 적용
- 탭 최대치 도달 시 자동 삭제 대신 안내 토스트, "모두 닫기"(업무 현황 탭은 보존)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
taekyoungc
2026-06-11 17:26:36 +09:00
parent 912ffdbe23
commit a8afaf4af2
108 changed files with 1198 additions and 965 deletions

View File

@@ -43,11 +43,22 @@ tailwind.config = {
.embed-flash.ok { background: #ecfdf5; border: 1px solid #a7f3d0; color: #065f46; }
.embed-flash.err { background: #fef2f2; border: 1px solid #fecaca; color: #991b1b; }
.data-table { width: 100%; border-collapse: collapse; font-family: 'Pretendard', 'Malgun Gothic', 'Noto Sans KR', sans-serif; }
.data-table th, .data-table td { border: 1px solid #ccc; padding: 4px 8px; white-space: nowrap; font-size: 13px; }
.data-table th { background-color: #e9ecef; text-align: center; vertical-align: middle; font-weight: bold; color: #333; }
.data-table tbody tr:nth-child(even) td { background-color: #f9f9f9; }
.data-table tbody tr:hover td { background-color: #e6f7ff !important; }
.data-table { font-size: 13px; }
.data-table th, .data-table td { text-align: left; padding: 0.55rem 0.5rem; white-space: nowrap; border: 0; border-bottom: 1px solid #e5e7eb; }
.data-table thead th { font-size: 0.6875rem; font-weight: 600; color: #6b7280; background: transparent; vertical-align: middle; }
.data-table tbody td { color: #374151; }
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr:hover td { background-color: #f9fafb; }
@media print { .no-print { display: none !important; } .embed-titlebar { display: none; } }
/* 화면 설명 드로어(팝업) — 현재 화면 위 오른쪽에 겹쳐 띄움 */
.help-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 92vw); background: #fff; box-shadow: -8px 0 26px rgba(0,0,0,.18); z-index: 9999; display: none; flex-direction: column; }
.help-drawer.open { display: flex; }
.help-drawer-head { display: flex; align-items: center; justify-content: space-between; padding: .5rem .75rem; background: #1a2b4b; color: #fff; font-size: .8rem; font-weight: 700; flex-shrink: 0; }
.help-drawer-head .hd-btns { display: flex; gap: 4px; }
.help-drawer-head .hd-btn { color: #fff; background: rgba(255,255,255,.14); border: 0; width: 26px; height: 26px; border-radius: 6px; cursor: pointer; font-size: 13px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
.help-drawer-head .hd-btn:hover { background: rgba(255,255,255,.28); }
.help-drawer iframe { flex: 1; width: 100%; border: 0; background: #fff; }
.help-drawer-grip { position: absolute; left: -4px; top: 0; bottom: 0; width: 8px; cursor: col-resize; }
</style>
</head>
<body>
@@ -76,6 +87,20 @@ tailwind.config = {
</div>
<?php endif; ?>
</div>
<!-- 화면 설명 드로어(팝업) -->
<div id="helpDrawer" class="help-drawer no-print" aria-hidden="true">
<div class="help-drawer-grip" id="helpDrawerGrip"></div>
<div class="help-drawer-head">
<span><i class="fa-regular fa-circle-question"></i> 화면 설명</span>
<div class="hd-btns">
<a id="helpDrawerTab" href="#" class="hd-btn" title="탭으로 열기"><i class="fa-solid fa-up-right-from-square"></i></a>
<button type="button" id="helpDrawerClose" class="hd-btn" title="닫기">&times;</button>
</div>
</div>
<iframe id="helpDrawerFrame" title="화면 설명"></iframe>
</div>
<script>
(function () {
// 세션 만료 등으로 iframe 안에서 로그인 페이지가 열리면 상위 프레임을 로그인으로 보낸다.
@@ -106,19 +131,46 @@ tailwind.config = {
return u.href;
} catch (e) { return null; }
}
// "이 화면 설명" → 워크스페이스 새 탭으로 매뉴얼 열기(없으면 새 창)
// "이 화면 설명" → 현재 화면 위 오른쪽 드로어(팝업)로 띄워 동시에 보기
var drawer = document.getElementById('helpDrawer');
var dFrame = document.getElementById('helpDrawerFrame');
function withEmbedUrl(url) { try { var x = new URL(url, location.href); x.searchParams.set('embed', '1'); return x.href; } catch (e) { return url; } }
function openHelp(url) {
var u = withEmbedUrl(url);
if (dFrame.getAttribute('data-src') !== u) { dFrame.src = u; dFrame.setAttribute('data-src', u); }
var tab = document.getElementById('helpDrawerTab'); if (tab) tab.setAttribute('href', url);
drawer.classList.add('open');
}
function closeHelp() { drawer.classList.remove('open'); }
document.addEventListener('click', function (e) {
var h = e.target.closest ? e.target.closest('a.embed-help') : null;
if (!h) return;
e.preventDefault(); e.stopPropagation();
var url = h.getAttribute('href');
try {
if (window.parent && window.parent !== window && typeof window.parent.wsOpenTab === 'function') {
window.parent.wsOpenTab(url, '도움말'); return;
}
} catch (err) {}
window.open(url, '_blank');
openHelp(h.getAttribute('href'));
}, true);
document.getElementById('helpDrawerClose').addEventListener('click', closeHelp);
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeHelp(); });
// 드로어 헤더의 "탭으로 열기" → 워크스페이스 탭으로(없으면 새 창)
document.getElementById('helpDrawerTab').addEventListener('click', function (e) {
e.preventDefault();
var url = this.getAttribute('href') || '';
try { if (window.parent && window.parent !== window && typeof window.parent.wsOpenTab === 'function') { window.parent.wsOpenTab(url, '도움말'); closeHelp(); return; } } catch (err) {}
window.open(url, '_blank');
});
// 드로어 폭 드래그 조절
(function () {
var grip = document.getElementById('helpDrawerGrip'), dragging = false;
grip.addEventListener('mousedown', function (e) { e.preventDefault(); dragging = true; document.body.style.userSelect = 'none'; });
document.addEventListener('mousemove', function (e) { if (!dragging) return; var w = window.innerWidth - e.clientX; drawer.style.width = Math.min(window.innerWidth * 0.92, Math.max(300, w)) + 'px'; });
document.addEventListener('mouseup', function () { dragging = false; document.body.style.userSelect = ''; });
})();
// 글씨 크기(zoom) — 상단바에서 조절한 값을 적용. localStorage 공유 + storage 이벤트로 실시간 반영.
function applyFontScale() {
try { var s = parseInt(localStorage.getItem('jrj_font_scale') || '100', 10); if (!(s >= 70 && s <= 150)) s = 100; document.documentElement.style.zoom = (s / 100); } catch (e) {}
}
applyFontScale();
window.addEventListener('storage', function (e) { if (e.key === 'jrj_font_scale') applyFontScale(); });
document.addEventListener('click', function (e) {
var a = e.target.closest ? e.target.closest('a[href]') : null;