| [9d9f3c1] | 1 | /**
|
|---|
| [834bcc3] | 2 | * Admin: Edit press kit (EPK) — per-site bio + press contact.
|
|---|
| [9d9f3c1] | 3 | *
|
|---|
| [834bcc3] | 4 | * GET /admin/epk -> form with current bio + contact
|
|---|
| 5 | * POST /admin/epk -> save (app_settings: epk_bio_<siteId> / epk_contact_<siteId>)
|
|---|
| [9d9f3c1] | 6 | *
|
|---|
| [834bcc3] | 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).
|
|---|
| [9d9f3c1] | 9 | */
|
|---|
| 10 |
|
|---|
| 11 | import express from 'express';
|
|---|
| [e6ad948] | 12 | import db from '../config/database.js';
|
|---|
| [9d9f3c1] | 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';
|
|---|
| [69b509d] | 17 | import { t, resolveLang } from '../services/i18n.js';
|
|---|
| [9d9f3c1] | 18 |
|
|---|
| 19 | const router = express.Router();
|
|---|
| 20 |
|
|---|
| [e6ad948] | 21 | const MAX_EPK_TRACKS = 5;
|
|---|
| 22 |
|
|---|
| [9d9f3c1] | 23 | router.get('/', requireGod, (req, res) => {
|
|---|
| 24 | const site = res.locals.site;
|
|---|
| [69b509d] | 25 | if (!site) return res.status(404).send('Site required');
|
|---|
| [9d9f3c1] | 26 | if (!premiumUnlocked()) {
|
|---|
| [69b509d] | 27 | return res.status(403).send('Press kit is a premium feature.');
|
|---|
| [9d9f3c1] | 28 | }
|
|---|
| [e6ad948] | 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) {}
|
|---|
| [9d9f3c1] | 34 | renderPage(req, res, 'pages/admin-epk', {
|
|---|
| [3487567] | 35 | pageTitleKey: 'admin.t_epk',
|
|---|
| [9d9f3c1] | 36 | bodyClass: 'on-admin',
|
|---|
| 37 | site,
|
|---|
| 38 | epkBio: getSetting('epk_bio_' + site.id, '') || '',
|
|---|
| 39 | epkContact: getSetting('epk_contact_' + site.id, '') || '',
|
|---|
| [e6ad948] | 40 | allTracks,
|
|---|
| 41 | chosenTracks: chosen,
|
|---|
| 42 | maxEpkTracks: MAX_EPK_TRACKS,
|
|---|
| [9d9f3c1] | 43 | success: req.query.success || null,
|
|---|
| 44 | });
|
|---|
| 45 | });
|
|---|
| 46 |
|
|---|
| 47 | router.post('/', requireGod, (req, res) => {
|
|---|
| 48 | const site = res.locals.site;
|
|---|
| [69b509d] | 49 | if (!site) return res.status(404).send('Site required');
|
|---|
| [9d9f3c1] | 50 | setSetting('epk_bio_' + site.id, (req.body.epk_bio || '').toString().slice(0, 1000).trim());
|
|---|
| 51 | setSetting('epk_contact_' + site.id, (req.body.epk_contact || '').toString().slice(0, 300).trim());
|
|---|
| [834bcc3] | 52 | // Chosen tracks: only ids belonging to THIS site, max 5, in the supplied order.
|
|---|
| [e6ad948] | 53 | let ids = req.body.epk_tracks;
|
|---|
| 54 | if (!Array.isArray(ids)) ids = ids ? [ids] : [];
|
|---|
| 55 | const valid = new Set(db.prepare('SELECT id FROM audio_tracks WHERE site_id = ?').all(site.id).map((r) => r.id));
|
|---|
| 56 | ids = ids.map(String).filter((id) => valid.has(id)).slice(0, MAX_EPK_TRACKS);
|
|---|
| 57 | setSetting('epk_tracks_' + site.id, JSON.stringify(ids));
|
|---|
| [69b509d] | 58 | const lang = resolveLang(req, { defaultLang: getSetting('default_lang') });
|
|---|
| 59 | res.redirect('/admin/epk?success=' + encodeURIComponent(t(lang, 'aepk.saved')));
|
|---|
| [9d9f3c1] | 60 | });
|
|---|
| 61 |
|
|---|
| 62 | export default router;
|
|---|