Files
haopengzhan 8c0b04db0e 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
2026-09-16 23:08:53 -07:00

70 lines
4.1 KiB
Plaintext

<%- include('../partials/head', { pageType: 'admin' }) %>
<div class="container" style="padding-top: 1.5rem; max-width: 1080px;">
<%- include('../partials/admin-header', { activeAdminTab: 'search', stats }) %>
<!-- Search Logs & Analytics -->
<section style="margin-bottom: 3rem;">
<div style="display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 1.25rem;">
<h2 style="font-size: 1.4rem; font-family: var(--font-serif); font-weight: 400; margin: 0;">Recent Search Queries (<%= searchLogs.length %>)</h2>
<span style="font-size: 0.85rem; color: var(--color-text-muted);">Recorded live in SQLite <code>search_logs</code></span>
</div>
<% if (searchLogs.length === 0) { %>
<p style="color: var(--color-text-muted); padding: 2rem; background: var(--color-surface); border-radius: var(--radius-sm); border: 1px dashed var(--color-border); text-align: center;">
No search queries recorded yet. Try searching on the <a href="/search" target="_blank" style="text-decoration: underline;">Search page</a>!
</p>
<% } else { %>
<div style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-sm); overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.02);">
<table style="width: 100%; border-collapse: collapse; font-size: 0.92rem; text-align: left;">
<thead>
<tr style="background: var(--color-surface-soft); border-bottom: 1px solid var(--color-border);">
<th style="padding: 0.85rem 1.25rem; font-weight: 600;">Query</th>
<th style="padding: 0.85rem 1rem; font-weight: 600;">Results Found</th>
<th style="padding: 0.85rem 1.25rem; font-weight: 600;">Searched At</th>
<th style="padding: 0.85rem 1rem; font-weight: 600; text-align: right;">Action</th>
</tr>
</thead>
<tbody>
<% searchLogs.forEach(log => { %>
<tr style="border-bottom: 1px solid var(--color-border);">
<td style="padding: 0.85rem 1.25rem;">
<code style="background: var(--color-surface-soft); padding: 3px 8px; border-radius: 4px; font-family: var(--font-mono); font-size: 0.88rem; color: var(--color-text-main);"><%= log.query %></code>
</td>
<td style="padding: 0.85rem 1rem;">
<span class="pill <%= log.result_count > 0 ? 'pill-success' : 'pill-danger' %>" style="font-size: 0.8rem;">
<%= log.result_count %> <%= log.result_count === 1 ? 'result' : 'results' %>
</span>
</td>
<td style="padding: 0.85rem 1.25rem; color: var(--color-text-muted); font-size: 0.85rem;">
<%= new Date(log.searched_at).toLocaleString() %>
</td>
<td style="padding: 0.85rem 1rem; text-align: right;">
<a href="/search?q=<%= encodeURIComponent(log.query) %>" target="_blank" class="btn btn-secondary" style="padding: 0.25rem 0.65rem; font-size: 0.78rem;">
Run &nearr;
</a>
</td>
</tr>
<% }) %>
</tbody>
</table>
</div>
<% } %>
</section>
<!-- Trending Search Recommendations -->
<section style="margin-bottom: 3rem;">
<h2 style="font-size: 1.4rem; font-family: var(--font-serif); font-weight: 400; margin-bottom: 1rem;">Active Search Recommendations</h2>
<div style="display: flex; gap: 0.75rem; flex-wrap: wrap;">
<% (recommendations || []).forEach(rec => { %>
<div style="background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: 0.6rem 1rem; display: flex; align-items: center; gap: 0.6rem;">
<code style="font-family: var(--font-mono); font-size: 0.85rem;"><%= rec.query %></code>
<span style="font-size: 0.78rem; color: var(--color-text-muted);">(<%= rec.clicks %> clicks)</span>
</div>
<% }) %>
</div>
</section>
</div>
<%- include('../partials/foot', { pageType: 'admin' }) %>