This commit is contained in:
cay 2026-03-28 09:37:52 +00:00
parent fed7951a98
commit 9dc8f554b9
2 changed files with 67 additions and 0 deletions

View File

@ -346,4 +346,21 @@ router.post('/members/:id/reviewed', requireAdmin, async (req, res) => {
}
});
// GET /admin/api/badge-count für Live-Update
router.get('/api/badge-count', requireAdmin, async (req, res) => {
try {
const [rows] = await db.query(`
SELECT
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_count,
SUM(CASE WHEN reviewed = 0 AND status = 'active' THEN 1 ELSE 0 END) as new_count
FROM memberships
`);
const total = (rows[0].pending_count || 0) + (rows[0].new_count || 0);
res.json({ total, pending: rows[0].pending_count || 0, new: rows[0].new_count || 0 });
} catch (err) {
res.json({ total: 0, pending: 0, new: 0 });
}
});
module.exports = router;

View File

@ -391,6 +391,56 @@
window.location = '/admin/members/' + id;
}
// Live Badge Update alle 30 Sekunden
function updateBadge() {
fetch('/admin/api/badge-count')
.then(r => r.json())
.then(data => {
const badge = document.querySelector('.nav-badge');
if (data.total > 0) {
if (badge) {
badge.textContent = data.total;
} else {
// Badge neu erstellen
const link = document.querySelector('[onclick*="mitglieder"]');
if (link) {
const span = document.createElement('span');
span.className = 'nav-badge';
span.textContent = data.total;
link.appendChild(span);
}
}
// Stat-Karten aktualisieren
if (data.new > 0) {
let newCard = document.getElementById('stat-new');
if (!newCard) {
const statsRow = document.querySelector('.stats-row');
newCard = document.createElement('div');
newCard.id = 'stat-new';
newCard.className = 'stat-card stat-card-new';
newCard.style.cursor = 'pointer';
newCard.onclick = () => showSection('mitglieder', document.querySelector('[onclick*="mitglieder"]'));
newCard.innerHTML = '<div class="stat-number" style="color:#0891b2">' + data.new + '</div><div class="stat-label">🆕 Neu</div>';
statsRow.appendChild(newCard);
} else {
newCard.querySelector('.stat-number').textContent = data.new;
}
} else {
const newCard = document.getElementById('stat-new');
if (newCard) newCard.remove();
}
} else {
if (badge) badge.remove();
const newCard = document.getElementById('stat-new');
if (newCard) newCard.remove();
}
}).catch(() => {});
}
// Sofort + alle 30 Sekunden
updateBadge();
setInterval(updateBadge, 30000);
function filterMembers() {
const q = document.getElementById('memberSearch').value.toLowerCase();
document.querySelectorAll('.member-row').forEach(row => {