source: Klonkt/src/routes/admin-comments.js@ 7bc636b

main
Last change on this file since 7bc636b was 7bc636b, checked in by Robin <robin@…>, 4 months ago

Initial commit — PrutFolio v1 source (pulled from Hetzner /srv/prutfolio)

  • Property mode set to 100644
File size: 2.7 KB
Line 
1/**
2 * Admin: Comment moderation queue — Phase E.
3 *
4 * GET /admin/comments -> list pending + recent (god-only)
5 * POST /admin/comments/:id/approve -> set status = 'approved'
6 * POST /admin/comments/:id/reject -> set status = 'rejected' (keeps the row
7 * so we have a paper trail; admin can
8 * hard-delete via the post page).
9 *
10 * Scope: shows comments for the resolved site only (the one matched by
11 * /sites/:slug or default). Future: filter by status / search.
12 */
13
14import express from 'express';
15import db from '../config/database.js';
16import { renderPage } from '../middleware/render.js';
17import { requireGod } from '../middleware/auth.js';
18
19const router = express.Router();
20
21router.get('/', requireGod, (req, res) => {
22 const site = res.locals.site;
23 if (!site) return res.status(404).send('No site');
24
25 const pending = db.prepare(`
26 SELECT c.id, c.content, c.created_at, c.parent_comment_id,
27 u.username AS author_username,
28 p.slug AS post_slug, p.title AS post_title
29 FROM comments c
30 JOIN users u ON u.id = c.author_id
31 JOIN posts p ON p.id = c.post_id
32 WHERE p.site_id = ? AND c.status = 'pending'
33 ORDER BY c.created_at ASC
34 LIMIT 200
35 `).all(site.id);
36
37 const recent = db.prepare(`
38 SELECT c.id, c.content, c.created_at, c.status,
39 u.username AS author_username,
40 p.slug AS post_slug, p.title AS post_title
41 FROM comments c
42 JOIN users u ON u.id = c.author_id
43 JOIN posts p ON p.id = c.post_id
44 WHERE p.site_id = ? AND c.status IN ('approved', 'rejected')
45 ORDER BY c.created_at DESC
46 LIMIT 30
47 `).all(site.id);
48
49 renderPage(req, res, 'pages/admin-comments', {
50 pageTitle: 'Comment moderation',
51 bodyClass: 'on-admin',
52 pending,
53 recent,
54 moderationMode: site.comments_moderation_mode || 'trust',
55 success: req.query.success || null,
56 error: req.query.error || null,
57 });
58});
59
60function setStatus(req, res, status) {
61 const site = res.locals.site;
62 if (!site) return res.status(404).send('No site');
63
64 const row = db.prepare(`
65 SELECT c.id FROM comments c JOIN posts p ON p.id = c.post_id
66 WHERE c.id = ? AND p.site_id = ?
67 `).get(req.params.id, site.id);
68
69 if (!row) return res.redirect('/admin/comments?error=Not+found');
70
71 db.prepare(
72 'UPDATE comments SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?'
73 ).run(status, req.params.id);
74 res.redirect('/admin/comments?success=' + encodeURIComponent('Comment ' + status));
75}
76
77router.post('/:id/approve', requireGod, (req, res) => setStatus(req, res, 'approved'));
78router.post('/:id/reject', requireGod, (req, res) => setStatus(req, res, 'rejected'));
79
80export default router;
Note: See TracBrowser for help on using the repository browser.