Changeset 2e247e4 in Klonkt
- Timestamp:
- 06/19/2026 12:00:48 AM (3 months ago)
- Branches:
- main
- Children:
- 91094a4
- Parents:
- 255e3d3
- Location:
- src
- Files:
-
- 5 added
- 3 edited
-
config/database.js (modified) (1 diff)
-
routes/admin-newsletter.js (added)
-
routes/newsletter.js (added)
-
server.js (modified) (3 diffs)
-
services/SubscriberService.js (added)
-
views/pages/admin-newsletter.ejs (added)
-
views/pages/admin.ejs (modified) (1 diff)
-
views/pages/newsletter.ejs (added)
Legend:
- Unmodified
- Added
- Removed
-
src/config/database.js
r255e3d3 r2e247e4 188 188 // Tags van de originele post — getoond in de cirkel (comma-separated string). 189 189 ensureColumn('remote_posts', 'tags', 'TEXT'); 190 191 // Nieuwsbrief / mailinglijst (premium). Abonnees per site; double opt-in als SMTP 192 // er is (status 'pending' tot bevestigd), anders single opt-in ('confirmed'). 193 // 'unsub' = uitgeschreven. token = confirm/unsubscribe-sleutel (in de e-maillinks). 194 db.exec(` 195 CREATE TABLE IF NOT EXISTS subscribers ( 196 id TEXT PRIMARY KEY, 197 site_id TEXT NOT NULL, 198 email TEXT NOT NULL, 199 status TEXT NOT NULL DEFAULT 'pending', 200 source TEXT DEFAULT 'widget', 201 token TEXT NOT NULL, 202 created_at DATETIME DEFAULT CURRENT_TIMESTAMP, 203 confirmed_at DATETIME, 204 UNIQUE(site_id, email) 205 ); 206 CREATE INDEX IF NOT EXISTS idx_subscribers_site_status ON subscribers(site_id, status); 207 `); 208 209 // Verstuurde nieuwsbrieven (historie + aantallen). 210 db.exec(` 211 CREATE TABLE IF NOT EXISTS newsletters ( 212 id TEXT PRIMARY KEY, 213 site_id TEXT NOT NULL, 214 subject TEXT NOT NULL, 215 body TEXT NOT NULL, 216 sent_at DATETIME DEFAULT CURRENT_TIMESTAMP, 217 recipient_count INTEGER DEFAULT 0 218 ); 219 `); 190 220 } 191 221 -
src/server.js
r255e3d3 r2e247e4 53 53 import circleRoutes from './routes/circle.js'; 54 54 import epkRoutes from './routes/epk.js'; 55 import newsletterRoutes from './routes/newsletter.js'; 56 import adminNewsletterRoutes from './routes/admin-newsletter.js'; 55 57 56 58 if (!process.env.SESSION_SECRET) { … … 252 254 app.use('/admin/patreon', adminPatreonRoutes); 253 255 app.use('/admin/stats', adminStatsRoutes); 256 app.use('/admin/newsletter', adminNewsletterRoutes); 254 257 app.use('/admin', adminRoutes); 255 258 app.use('/prutter', prutterRoutes); … … 267 270 app.use('/', circleRoutes); // /cirkel-feed (solo/hub: next() -> postsRoutes) 268 271 app.use('/', epkRoutes); // /pers perskit (premium; niet-premium: next() -> 404) 272 app.use('/', newsletterRoutes); // /nieuwsbrief in/uitschrijven (premium; niet-premium: next()) 269 273 app.use('/', postsRoutes); 270 274 -
src/views/pages/admin.ejs
r255e3d3 r2e247e4 33 33 <% if (typeof premiumUnlocked === 'undefined' || premiumUnlocked) { %> 34 34 <a href="/admin/stats" class="btn">📊 Statistieken</a> 35 <a href="/admin/newsletter" class="btn">✉️ Nieuwsbrief</a> 36 <% if (tenancy !== 'hub' && primarySite) { %><a href="/pers" class="btn" target="_blank">📰 Perskit</a><% } %> 35 37 <% } %> 36 38 <a href="/admin/updates" class="btn">🔄 Updates</a>
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)