feat: initial release of pengzhan.dev personal editorial blog platform
- Editorial web platform built with Node.js, Express, EJS, and Vanilla CSS - Markdown content engine with YAML frontmatter, bilingual variants, and hot-reload watcher - Unified SQLite with FTS5 search indexing, query logging, and schema filters - Centered editorial post layout with margin-docked left TOC and mobile bottom sheet - WordPress-grade comment system with moderation dashboard and bulk operations under /guanli - Complete SEO suite (JSON-LD structured data, RSS/Atom feeds, XML sitemap, robots.txt) - CI/CD workflows for linting, security audits (Gitleaks), automated tests, and Docker releases
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
<div class="admin-header-wrapper" style="margin-bottom: 2.5rem; border-bottom: 1px solid var(--color-border); padding-bottom: 1.5rem;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; margin-bottom: 1.75rem;">
|
||||
<div>
|
||||
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
||||
<span style="font-size: 1.5rem;">⚙️</span>
|
||||
<h1 style="font-size: 1.8rem; margin: 0; font-family: var(--font-serif); font-weight: 700;">Site Administration</h1>
|
||||
</div>
|
||||
<p style="color: var(--color-text-secondary); margin: 0.25rem 0 0 0; font-size: 0.92rem;">Unified control panel for comments moderation, SEO health, and search logs.</p>
|
||||
</div>
|
||||
|
||||
<!-- Admin Navigation Tabs -->
|
||||
<div style="display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap;">
|
||||
<a href="/guanli/comments" class="btn <%= activeAdminTab === 'comments' ? 'btn-primary' : 'btn-secondary' %>" style="padding: 0.45rem 0.95rem; font-size: 0.88rem;">
|
||||
💬 Comments
|
||||
<% if (stats && stats.pendingComments > 0) { %>
|
||||
<span style="background: #ef4444; color: white; padding: 1px 6px; border-radius: 9999px; font-size: 0.72rem; margin-left: 0.35rem; font-weight: 700;"><%= stats.pendingComments %></span>
|
||||
<% } %>
|
||||
</a>
|
||||
|
||||
<a href="/guanli/seo" class="btn <%= activeAdminTab === 'seo' ? 'btn-primary' : 'btn-secondary' %>" style="padding: 0.45rem 0.95rem; font-size: 0.88rem;">
|
||||
📊 SEO Health
|
||||
</a>
|
||||
|
||||
<a href="/guanli/search" class="btn <%= activeAdminTab === 'search' ? 'btn-primary' : 'btn-secondary' %>" style="padding: 0.45rem 0.95rem; font-size: 0.88rem;">
|
||||
🔍 Search Analytics
|
||||
</a>
|
||||
|
||||
<a href="/guanli/logout" class="btn btn-secondary" style="padding: 0.45rem 0.85rem; font-size: 0.88rem; color: #b91c1c;" title="Sign Out">
|
||||
Sign Out 🚪
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Unified KPI Cards -->
|
||||
<% if (typeof stats !== 'undefined') { %>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; margin-top: 1.5rem;">
|
||||
<div class="admin-kpi-card">
|
||||
<div style="font-size: 0.8rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600;">Published Posts</div>
|
||||
<div style="font-size: 1.6rem; font-family: var(--font-serif); font-weight: 700; margin-top: 0.25rem;"><%= stats.totalPosts %></div>
|
||||
</div>
|
||||
|
||||
<div class="admin-kpi-card <%= stats.pendingComments > 0 ? 'has-pending' : '' %>">
|
||||
<div class="<%= stats.pendingComments > 0 ? 'kpi-title-pending' : 'kpi-title-default' %>" style="font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600;">Pending Moderation</div>
|
||||
<div class="<%= stats.pendingComments > 0 ? 'kpi-value-pending' : '' %>" style="font-size: 1.6rem; font-family: var(--font-serif); font-weight: 700; margin-top: 0.25rem;"><%= stats.pendingComments %></div>
|
||||
</div>
|
||||
|
||||
<div class="admin-kpi-card">
|
||||
<div style="font-size: 0.8rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600;">Approved Comments</div>
|
||||
<div class="kpi-value-approved" style="font-size: 1.6rem; font-family: var(--font-serif); font-weight: 700; margin-top: 0.25rem;"><%= stats.approvedComments %></div>
|
||||
</div>
|
||||
|
||||
<div class="admin-kpi-card">
|
||||
<div style="font-size: 0.8rem; color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600;">Search Queries Logged</div>
|
||||
<div style="font-size: 1.6rem; font-family: var(--font-serif); font-weight: 700; margin-top: 0.25rem;"><%= stats.totalSearches %></div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
Reference in New Issue
Block a user