Files
JH/mysql-preview.html

110 lines
4.3 KiB
HTML

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MySQL 데이터 미리보기</title>
<style>
:root {
--bg: #f5f7fb;
--card: #ffffff;
--line: #d6deea;
--text: #1f2a44;
--accent: #0d9488;
}
body { margin: 0; font-family: "Noto Sans KR", sans-serif; color: var(--text); background: linear-gradient(180deg, #eef4ff, var(--bg)); }
.wrap { max-width: 1200px; margin: 24px auto; padding: 0 16px; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 16px; }
.row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
select, input, button { padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; }
button { background: var(--accent); color: #fff; border: 0; cursor: pointer; }
button:hover { filter: brightness(0.95); }
.meta { margin: 10px 0; font-size: 13px; color: #475569; }
.table-wrap { overflow: auto; border: 1px solid var(--line); border-radius: 10px; }
table { border-collapse: collapse; width: 100%; min-width: 900px; background: #fff; }
th, td { border-bottom: 1px solid #ebf0f8; padding: 7px 9px; font-size: 13px; text-align: left; white-space: nowrap; }
th { position: sticky; top: 0; background: #f8fbff; z-index: 1; }
</style>
</head>
<body>
<div class="wrap">
<div class="card">
<h2 style="margin-top:0;">MySQL 데이터 미리보기</h2>
<div class="row">
<button id="btnLoadTables">테이블 목록 불러오기</button>
<select id="tableSelect"><option value="">테이블 선택</option></select>
<input id="limitInput" type="number" min="1" max="500" value="100">
<button id="btnLoadRows">데이터 조회</button>
</div>
<div id="meta" class="meta">대기 중</div>
<div class="table-wrap">
<table id="resultTable">
<thead></thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
<script>
const tableSelect = document.getElementById('tableSelect');
const limitInput = document.getElementById('limitInput');
const meta = document.getElementById('meta');
const thead = document.querySelector('#resultTable thead');
const tbody = document.querySelector('#resultTable tbody');
function setMeta(text) { meta.textContent = text; }
async function loadTables() {
setMeta('테이블 목록 조회 중...');
const res = await fetch('/api/mysql-tables');
const data = await res.json();
tableSelect.innerHTML = '<option value="">테이블 선택</option>';
(data.tables || []).forEach((t) => {
const opt = document.createElement('option');
opt.value = t;
opt.textContent = t;
tableSelect.appendChild(opt);
});
setMeta(`테이블 ${data.count || 0}개 로드 완료`);
}
async function loadRows() {
const table = tableSelect.value;
const limit = Number(limitInput.value || 100);
if (!table) return setMeta('테이블을 먼저 선택하세요.');
setMeta(`${table} 조회 중...`);
const res = await fetch(`/api/mysql-table-preview?table=${encodeURIComponent(table)}&limit=${encodeURIComponent(limit)}`);
const data = await res.json();
renderRows(data.rows || []);
setMeta(`${data.table} - ${data.count || 0}`);
}
function renderRows(rows) {
thead.innerHTML = '';
tbody.innerHTML = '';
if (!rows.length) return;
const cols = Object.keys(rows[0]);
const trh = document.createElement('tr');
cols.forEach((c) => {
const th = document.createElement('th');
th.textContent = c;
trh.appendChild(th);
});
thead.appendChild(trh);
rows.forEach((r) => {
const tr = document.createElement('tr');
cols.forEach((c) => {
const td = document.createElement('td');
td.textContent = r[c] == null ? '' : String(r[c]);
tr.appendChild(td);
});
tbody.appendChild(tr);
});
}
document.getElementById('btnLoadTables').addEventListener('click', loadTables);
document.getElementById('btnLoadRows').addEventListener('click', loadRows);
</script>
</body>
</html>