feat: /api/v2/analiza/* endpoints - sport analytics backend
This commit is contained in:
+15
-9
@@ -345,6 +345,7 @@ table tbody tr:hover{background:var(--bg3)}
|
||||
<link rel="stylesheet" href="/static/shared/sidebar.css">
|
||||
<script src="/static/shared/sidebar.js" defer data-active="profil"></script>
|
||||
<script src="/static/oib_format.js" defer></script>
|
||||
<script src="/static/shared/sortable.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -481,7 +482,7 @@ async function apiAuth(path, opts){
|
||||
const onLogin = location.pathname.includes('/login');
|
||||
if(!onLogin && !window.__pgz_redirecting){
|
||||
window.__pgz_redirecting = true;
|
||||
window.(window.__pgz_made_api_call ? location.href = '/login?reason=unauthorized' : console.warn('[auth] no token but no API call yet, skipping redirect'));
|
||||
if(window.__pgz_made_api_call){location.href='/login?reason=unauthorized';}else{console.warn('[auth] no token but no API call yet, skipping redirect');}
|
||||
}
|
||||
return {__unauthorized:true, status:401};
|
||||
}
|
||||
@@ -511,7 +512,7 @@ const NAV_BY_ROLE = {
|
||||
{id:'sportasi', ic:'\u{1F464}', label:'Sportaši'},
|
||||
{id:'financije', ic:'€', label:'Financije'},
|
||||
{id:'erp', ic:'\u{1F4BC}', label:'ERP', href:'/erp/full'},
|
||||
{id:'crm', ic:'\u{1F4DD}', label:'CRM', href:'/crm/v2'},
|
||||
{id:'crm', ic:'\u{1F4DD}', label:'CRM', href:'/crm'},
|
||||
{id:'dokumenti', ic:'\u{1F4D6}', label:'Dokumenti'},
|
||||
{id:'racuni', ic:'\u{1F9FE}', label:'Računi (OCR)', href:'/erp/full?tab=uploads'},
|
||||
{id:'putni', ic:'\u{2708}', label:'Putni nalozi', href:'/erp/full?tab=putni'},
|
||||
@@ -593,11 +594,13 @@ function applyMeToHeader(){
|
||||
$('#user-name').innerHTML = esc(name) + `<span class="role-badge" id="user-role-badge">${esc(me.user_type||'')}</span>`;
|
||||
$('#user-tenant').textContent = tenant;
|
||||
$('#user-role-label')?.replaceChildren(document.createTextNode(roleLabel));
|
||||
// Avatar topbar
|
||||
// Avatar topbar — onError replaces <img> with initials so a 404 / dead URL doesn't show a broken-image icon
|
||||
const _avInits = esc(initials(name));
|
||||
const _avFallback = `this.onerror=null;this.style.display='none';if(this.parentElement){this.parentElement.textContent='${_avInits}';}`;
|
||||
if(me.avatar_url){
|
||||
$('#user-av').innerHTML = `<img src="${esc(me.avatar_url)}${me.avatar_url.includes('?')?'&':'?'}t=${Date.now()}" alt="">`;
|
||||
$('#user-av').innerHTML = `<img src="${esc(me.avatar_url)}${me.avatar_url.includes('?')?'&':'?'}t=${Date.now()}" alt="" onerror="${_avFallback}">`;
|
||||
} else if(me.google_picture){
|
||||
$('#user-av').innerHTML = `<img src="${esc(me.google_picture)}" alt="">`;
|
||||
$('#user-av').innerHTML = `<img src="${esc(me.google_picture)}" alt="" onerror="${_avFallback}">`;
|
||||
} else {
|
||||
$('#user-av').textContent = initials(name);
|
||||
}
|
||||
@@ -605,8 +608,8 @@ function applyMeToHeader(){
|
||||
if($('#sf-name')) $('#sf-name').textContent = name;
|
||||
if($('#sf-role')) $('#sf-role').textContent = roleLabel;
|
||||
if($('#sf-av')){
|
||||
if(me.avatar_url) $('#sf-av').innerHTML = `<img src="${esc(me.avatar_url)}${me.avatar_url.includes('?')?'&':'?'}t=${Date.now()}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%">`;
|
||||
else if(me.google_picture) $('#sf-av').innerHTML = `<img src="${esc(me.google_picture)}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%">`;
|
||||
if(me.avatar_url) $('#sf-av').innerHTML = `<img src="${esc(me.avatar_url)}${me.avatar_url.includes('?')?'&':'?'}t=${Date.now()}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%" onerror="${_avFallback}">`;
|
||||
else if(me.google_picture) $('#sf-av').innerHTML = `<img src="${esc(me.google_picture)}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%" onerror="${_avFallback}">`;
|
||||
else $('#sf-av').textContent = initials(name);
|
||||
}
|
||||
if($('#role-sub')) $('#role-sub').textContent = tenant || roleLabel;
|
||||
@@ -895,8 +898,10 @@ function profileMe(){
|
||||
function profileRender(){
|
||||
const u = profileMe();
|
||||
const name = u.full_name || ((u.ime||'')+' '+(u.prezime||'')).trim() || u.email || '—';
|
||||
const av = u.avatar_url ? `<img src="${esc(u.avatar_url)}" alt="">`
|
||||
: (u.google_picture ? `<img src="${esc(u.google_picture)}" alt="">` : esc(initials(name)));
|
||||
const _avInits2 = esc(initials(name));
|
||||
const _avFallback2 = `this.onerror=null;this.style.display='none';if(this.parentElement){this.parentElement.textContent='${_avInits2}';}`;
|
||||
const av = u.avatar_url ? `<img src="${esc(u.avatar_url)}" alt="" onerror="${_avFallback2}">`
|
||||
: (u.google_picture ? `<img src="${esc(u.google_picture)}" alt="" onerror="${_avFallback2}">` : esc(initials(name)));
|
||||
const lastLogin = u.last_login ? new Date(u.last_login).toLocaleString('hr-HR') : '—';
|
||||
const created = u.created_at ? new Date(u.created_at).toLocaleString('hr-HR') : '—';
|
||||
const gdpr = u.gdpr_consent_at ? new Date(u.gdpr_consent_at).toLocaleDateString('hr-HR') : null;
|
||||
@@ -2498,5 +2503,6 @@ window.renderPGZToggleBtn = function(){
|
||||
};
|
||||
</script>
|
||||
<script src="/static/js/export_dropdown.js"></script>
|
||||
<script src="/static/_ai_widget.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user