- Implement ephemeral staging mode (APP_ENV=staging) to isolate test/dev DB writes in /tmp - Add read-only posts management dashboard under /guanli/posts with live links and comment counters - Add hot re-indexing endpoint (/guanli/reindex) to refresh Markdown without restarting server - Replace static recommended search config with dynamic frequency-based trending searches - Remove early scaffold mockup file (dropbox/zh.md) and clean legacy mock test queries - Add native Makefile with dev, dev-persistent, test, lint, and docker targets - Update test suite and documentation for development workflows
63 lines
3.9 KiB
Plaintext
63 lines
3.9 KiB
Plaintext
<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/posts" class="btn <%= activeAdminTab === 'posts' ? 'btn-primary' : 'btn-secondary' %>" style="padding: 0.45rem 0.95rem; font-size: 0.88rem;">
|
|
📝 Posts
|
|
</a>
|
|
|
|
<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>
|