source: Klonkt/src/routes/admin-stats.js@ 37edecd

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

Link-in-bio + click stats (premium feature #6)

Linktree-style page from the existing sites.profile_links (JSON [{platform,url}])
+ PLATFORMS icons. Clicks counted per url.

  • DB: link_clicks (site_id, url, clicks), PK (site_id,url).
  • routes/linkbio.js (premium-gated): GET /links (page with profile_links as buttons), GET /links/go/:i (counts click per url + 302 redirect). Open-redirect safe: only redirects to a url in the site's own profile_links; http(s)/mailto only.
  • view pages/linkbio.ejs (photo/name/bio + brand-coloured buttons with SVG icons).
  • admin-stats: link-clicks section (top 50, per url) for the current site.
  • admin dashboard: 🔗 Link-in-bio link (premium, non-hub).

node --check passed.

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

  • Property mode set to 100644
File size: 1.4 KB
Line 
1/**
2 * Admin: Statistieken (premium-module, god-only).
3 *
4 * GET /admin/stats -> cookievrije statistieken: bezoekers/weergaven per dag,
5 * plays, en de populairste posts/tracks.
6 *
7 * Premium-gated via premiumUnlocked() (premium-laag uit = gewoon beschikbaar;
8 * aan = Patreon vereist). Tracking zit in StatsService (geen cookies).
9 */
10
11import express from 'express';
12import db from '../config/database.js';
13import { renderPage } from '../middleware/render.js';
14import { requireGod } from '../middleware/auth.js';
15import { premiumUnlocked } from '../services/PatreonService.js';
16import { getStats } from '../services/StatsService.js';
17
18const router = express.Router();
19
20router.get('/', requireGod, (req, res) => {
21 if (!premiumUnlocked()) {
22 return res.status(403).send('Statistieken is een premium-functie — koppel Patreon in Beheer → Instellingen.');
23 }
24 // Link-in-bio klikken (premium #6) voor de huidige site.
25 let linkClicks = [];
26 if (res.locals.site) {
27 try {
28 linkClicks = db.prepare(
29 'SELECT url, clicks FROM link_clicks WHERE site_id = ? AND clicks > 0 ORDER BY clicks DESC LIMIT 50'
30 ).all(res.locals.site.id);
31 } catch { linkClicks = []; }
32 }
33 renderPage(req, res, 'pages/admin-stats', {
34 pageTitle: 'Statistieken',
35 bodyClass: 'on-admin',
36 stats: getStats(14),
37 linkClicks,
38 });
39});
40
41export default router;
Note: See TracBrowser for help on using the repository browser.