Changeset 0c2228a in Klonkt
- Timestamp:
- 06/14/2026 05:10:16 PM (3 months ago)
- Branches:
- main
- Children:
- 7963a6e
- Parents:
- 05a6ca0
- Location:
- src
- Files:
-
- 3 edited
-
routes/admin-users.js (modified) (1 diff)
-
views/pages/admin-users.ejs (modified) (1 diff)
-
views/partials/topnav.ejs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/admin-users.js
r05a6ca0 r0c2228a 98 98 } 99 99 100 const owned = db.prepare(` 101 SELECT 102 (SELECT COUNT(*) FROM posts WHERE author_id = ?) AS posts, 103 (SELECT COUNT(*) FROM sites WHERE owner_id = ?) AS sites 104 `).get(userId, userId); 100 // Cascade-verwijderen: de sites van deze user (+ posts/playlists/audio/leden/ 101 // comments daaronder), z'n eigen content elders, en daarna de user zelf. 102 // Atomisch in een transactie — faalt er een FK, dan rolt alles terug. 103 const del = db.transaction(() => { 104 const sites = db.prepare('SELECT id FROM sites WHERE owner_id = ?').all(userId).map((s) => s.id); 105 for (const sid of sites) { 106 db.prepare('DELETE FROM comments WHERE post_id IN (SELECT id FROM posts WHERE site_id = ?)').run(sid); 107 db.prepare('DELETE FROM posts WHERE site_id = ?').run(sid); 108 db.prepare('DELETE FROM playlists WHERE site_id = ?').run(sid); 109 db.prepare('DELETE FROM audio_tracks WHERE site_id = ?').run(sid); 110 db.prepare('DELETE FROM site_members WHERE site_id = ?').run(sid); 111 db.prepare('DELETE FROM sites WHERE id = ?').run(sid); 112 } 113 // Eigen content op andere sites + losse koppelingen. 114 db.prepare('DELETE FROM comments WHERE post_id IN (SELECT id FROM posts WHERE author_id = ?)').run(userId); 115 db.prepare('DELETE FROM posts WHERE author_id = ?').run(userId); 116 db.prepare('DELETE FROM comments WHERE author_id = ?').run(userId); 117 db.prepare('DELETE FROM site_members WHERE user_id = ?').run(userId); 118 db.prepare('DELETE FROM users WHERE id = ?').run(userId); 119 }); 105 120 106 if (owned.posts > 0 || owned.sites > 0) { 107 return res.redirect('/admin/users?error=' + encodeURIComponent( 108 `Cannot delete: user owns ${owned.sites} site(s) and ${owned.posts} post(s). Reassign or delete those first.` 109 )); 121 try { 122 del(); 123 } catch (e) { 124 console.error('[admin/users delete]', e.message); 125 return res.redirect('/admin/users?error=' + encodeURIComponent('Verwijderen mislukt (mogelijk gekoppelde data).')); 110 126 } 111 127 112 // Clean up dangling references 113 db.prepare('DELETE FROM site_members WHERE user_id = ?').run(userId); 114 db.prepare('DELETE FROM comments WHERE author_id = ?').run(userId); 115 db.prepare('DELETE FROM users WHERE id = ?').run(userId); 116 117 res.redirect('/admin/users?success=' + encodeURIComponent('User deleted: ' + target.username)); 128 res.redirect('/admin/users?success=' + encodeURIComponent('Gebruiker verwijderd: ' + target.username)); 118 129 }); 119 130 -
src/views/pages/admin-users.ejs
r05a6ca0 r0c2228a 74 74 </form> 75 75 76 <% if (u.id !== user.id && (u.post_count + u.site_count === 0)) { %> 76 <% if (u.id !== user.id) { %> 77 <% var _warn = (u.post_count + u.site_count > 0) 78 ? ('Dit verwijdert ook hun site + ' + u.post_count + ' post(s). ') 79 : ''; %> 77 80 <form method="post" action="/admin/users/<%= u.id %>/delete" class="ax-delete-form" 78 onsubmit="return confirm(' Verwijder gebruiker <%= u.username %>?')">81 onsubmit="return confirm('Gebruiker <%= u.username %> verwijderen? <%= _warn %>Dit kan niet ongedaan worden.')"> 79 82 <button type="submit" class="ax-icon-btn ax-icon-btn-danger" aria-label="Verwijderen" title="Verwijderen">🗑</button> 80 83 </form> -
src/views/partials/topnav.ejs
r05a6ca0 r0c2228a 28 28 <% } else if (typeof tenancy !== 'undefined' && tenancy === 'hub') { %> 29 29 <%# Hub: de brand is de hub-naam en gaat naar de hub-home (volledige nav, geen 30 HTMX, zodat de headerloze overview correct rendert). %> 31 <a class="site-title" href="/" aria-label="Naar de hub-home"><%= (typeof hubTitle !== 'undefined' && hubTitle) ? hubTitle : 'Home' %></a> 30 HTMX, zodat de headerloze overview correct rendert). Eigen class want 31 .site-title is overal display:none. %> 32 <a class="nav-hub-home" href="/" aria-label="Naar de hub-home"><%= (typeof hubTitle !== 'undefined' && hubTitle) ? hubTitle : 'Home' %></a> 32 33 <% } else if (site) { %> 33 34 <a class="site-title" href="<%= _siteUrlBase %>/" … … 232 233 } 233 234 235 /* Hub-home brand is WÉL zichtbaar — de thuisknop op artiest-/hub-pagina's. */ 236 .masthead-brand .nav-hub-home { 237 display: inline-block; vertical-align: middle; 238 color: var(--ink); text-decoration: none; 239 font-family: var(--font-display, serif); font-weight: 700; font-size: 1.05rem; 240 transition: color 120ms; 241 } 242 .masthead-brand .nav-hub-home:hover { color: var(--accent); } 243 234 244 /* On mobile, hide the entire masthead except for admin pages. The brand 235 245 appears in the profile-header on content pages, and the bottom-tab
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)