| 1 | <div class="container admin-comments-page">
|
|---|
| 2 | <p><a href="/admin" class="btn">← 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 | — 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 | — 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="/<%= c.post_slug %>"><%= c.post_title || c.post_slug %></a>
|
|---|
| 29 | <span class="muted">· <%= 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="/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="/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 | <table class="admin-table">
|
|---|
| 50 | <thead>
|
|---|
| 51 | <tr><th>Author</th><th>Post</th><th>Status</th><th>Date</th></tr>
|
|---|
| 52 | </thead>
|
|---|
| 53 | <tbody>
|
|---|
| 54 | <% recent.forEach(function(c) { %>
|
|---|
| 55 | <tr class="status-<%= c.status %>">
|
|---|
| 56 | <td><%= c.author_username %></td>
|
|---|
| 57 | <td><a href="/<%= c.post_slug %>"><%= c.post_title || c.post_slug %></a></td>
|
|---|
| 58 | <td>
|
|---|
| 59 | <span class="status-pill status-pill--<%= c.status %>"><%= c.status %></span>
|
|---|
| 60 | </td>
|
|---|
| 61 | <td><%= formatDateTime(c.created_at) %></td>
|
|---|
| 62 | </tr>
|
|---|
| 63 | <% }); %>
|
|---|
| 64 | </tbody>
|
|---|
| 65 | </table>
|
|---|
| 66 | <% } %>
|
|---|
| 67 | </div>
|
|---|
| 68 |
|
|---|
| 69 | <style>
|
|---|
| 70 | .admin-comments-page { max-width: 900px; margin: 3rem auto; padding: 0 1rem; }
|
|---|
| 71 | .admin-comments-page h1 { font-family: var(--font-display, serif); font-size: 2rem; margin: 0 0 1rem; }
|
|---|
| 72 | .admin-comments-page h2 { font-family: var(--font-display, serif); font-size: 1.25rem; margin: 1.5rem 0 0.75rem; }
|
|---|
| 73 | .muted { color: var(--ink-muted, var(--ink-soft)); }
|
|---|
| 74 | .muted a { color: var(--accent); }
|
|---|
| 75 |
|
|---|
| 76 | .moderation-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 1rem; }
|
|---|
| 77 | .moderation-item {
|
|---|
| 78 | background: var(--paper-2);
|
|---|
| 79 | border: 1px solid var(--rule);
|
|---|
| 80 | border-radius: 8px;
|
|---|
| 81 | padding: 1rem;
|
|---|
| 82 | }
|
|---|
| 83 | .moderation-meta { font-size: 0.85rem; margin-bottom: 0.5rem; color: var(--ink-soft); }
|
|---|
| 84 | .moderation-meta a { color: var(--accent); }
|
|---|
| 85 | .moderation-content {
|
|---|
| 86 | margin: 0 0 0.75rem;
|
|---|
| 87 | padding: 0.5rem 0.75rem;
|
|---|
| 88 | border-left: 3px solid var(--accent);
|
|---|
| 89 | background: var(--paper);
|
|---|
| 90 | white-space: pre-wrap;
|
|---|
| 91 | word-wrap: break-word;
|
|---|
| 92 | color: var(--ink);
|
|---|
| 93 | }
|
|---|
| 94 | .moderation-actions { display: flex; gap: 0.5rem; }
|
|---|
| 95 |
|
|---|
| 96 | .status-pill {
|
|---|
| 97 | display: inline-block; padding: 0.1rem 0.5rem; border-radius: 10px;
|
|---|
| 98 | font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
|
|---|
| 99 | }
|
|---|
| 100 | .status-pill--approved { background: rgba(40, 160, 90, 0.15); color: #2a9d5e; }
|
|---|
| 101 | .status-pill--rejected { background: rgba(200, 60, 60, 0.15); color: #c33; }
|
|---|
| 102 | .status-pill--pending { background: var(--paper); color: var(--ink-muted, var(--ink-soft)); }
|
|---|
| 103 |
|
|---|
| 104 | .audio-flash { padding: 0.75rem 1rem; border-radius: 6px; margin: 1rem 0; font-size: 0.9rem; }
|
|---|
| 105 | .audio-flash--ok { background: rgba(40, 160, 90, 0.15); color: #2a9d5e; border: 1px solid rgba(40, 160, 90, 0.3); }
|
|---|
| 106 | .audio-flash--err { background: rgba(200, 60, 60, 0.15); color: #c33; border: 1px solid rgba(200, 60, 60, 0.3); }
|
|---|
| 107 | </style>
|
|---|