initial: novel-app snapshot
This commit is contained in:
44
static/js/pages/index.js
Normal file
44
static/js/pages/index.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/* index page: 小说列表 dashboard. */
|
||||
|
||||
import { escapeHtml, fetchJson } from "../utils.js";
|
||||
import { statusBadge } from "../components/status-badge.js";
|
||||
|
||||
function renderCard(n) {
|
||||
const target = n.target_words || 0;
|
||||
const current = n.current_words || 0;
|
||||
const pct = target > 0 ? Math.min(100, Math.round((current / target) * 100)) : 0;
|
||||
return ''
|
||||
+ '<div class="col-md-4">'
|
||||
+ ' <div class="card h-100">'
|
||||
+ ' <div class="card-body">'
|
||||
+ ' <h5 class="card-title">' + escapeHtml(n.title) + '</h5>'
|
||||
+ ' <p class="card-text mb-2">'
|
||||
+ ' <span class="badge text-bg-primary">' + escapeHtml(n.genre || "未分类") + '</span> '
|
||||
+ statusBadge(n.status)
|
||||
+ ' </p>'
|
||||
+ ' <p class="card-text text-muted small">' + escapeHtml(n.style || "") + '</p>'
|
||||
+ ' <div class="progress mb-2" role="progressbar" aria-label="写作进度">'
|
||||
+ ' <div class="progress-bar" style="width:' + pct + '%">' + pct + '%</div>'
|
||||
+ ' </div>'
|
||||
+ ' <p class="card-text small text-muted">' + current + ' / ' + target + ' 字</p>'
|
||||
+ ' <a class="btn btn-outline-primary btn-sm" href="/novel/' + n.id + '">打开</a>'
|
||||
+ ' </div>'
|
||||
+ ' </div>'
|
||||
+ '</div>';
|
||||
}
|
||||
|
||||
async function loadNovels() {
|
||||
const container = document.getElementById("novelCards");
|
||||
try {
|
||||
const novels = await fetchJson("/api/novels");
|
||||
if (!novels.length) {
|
||||
container.innerHTML = '<div class="text-muted">还没有小说, 点击右上角"拆书创建新小说"开始。</div>';
|
||||
return;
|
||||
}
|
||||
container.innerHTML = novels.map(renderCard).join("");
|
||||
} catch (err) {
|
||||
container.innerHTML = '<div class="alert alert-danger">加载失败: ' + escapeHtml(err.message) + "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
loadNovels();
|
||||
Reference in New Issue
Block a user