7-sub sprint UI residual: footer login + kalendar CRUD + notif center + CRM extra tabs
A: shared/sidebar.js footer onclick → handleFootClick (Guest→/sport/login, logged-in→logout()), a11y role+keyboard, popup link fix
B: app.html SECTIONS['kalendar'] kalOpenModal/Save/Edit/Delete + Akcije kolona, mock savez:kalendar maknut
C: app.html renderNotifCenter() (sve 4 role) + sidebar bell unread badge (30s poll)
F: crm_v2.html +443 linija — Članarine, Liječnički, Obrasci tabovi (split view + dynamic schema modal)
G: index.html minor + sidebar dokumenti link refresh
Note: backend (kalendar_router, notif_router, crm_router, erp_full_router uploads, dokumenti unified) već u commit f7b5114.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -274,6 +274,37 @@
|
||||
el.classList.toggle('active', el.dataset.id===h);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── notif bell badge polling (30s) ───
|
||||
try {
|
||||
const refreshBadge = async () => {
|
||||
try {
|
||||
const tok = readToken();
|
||||
const r = await fetch('/sport/api/v2/notif/count', {
|
||||
headers: tok ? {'Authorization':'Bearer '+tok} : {}
|
||||
});
|
||||
if(!r.ok) return;
|
||||
const d = await r.json();
|
||||
const n = (d && d.unread) || 0;
|
||||
const el = document.querySelector('#pgz-sb .pgz-nav-i[data-id="notif"]');
|
||||
if(!el) return;
|
||||
let b = el.querySelector('.badge.notif-badge');
|
||||
if(n > 0){
|
||||
if(!b){
|
||||
b = document.createElement('span');
|
||||
b.className = 'badge notif-badge';
|
||||
b.style.cssText = 'background:#dc2626;color:#fff;border-radius:10px;padding:1px 6px;font-size:10px;font-weight:700;margin-left:auto';
|
||||
el.appendChild(b);
|
||||
}
|
||||
b.textContent = String(n);
|
||||
} else if(b){
|
||||
b.remove();
|
||||
}
|
||||
} catch(e){}
|
||||
};
|
||||
refreshBadge();
|
||||
setInterval(refreshBadge, 30000);
|
||||
} catch(e){}
|
||||
},
|
||||
|
||||
toggle(){
|
||||
|
||||
Reference in New Issue
Block a user