diff --git a/backend/src/routes/admin.js b/backend/src/routes/admin.js index 33b05af..30bef64 100644 --- a/backend/src/routes/admin.js +++ b/backend/src/routes/admin.js @@ -41,12 +41,13 @@ router.get('/users', authenticate, requireAdmin, (req, res) => { const stats = users.map(u => { const archiv = db.prepare('SELECT COUNT(*) c FROM calculations WHERE user_id=?').get(u.id).c; const bestellung = db.prepare('SELECT COUNT(*) c FROM orders WHERE user_id=?').get(u.id).c; + const snippets_c = db.prepare('SELECT COUNT(*) c FROM snippets WHERE user_id=?').get(u.id).c; const todos = db.prepare('SELECT COUNT(*) c FROM todos WHERE user_id=?').get(u.id).c; const links = db.prepare('SELECT COUNT(*) c FROM quick_links WHERE user_id=?').get(u.id).c; const files = db.prepare('SELECT COUNT(*) c FROM files WHERE user_id=?').get(u.id).c; const noteLen = (db.prepare('SELECT content FROM notes WHERE user_id=?').get(u.id)?.content || '').length; const icals = db.prepare('SELECT COUNT(*) c FROM calendar_feeds WHERE user_id=?').get(u.id).c; - return { ...u, archiv, bestellung, todos, links, files, icals, noteLen }; + return { ...u, archiv, bestellung, snippets_c, todos, links, files, icals, noteLen }; }); res.json(stats); }); diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index a5c24ef..73d4c04 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1887,6 +1887,7 @@ function UserManagement({ toast }) { {[ ['◈ Archiv', u.archiv], ['📦 Bestellungen', u.bestellung], + ['> Codes', u.snippets_c], ['✓ Todos', u.todos], ['🔗 Links', u.links], ['📁 Dateien', u.files], diff --git a/frontend/src/tools/codeschnipsel.jsx b/frontend/src/tools/codeschnipsel.jsx index 99c7801..e5f831d 100644 --- a/frontend/src/tools/codeschnipsel.jsx +++ b/frontend/src/tools/codeschnipsel.jsx @@ -148,23 +148,25 @@ function HistoryModal({ snippet, onClose, onRestore, toast }) { useEffect(()=>{ load(); },[]); // Entries: [current, ...history] where index 0 = current - // entries[i].code, entries[i].label const entries = [ { id:'current', code: snippet.code, language: snippet.language, saved_at: snippet.updated_at, label:'Aktuell', isCurrent: true }, ...history.map((h,i) => ({ ...h, label:`v${history.length - i}`, isCurrent: false })), ]; + // Check if current code matches a history entry (= was restored) + const restoredFromIdx = history.findIndex(h => h.code === snippet.code); + const restoredFromLabel = restoredFromIdx >= 0 ? `v${history.length - restoredFromIdx}` : null; + const selected = entries[selectedIdx]; - // Diff: what changed FROM previous version TO selected (selected is newer) - const prevEntry = entries[selectedIdx + 1]; // one step older - const oldCode = prevEntry?.code ?? null; // null = älteste, kein Diff + const prevEntry = entries[selectedIdx + 1]; + const oldCode = prevEntry?.code ?? null; const delHistory = async (hid) => { + if (!window.confirm('Diese Version wirklich löschen?')) return; try { await api(`/tools/snippets/${snippet.id}/history/${hid}`, { method:'DELETE' }); await load(); - // If deleted entry was selected, jump to current setSelectedIdx(0); toast('Version gelöscht'); } catch(e) { toast(e.message,'error'); } @@ -221,6 +223,11 @@ function HistoryModal({ snippet, onClose, onRestore, toast }) { fontFamily:'monospace',fontSize:10,fontWeight: e.isCurrent?700:400}}> {e.label} {e.isCurrent&&●} + {e.isCurrent && restoredFromLabel && ( +