| 1 | /**
|
|---|
| 2 | * Admin: Edit press kit (EPK) — per-site bio + press contact.
|
|---|
| 3 | *
|
|---|
| 4 | * GET /admin/epk -> form with current bio + contact
|
|---|
| 5 | * POST /admin/epk -> save (app_settings: epk_bio_<siteId> / epk_contact_<siteId>)
|
|---|
| 6 | *
|
|---|
| 7 | * The press kit page itself (/pers) reads these values; tracks + recent posts come
|
|---|
| 8 | * automatically. Press kit is premium + solo (see routes/epk.js).
|
|---|
| 9 | */
|
|---|
| 10 |
|
|---|
| 11 | import express from 'express';
|
|---|
| 12 | import db from '../config/database.js';
|
|---|
| 13 | import { renderPage } from '../middleware/render.js';
|
|---|
| 14 | import { requireGod } from '../middleware/auth.js';
|
|---|
| 15 | import { getSetting, setSetting } from '../services/SettingsService.js';
|
|---|
| 16 | import { premiumUnlocked } from '../services/PatreonService.js';
|
|---|
| 17 | import { t, resolveLang } from '../services/i18n.js';
|
|---|
| 18 |
|
|---|
| 19 | const router = express.Router();
|
|---|
| 20 |
|
|---|
| 21 | const MAX_EPK_TRACKS = 5;
|
|---|
| 22 |
|
|---|
| 23 | router.get('/', requireGod, (req, res) => {
|
|---|
| 24 | const site = res.locals.site;
|
|---|
| 25 | if (!site) return res.status(404).send('Site required');
|
|---|
| 26 | if (!premiumUnlocked()) {
|
|---|
| 27 | return res.status(403).send('Press kit is a premium feature.');
|
|---|
| 28 | }
|
|---|
| 29 | const allTracks = db.prepare(
|
|---|
| 30 | `SELECT id, title, artist FROM audio_tracks WHERE site_id = ? ORDER BY position ASC, created_at ASC`
|
|---|
| 31 | ).all(site.id);
|
|---|
| 32 | let chosen = [];
|
|---|
| 33 | try { const r = JSON.parse(getSetting('epk_tracks_' + site.id, '') || '[]'); if (Array.isArray(r)) chosen = r; } catch (e) {}
|
|---|
| 34 | renderPage(req, res, 'pages/admin-epk', {
|
|---|
| 35 | pageJs: 'admin-epk',
|
|---|
| 36 | pageTitleKey: 'admin.t_epk',
|
|---|
| 37 | bodyClass: 'on-admin',
|
|---|
| 38 | site,
|
|---|
| 39 | epkBio: getSetting('epk_bio_' + site.id, '') || '',
|
|---|
| 40 | epkContact: getSetting('epk_contact_' + site.id, '') || '',
|
|---|
| 41 | allTracks,
|
|---|
| 42 | chosenTracks: chosen,
|
|---|
| 43 | maxEpkTracks: MAX_EPK_TRACKS,
|
|---|
| 44 | success: req.query.success || null,
|
|---|
| 45 | });
|
|---|
| 46 | });
|
|---|
| 47 |
|
|---|
| 48 | router.post('/', requireGod, (req, res) => {
|
|---|
| 49 | const site = res.locals.site;
|
|---|
| 50 | if (!site) return res.status(404).send('Site required');
|
|---|
| 51 | setSetting('epk_bio_' + site.id, (req.body.epk_bio || '').toString().slice(0, 1000).trim());
|
|---|
| 52 | setSetting('epk_contact_' + site.id, (req.body.epk_contact || '').toString().slice(0, 300).trim());
|
|---|
| 53 | // Chosen tracks: only ids belonging to THIS site, max 5, in the supplied order.
|
|---|
| 54 | let ids = req.body.epk_tracks;
|
|---|
| 55 | if (!Array.isArray(ids)) ids = ids ? [ids] : [];
|
|---|
| 56 | const valid = new Set(db.prepare('SELECT id FROM audio_tracks WHERE site_id = ?').all(site.id).map((r) => r.id));
|
|---|
| 57 | ids = ids.map(String).filter((id) => valid.has(id)).slice(0, MAX_EPK_TRACKS);
|
|---|
| 58 | setSetting('epk_tracks_' + site.id, JSON.stringify(ids));
|
|---|
| 59 | const lang = resolveLang(req, { defaultLang: getSetting('default_lang') });
|
|---|
| 60 | res.redirect('/admin/epk?success=' + encodeURIComponent(t(lang, 'aepk.saved')));
|
|---|
| 61 | });
|
|---|
| 62 |
|
|---|
| 63 | export default router;
|
|---|