Add docs/index.html

This commit is contained in:
2026-02-12 03:40:22 +09:00
parent c39fc0cb47
commit d4593f6f94

381
docs/index.html Normal file
View File

@@ -0,0 +1,381 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Firmware Downloads</title>
<style>
:root {
--color-primary: #0366d6;
--color-success: #28a745;
--color-bg: #f6f8fa;
--color-border: #e1e4e8;
--color-text: #24292e;
--color-text-secondary: #586069;
--color-white: #ffffff;
--shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
--radius: 6px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Malgun Gothic', sans-serif;
background: var(--color-bg);
color: var(--color-text);
line-height: 1.6;
}
.header {
background: var(--color-white);
border-bottom: 1px solid var(--color-border);
padding: 24px 0;
}
.container {
max-width: 860px;
margin: 0 auto;
padding: 0 24px;
}
.header h1 {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 4px;
}
.header p {
color: var(--color-text-secondary);
font-size: 0.95rem;
}
.content {
padding: 24px 0;
}
.release-card {
background: var(--color-white);
border: 1px solid var(--color-border);
border-radius: var(--radius);
margin-bottom: 16px;
box-shadow: var(--shadow);
}
.release-header {
padding: 20px 24px;
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 8px;
}
.release-title {
font-size: 1.2rem;
font-weight: 600;
}
.release-meta {
display: flex;
align-items: center;
gap: 12px;
}
.tag {
display: inline-block;
background: var(--color-primary);
color: var(--color-white);
padding: 2px 10px;
border-radius: 20px;
font-size: 0.8rem;
font-weight: 500;
}
.tag-latest {
background: var(--color-success);
}
.date {
color: var(--color-text-secondary);
font-size: 0.85rem;
}
.release-body {
padding: 20px 24px;
border-bottom: 1px solid var(--color-border);
font-size: 0.95rem;
color: var(--color-text-secondary);
}
.release-body h2,
.release-body h3 {
font-size: 1rem;
color: var(--color-text);
margin-top: 12px;
margin-bottom: 4px;
}
.release-body ul {
padding-left: 20px;
margin: 4px 0;
}
.release-body li {
margin: 2px 0;
}
.release-assets {
padding: 16px 24px;
}
.assets-title {
font-size: 0.85rem;
font-weight: 600;
color: var(--color-text-secondary);
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.asset-link {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--color-success);
color: var(--color-white);
padding: 8px 16px;
border-radius: var(--radius);
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
margin: 4px 4px 4px 0;
transition: opacity 0.15s;
}
.asset-link:hover {
opacity: 0.85;
}
.asset-size {
font-size: 0.8rem;
opacity: 0.85;
}
.download-icon::before {
content: "\2193";
font-weight: bold;
}
.no-assets {
color: var(--color-text-secondary);
font-size: 0.9rem;
font-style: italic;
}
.loading,
.error-msg,
.empty-msg {
text-align: center;
padding: 60px 24px;
color: var(--color-text-secondary);
}
.error-msg {
color: #d73a49;
}
.spinner {
display: inline-block;
width: 24px;
height: 24px;
border: 3px solid var(--color-border);
border-top-color: var(--color-primary);
border-radius: 50%;
animation: spin 0.6s linear infinite;
margin-bottom: 12px;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.footer {
text-align: center;
padding: 24px;
color: var(--color-text-secondary);
font-size: 0.8rem;
border-top: 1px solid var(--color-border);
margin-top: 24px;
}
@media (max-width: 600px) {
.container {
padding: 0 16px;
}
.release-header {
padding: 16px;
}
.release-body,
.release-assets {
padding: 16px;
}
.release-meta {
width: 100%;
}
.asset-link {
display: flex;
text-align: center;
justify-content: center;
}
}
</style>
</head>
<body>
<div class="header">
<div class="container">
<h1 id="page-title">Firmware Downloads</h1>
<p id="page-desc">최신 펌웨어 릴리즈를 다운로드할 수 있습니다.</p>
</div>
</div>
<div class="content">
<div class="container" id="releases">
<div class="loading">
<div class="spinner"></div>
<p>릴리즈 목록을 불러오는 중...</p>
</div>
</div>
</div>
<div class="footer">
<div class="container">
<span id="company-name"></span>
</div>
</div>
<script>
// ================================================================
// 설정 - 환경에 맞게 수정
// ================================================================
const CONFIG = {
GITEA_URL: 'https://gitea.dabit.synology.me',
ORG: 'DabitReleases',
REPO: 'DIBD-Releases',
PAGE_TITLE: 'Firmware Downloads',
PAGE_DESC: '최신 펌웨어 릴리즈를 다운로드할 수 있습니다.',
COMPANY_NAME: '다빛솔루션',
};
// ================================================================
document.getElementById('page-title').textContent = CONFIG.PAGE_TITLE;
document.getElementById('page-desc').textContent = CONFIG.PAGE_DESC;
document.getElementById('company-name').textContent = CONFIG.COMPANY_NAME;
document.title = CONFIG.PAGE_TITLE;
function formatDate(dateStr) {
const d = new Date(dateStr);
return d.toLocaleDateString('ko-KR', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
}
function formatSize(bytes) {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}
function renderMarkdown(text) {
if (!text) return '';
return text
.replace(/^### (.+)$/gm, '<h3>$1</h3>')
.replace(/^## (.+)$/gm, '<h2>$1</h2>')
.replace(/^\- (.+)$/gm, '<li>$1</li>')
.replace(/(<li>.*<\/li>\n?)+/gs, '<ul>$&</ul>')
.replace(/\n{2,}/g, '<br><br>')
.replace(/\n/g, '<br>');
}
function renderRelease(release, isLatest) {
const assets = release.assets || [];
const assetsHtml = assets.length > 0
? assets.map(a =>
`<a class="asset-link" href="${a.browser_download_url}" download>
<span class="download-icon"></span>
${a.name}
<span class="asset-size">(${formatSize(a.size)})</span>
</a>`
).join('')
: '<span class="no-assets">첨부파일 없음</span>';
const latestTag = isLatest ? '<span class="tag tag-latest">Latest</span>' : '';
return `
<div class="release-card">
<div class="release-header">
<span class="release-title">${release.name || release.tag_name}</span>
<div class="release-meta">
<span class="tag">${release.tag_name}</span>
${latestTag}
<span class="date">${formatDate(release.published_at)}</span>
</div>
</div>
${release.body ? `<div class="release-body">${renderMarkdown(release.body)}</div>` : ''}
<div class="release-assets">
<div class="assets-title">Downloads</div>
${assetsHtml}
</div>
</div>`;
}
async function loadReleases() {
const container = document.getElementById('releases');
const apiUrl = `${CONFIG.GITEA_URL}/api/v1/repos/${CONFIG.ORG}/${CONFIG.REPO}/releases`;
try {
const res = await fetch(apiUrl);
if (!res.ok) {
throw new Error(`API 응답 오류 (${res.status})`);
}
const releases = await res.json();
if (!Array.isArray(releases) || releases.length === 0) {
container.innerHTML = `
<div class="empty-msg">
<p>등록된 릴리즈가 없습니다.</p>
</div>`;
return;
}
container.innerHTML = releases
.map((release, i) => renderRelease(release, i === 0))
.join('');
} catch (err) {
container.innerHTML = `
<div class="error-msg">
<p>릴리즈 목록을 불러올 수 없습니다.</p>
<p>${err.message}</p>
</div>`;
}
}
loadReleases();
</script>
</body>
</html>