source: Klonkt/src/views/pages/admin-comments.ejs@ 3ec691c

main
Last change on this file since 3ec691c was a474bd2, checked in by roboburr <roboburr@…>, 3 months ago

ui: comment moderation "Recent decisions" as cards instead of a flat table

Card list with status pill, author + post + date, coloured left border per
status (green=approved/red=rejected), responsive (wraps on narrow screen).

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 5.4 KB
Line 
1<div class="container admin-comments-page">
2 <p><a href="/admin" class="btn">&larr; Beheer</a></p>
3 <h1>Comment moderation</h1>
4
5 <p class="muted">
6 Mode for this site: <strong><%= moderationMode %></strong>
7 <% if (moderationMode === 'trust') { %>
8 &mdash; comments are auto-approved. Switch to <em>moderate</em> in
9 <a href="/admin/sites/<%= site.slug %>/edit">site settings</a> to queue them.
10 <% } else { %>
11 &mdash; new comments require approval before showing up on posts.
12 <% } %>
13 </p>
14
15 <% if (success) { %><div class="audio-flash audio-flash--ok"><%= success %></div><% } %>
16 <% if (error) { %><div class="audio-flash audio-flash--err"><%= error %></div><% } %>
17
18 <h2>Pending (<%= pending.length %>)</h2>
19 <% if (!pending.length) { %>
20 <p class="muted">Nothing waiting.</p>
21 <% } else { %>
22 <ol class="moderation-list">
23 <% pending.forEach(function(c) { %>
24 <li class="moderation-item">
25 <div class="moderation-meta">
26 <strong><%= c.author_username %></strong>
27 <% if (c.parent_comment_id) { %><span class="muted">(reply)</span><% } %>
28 on <a href="<%= siteUrlBase %>/<%= c.post_slug %>"><%= c.post_title || c.post_slug %></a>
29 <span class="muted">&middot; <%= formatDateTime(c.created_at) %></span>
30 </div>
31 <blockquote class="moderation-content"><%= c.content %></blockquote>
32 <div class="moderation-actions">
33 <form method="post" action="<%= siteUrlBase %>/admin/comments/<%= c.id %>/approve" style="display:inline">
34 <button type="submit" class="btn btn-primary">Approve</button>
35 </form>
36 <form method="post" action="<%= siteUrlBase %>/admin/comments/<%= c.id %>/reject" style="display:inline">
37 <button type="submit" class="btn btn-danger">Reject</button>
38 </form>
39 </div>
40 </li>
41 <% }); %>
42 </ol>
43 <% } %>
44
45 <h2>Recent decisions</h2>
46 <% if (!recent.length) { %>
47 <p class="muted">Nothing yet.</p>
48 <% } else { %>
49 <ul class="decision-list">
50 <% recent.forEach(function(c) { %>
51 <li class="decision-card decision-card--<%= c.status %>">
52 <span class="status-pill status-pill--<%= c.status %>"><%= c.status %></span>
53 <div class="decision-main">
54 <span class="decision-author"><%= c.author_username %></span>
55 <a class="decision-post" href="<%= siteUrlBase %>/<%= c.post_slug %>"><%= c.post_title || c.post_slug %></a>
56 </div>
57 <span class="decision-date"><%= formatDateTime(c.created_at) %></span>
58 </li>
59 <% }); %>
60 </ul>
61 <% } %>
62</div>
63
64<style>
65.admin-comments-page { max-width: 900px; margin: 3rem auto; padding: 0 1rem; }
66.admin-comments-page h1 { font-family: var(--font-display, serif); font-size: 2rem; margin: 0 0 1rem; }
67.admin-comments-page h2 { font-family: var(--font-display, serif); font-size: 1.25rem; margin: 1.5rem 0 0.75rem; }
68.muted { color: var(--ink-muted, var(--ink-soft)); }
69.muted a { color: var(--accent); }
70
71.moderation-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 1rem; }
72.moderation-item {
73 background: var(--paper-2);
74 border: 1px solid var(--rule);
75 border-radius: 8px;
76 padding: 1rem;
77}
78.moderation-meta { font-size: 0.85rem; margin-bottom: 0.5rem; color: var(--ink-soft); }
79.moderation-meta a { color: var(--accent); }
80.moderation-content {
81 margin: 0 0 0.75rem;
82 padding: 0.5rem 0.75rem;
83 border-left: 3px solid var(--accent);
84 background: var(--paper);
85 white-space: pre-wrap;
86 word-wrap: break-word;
87 color: var(--ink);
88}
89.moderation-actions { display: flex; gap: 0.5rem; }
90
91.status-pill {
92 display: inline-block; padding: 0.1rem 0.5rem; border-radius: 10px;
93 font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
94}
95.status-pill--approved { background: rgba(40, 160, 90, 0.15); color: #2a9d5e; }
96.status-pill--rejected { background: rgba(200, 60, 60, 0.15); color: #c33; }
97.status-pill--pending { background: var(--paper); color: var(--ink-muted, var(--ink-soft)); }
98
99/* Recent decisions als cards (i.p.v. een platte tabel) */
100.decision-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
101.decision-card {
102 display: flex; align-items: center; gap: 0.85rem;
103 padding: 0.7rem 0.9rem;
104 background: var(--paper-2); border: 1px solid var(--rule);
105 border-left: 3px solid var(--rule); border-radius: 10px;
106}
107.decision-card--approved { border-left-color: #2a9d5e; }
108.decision-card--rejected { border-left-color: #c33; }
109.decision-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
110.decision-author { font-weight: 600; }
111.decision-post { color: var(--accent); text-decoration: none; font-size: 0.88rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
112.decision-post:hover { text-decoration: underline; }
113.decision-date { flex: 0 0 auto; color: var(--ink-muted, var(--ink-soft)); font-size: 0.8rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
114@media (max-width: 520px) {
115 .decision-card { flex-wrap: wrap; }
116 .decision-date { width: 100%; }
117}
118
119.audio-flash { padding: 0.75rem 1rem; border-radius: 6px; margin: 1rem 0; font-size: 0.9rem; }
120.audio-flash--ok { background: rgba(40, 160, 90, 0.15); color: #2a9d5e; border: 1px solid rgba(40, 160, 90, 0.3); }
121.audio-flash--err { background: rgba(200, 60, 60, 0.15); color: #c33; border: 1px solid rgba(200, 60, 60, 0.3); }
122</style>
Note: See TracBrowser for help on using the repository browser.