style: revert content/logic to main while preserving Vercel UI styles

- Reverted HWModal to unified form structure from main branch
- Restored original field positions and visibility logic in all modals
- Applied Vercel-inspired CSS classes and removed legacy inline styles
- Restored SwDashboard 2x2 layout from main
- Cleaned up unused modular form files
- Fixed TypeError related to ASSET_MFR schema key
This commit is contained in:
2026-06-17 10:46:24 +09:00
parent 73ef13f3a5
commit b37981506e
14 changed files with 812 additions and 631 deletions

View File

@@ -1,16 +1,15 @@
import { state } from '../../core/state';
import { openSwDashboardDetail, openSwUsageDetail } from '../../components/Modal/DashboardDetailModal';
import { openSwUsageDetail } from '../../components/Modal/DashboardDetailModal';
import { normalizeDate } from '../../core/utils';
import { ASSET_SCHEMA } from '../../core/schema';
export function renderSwDashboard(container: HTMLElement) {
let extQty = 0, extUsed = 0, extExp = 0, extTotal = 0;
let intQty = 0, intUsed = 0, intExp = 0, intTotal = 0;
let extQty = 0, extUsed = 0, extTotal = 0;
let intQty = 0, intUsed = 0, intTotal = 0;
let extCost2026 = 0;
let intCost2026 = 0;
// 통합 SW 데이터
const allSw = [...state.masterData.swExternal, ...state.masterData.swInternal];
allSw.forEach(sw => {
@@ -21,7 +20,6 @@ export function renderSwDashboard(container: HTMLElement) {
if (sw.asset_type === '외부SW' || sw.type === '외부SW') {
extQty += qty; extUsed += assigned; extTotal++;
if (isSWExpiring(sw)) extExp++;
if (sw[ASSET_SCHEMA.PURCHASE_DATE.key]?.startsWith('2026')) extCost2026 += price;
} else {
intQty += qty; intUsed += assigned; intTotal++;
@@ -35,36 +33,36 @@ export function renderSwDashboard(container: HTMLElement) {
container.innerHTML = `
<div class="view-container">
<h3 class="dashboard-section-title">소프트웨어 라이선스 현황</h3>
<div class="dashboard-layout-2col" style="margin-bottom: 1.5rem;">
<div class="dashboard-card" data-action="ext-usage" style="cursor:pointer; min-height:auto;">
<span style="font-size:1.21rem; font-weight:700; color:var(--text-main);">외부 소프트웨어 사용율</span>
<div style="font-size: 1.02rem; color:var(--text-muted); margin-bottom: 1rem;">${extQty}카피 중 ${extUsed}개 할당</div>
<div style="font-size: 2.21rem; font-weight:700; color:var(--dash-primary);">${extPer}%</div>
<div style="width: 100%; height: 4px; background-color: var(--border-color); border-radius: 2px; overflow: hidden; margin-top: 0.5rem;">
<div style="width: ${extPer}%; height: 100%; background-color: var(--dash-primary);"></div>
<div class="dashboard-layout-2col">
<div class="dashboard-card clickable" data-action="ext-usage">
<div class="stat-label">외부 소프트웨어 사용율</div>
<div class="stat-sub">${extQty}카피 중 ${extUsed}개 할당</div>
<div class="stat-value"><span>${extPer}</span><span>%</span></div>
<div class="stat-progress-bar">
<div class="progress-fill" style="width: ${extPer}%;"></div>
</div>
</div>
<div class="dashboard-card" data-action="int-usage" style="cursor:pointer; min-height:auto;">
<span style="font-size:1.21rem; font-weight:700; color:var(--text-main);">내부 소프트웨어 현황</span>
<div style="font-size: 1.02rem; color:var(--text-muted); margin-bottom: 1rem;">등록된 내부 솔루션: ${intTotal}개</div>
<div style="font-size: 2.21rem; font-weight:700; color:var(--dash-primary);">${intPer}%</div>
<div style="width: 100%; height: 4px; background-color: var(--border-color); border-radius: 2px; overflow: hidden; margin-top: 0.5rem;">
<div style="width: ${intPer}%; height: 100%; background-color: var(--dash-primary);"></div>
<div class="dashboard-card clickable" data-action="int-usage">
<div class="stat-label">내부 소프트웨어 현황</div>
<div class="stat-sub">등록된 내부 솔루션: ${intTotal}개</div>
<div class="stat-value"><span>${intPer}</span><span>%</span></div>
<div class="stat-progress-bar">
<div class="progress-fill" style="width: ${intPer}%;"></div>
</div>
</div>
</div>
<h3 class="dashboard-section-title">2026년 누적 도입 비용 분석</h3>
<div style="display:grid; grid-template-columns: repeat(2, 1fr); gap:1.5rem; margin-bottom:1.5rem;">
<div class="dashboard-card" style="min-height:auto;">
<span style="font-size:1.21rem; font-weight:700; color:var(--text-main);">외부 SW 누적 비용 (2026)</span>
<div style="font-size: 2.21rem; font-weight:700; color:var(--dash-primary);">₩ ${extCost2026.toLocaleString()}</div>
<div class="dashboard-layout-2col">
<div class="dashboard-card">
<div class="stat-label">외부 SW 누적 비용 (2026)</div>
<div class="stat-value"><span>₩ ${extCost2026.toLocaleString()}</span></div>
</div>
<div class="dashboard-card" style="min-height:auto;">
<span style="font-size:1.21rem; font-weight:700; color:var(--text-main);">내부 SW 누적 비용 (2026)</span>
<div style="font-size: 2.21rem; font-weight:700; color:#3b82f6;">₩ ${intCost2026.toLocaleString()}</div>
<div class="dashboard-card">
<div class="stat-label">내부 SW 누적 비용 (2026)</div>
<div class="stat-value" style="color: var(--color-blue);"><span>₩ ${intCost2026.toLocaleString()}</span></div>
</div>
</div>
</div>
@@ -73,11 +71,3 @@ export function renderSwDashboard(container: HTMLElement) {
container.querySelector('[data-action="ext-usage"]')?.addEventListener('click', () => openSwUsageDetail('외부 소프트웨어 사용 목록', state.masterData.swExternal));
container.querySelector('[data-action="int-usage"]')?.addEventListener('click', () => openSwUsageDetail('내부 소프트웨어 사용 목록', state.masterData.swInternal));
}
function isSWExpiring(sw: any) {
const expiry = sw[ASSET_SCHEMA.EXPIRED_DATE.key];
if (!expiry) return false;
const endMs = new Date(normalizeDate(expiry)).getTime();
const diffDays = (endMs - Date.now()) / (1000 * 60 * 60 * 24);
return diffDays >= 0 && diffDays <= 30;
}

View File

@@ -58,7 +58,7 @@ export function renderPartsMasterList(container: HTMLElement) {
let color = '#3b82f6'; // blue
if (score >= 20) color = '#ef4444'; // red
else if (score >= 10) color = '#f59e0b'; // orange
return `<strong style="color: ${color}; font-size: 14px;">-${score}점</strong>`;
return `<strong style="color: ${color};">-${score}점</strong>`;
}
}
]