Files
MBN_STOCK_WEBVIEW/Web/index.html

174 lines
9.5 KiB
HTML

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'">
<title>MBN Stock WebView</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="app-shell">
<aside class="sidebar" aria-label="주요 메뉴">
<div class="brand-block">
<div class="brand-mark">M</div>
<div>
<strong>MBN STOCK</strong>
<span>방송 그래픽 콘솔</span>
</div>
</div>
<nav id="marketNav" class="market-nav">
<button class="nav-item active" data-market="dashboard"><span></span>대시보드</button>
<button class="nav-item" data-market="overseas"><span></span>해외</button>
<button class="nav-item" data-market="exchange"><span></span>환율</button>
<button class="nav-item" data-market="index"><span></span>지수</button>
<button class="nav-item" data-market="kospi"><span>K</span>코스피</button>
<button class="nav-item" data-market="kosdaq"><span>Q</span>코스닥</button>
<button class="nav-item" data-market="compare"><span></span>비교</button>
<button class="nav-item" data-market="theme"><span></span>테마</button>
<button class="nav-item" data-market="expert"><span></span>전문가</button>
<button class="nav-item" data-market="halted"><span></span>정지</button>
</nav>
<div class="sidebar-status">
<div class="status-row"><span class="status-dot ok"></span><span>Native Bridge</span><strong id="bridgeState">연결 중</strong></div>
<div class="status-row"><span id="databaseStateDot" class="status-dot pending"></span><span>Database</span><strong id="databaseState">확인 중</strong></div>
<div class="runtime" id="runtimeLabel">.NET 8 · WinUI 3 · x64</div>
</div>
</aside>
<main class="workspace">
<header class="workspace-header">
<div>
<p class="eyebrow">OPERATOR WORKSPACE</p>
<h1 id="workspaceTitle">마이그레이션 대시보드</h1>
</div>
<div class="header-meta">
<div><span>현재 시각</span><strong id="clock">--:--:--</strong></div>
<div><span>패키지</span><strong id="packageLabel">MSIX</strong></div>
<button id="requestInfoButton" class="ghost-button" type="button">상태 새로고침</button>
</div>
</header>
<section class="summary-strip" aria-label="마이그레이션 상태">
<article><span class="metric-icon mint"></span><div><strong>WebView UI</strong><small>FarPoint 대체 기반</small></div><b>READY</b></article>
<article><span class="metric-icon blue">71</span><div><strong>데이터 요청</strong><small>기존 SQL 계층 이관</small></div><b>MIGRATED</b></article>
<article id="databaseSummary"><span id="databaseSummaryIcon" class="metric-icon amber">DB</span><div><strong>Oracle · MariaDB</strong><small id="databaseSummaryDetail">연결 상태 확인 중</small></div><b id="databaseSummaryBadge">CHECKING</b></article>
<article id="playoutSummary" class="playout-summary"><span id="playoutSummaryIcon" class="metric-icon violet">T2</span><div><strong>Tornado Engine</strong><small id="playoutSummaryDetail">상태 확인 중</small></div><b id="playoutSummaryBadge">CHECKING</b></article>
</section>
<div class="console-grid">
<section class="panel catalog-panel">
<div class="panel-header">
<div><p class="panel-kicker">CUT CATALOG</p><h2>그래픽 항목</h2></div>
<span id="catalogModeBadge" class="badge">Web UI</span>
</div>
<label class="search-box">
<span></span>
<input id="catalogSearch" type="search" autocomplete="off" placeholder="종목·지수·그래픽 검색">
<kbd>Ctrl K</kbd>
</label>
<div id="catalogTabs" class="catalog-tabs" role="tablist">
<button class="active" type="button" data-category="all">전체</button>
<button type="button" data-category="plate"></button>
<button type="button" data-category="chart">차트</button>
<button type="button" data-category="market">시장</button>
</div>
<section id="liveDataPanel" class="live-data-panel" aria-labelledby="liveDataTitle" hidden>
<div class="live-data-header">
<div>
<p class="panel-kicker">LIVE DATABASE</p>
<h3 id="liveDataTitle">실시간 시장 데이터</h3>
</div>
<button id="retryLiveDataButton" class="live-retry" type="button">다시 조회</button>
</div>
<div id="databaseSources" class="database-sources" aria-label="데이터베이스 연결 상태"></div>
<div id="liveDataState" class="live-data-state" role="status" aria-live="polite"></div>
<div id="liveDataTables" class="live-data-tables"></div>
</section>
<div id="catalogList" class="catalog-list" aria-live="polite"></div>
</section>
<section class="panel playlist-panel">
<div class="panel-header">
<div><p class="panel-kicker">PLAYLIST</p><h2>송출 순서</h2></div>
<span id="playlistCount" class="badge neutral">0 CUTS</span>
</div>
<div class="playlist-actions">
<button id="selectAllButton" type="button">전체 선택</button>
<button id="moveUpButton" type="button" title="선택 항목 위로"></button>
<button id="moveDownButton" type="button" title="선택 항목 아래로"></button>
<button id="deleteButton" class="danger" type="button">삭제</button>
<span></span>
<button id="loadButton" type="button">불러오기</button>
<button id="saveButton" class="primary-soft" type="button">저장</button>
</div>
<div class="table-wrap">
<table>
<thead><tr><th class="check-cell"></th><th class="number-cell">#</th><th>그래픽 컷</th><th>구분</th><th class="drag-cell">정렬</th></tr></thead>
<tbody id="playlistBody"></tbody>
</table>
<div id="playlistEmpty" class="empty-state">
<strong>플레이리스트가 비어 있습니다.</strong>
<span>왼쪽 항목의 + 버튼으로 송출 순서를 구성하세요.</span>
</div>
</div>
</section>
<section class="panel playout-panel">
<div class="panel-header">
<div><p class="panel-kicker">PROGRAM / PREVIEW</p><h2>송출 제어</h2></div>
<span id="playoutState" class="badge neutral">IDLE</span>
</div>
<div class="playout-health" aria-label="Tornado 송출 연결 상태">
<div class="playout-health-item">
<span id="tornadoProcessDot" class="status-dot pending"></span>
<small>Tornado2 Process</small>
<strong id="tornadoProcessState">확인 중</strong>
</div>
<div class="playout-health-item">
<span id="playoutConnectionDot" class="status-dot pending"></span>
<small>Engine</small>
<strong id="playoutConnectionState">확인 중</strong>
</div>
<div class="playout-health-item safety">
<small>Safety Mode</small>
<strong id="playoutSafetyMode">확인 중</strong>
</div>
</div>
<div id="playoutStatusMessage" class="playout-status-message" role="status" aria-live="polite">송출 어댑터 상태를 확인하고 있습니다.</div>
<div id="playoutError" class="playout-error" role="alert" hidden>
<div><strong>송출 명령 오류</strong><span id="playoutErrorMessage"></span></div>
<button id="clearPlayoutErrorButton" type="button" aria-label="송출 오류 닫기">닫기</button>
</div>
<div class="preview-stage" id="previewStage">
<div class="safe-area">
<span>PREVIEW</span>
<strong id="previewTitle">선택된 그래픽 없음</strong>
<small id="previewSubtitle">플레이리스트 항목을 선택하세요.</small>
</div>
<div class="stage-corner top-left"></div><div class="stage-corner top-right"></div>
<div class="stage-corner bottom-left"></div><div class="stage-corner bottom-right"></div>
</div>
<div class="playout-controls">
<button id="prepareButton" class="prepare" type="button"><span>F2</span>PREPARE</button>
<button id="takeInButton" class="take-in" type="button"><span>F8</span>TAKE IN</button>
<button id="nextButton" type="button"><span></span>NEXT</button>
<button id="takeOutButton" class="take-out" type="button"><span>ESC</span>TAKE OUT</button>
</div>
<div class="event-log">
<div class="event-log-header"><strong>운영 로그</strong><button id="clearLogButton" type="button">지우기</button></div>
<ol id="eventLog"></ol>
</div>
</section>
</div>
</main>
</div>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script src="playout-safety.js"></script>
<script src="app.js"></script>
</body>
</html>