initial: blog-app snapshot

This commit is contained in:
omo
2026-08-17 17:11:27 +08:00
commit 65cb9d5ead
125 changed files with 14720 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
/* 项目列表页逻辑: 语言过滤 + 排序 + 项目卡片.
* renderProjectCard 由模板内联 module 注入.
*/
import { fetchJson } from "../utils.js";
export function initProjectsPage(renderProjectCard) {
let allProjects = [];
let currentLang = "all";
let currentSort = "stars";
function renderProjects() {
const container = document.getElementById("projectList");
let list = allProjects;
if (currentLang !== "all") {
list = list.filter((p) => (p.language || "") === currentLang);
}
list = [...list].sort((a, b) => {
if (currentSort === "stars") {
return (b.stars ?? 0) - (a.stars ?? 0);
}
return String(b.updated_at || "").localeCompare(String(a.updated_at || ""));
});
if (!list.length) {
container.innerHTML = '<div class="empty-hint">没有匹配的项目</div>';
return;
}
container.innerHTML = list
.map((p) =>
renderProjectCard(p, { showDescription: true, showUpdatedAt: true })
)
.join("");
}
async function loadProjects() {
try {
allProjects = await fetchJson("/api/projects");
renderProjects();
} catch (err) {
console.error("加载项目失败:", err);
document.getElementById("projectList").innerHTML =
'<div class="empty-hint empty-hint-error">加载失败, <button type="button" class="btn btn-sm btn-outline-danger js-retry-btn">点击重试</button></div>';
}
}
document.addEventListener("DOMContentLoaded", () => {
loadProjects();
document.querySelectorAll("[data-lang]").forEach((btn) => {
btn.addEventListener("click", () => {
document
.querySelectorAll("[data-lang]")
.forEach((b) => b.classList.remove("active"));
btn.classList.add("active");
currentLang = btn.dataset.lang;
renderProjects();
});
});
document.getElementById("sortSelect").addEventListener("change", (e) => {
currentSort = e.target.value;
renderProjects();
});
});
}