idea / static /loguri.html
vsmdvic's picture
Upload 20 files
469a4d4 verified
<!DOCTYPE html>
<html lang="ro">
<head>
<link rel="icon" type="image/svg+xml" href="favicon.svg">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>IDEA | Loguri</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="topbar">
<a href="admin-dashboard.html" class="topbar-logo">
<img src="logo.svg" alt="IDEA">
<span class="topbar-name">IDEA</span>
</a>
<div class="topbar-divider"></div>
<span class="topbar-section">LOGURI SISTEM</span>
<div class="topbar-right">
<div class="online-dot"></div>
<span class="role-tag" style="color:var(--white);border-color:rgba(255,255,255,0.2);">ADMIN</span>
<button class="btn-ghost" onclick="loadLogs()" style="font-size:9px;">&#8635; Reîncarcă</button>
<button class="btn-ghost" onclick="window.location.href='admin-dashboard.html'" style="font-size:9px;">← Înapoi</button>
</div>
</div>
<div class="main">
<div class="stats-row fade-in" id="log-stats">
<div class="stat-box"><div class="stat-num" id="st-total"></div><div class="stat-lbl">TOTAL</div></div>
<div class="stat-box"><div class="stat-num" id="st-erori"></div><div class="stat-lbl">ERORI</div></div>
<div class="stat-box"><div class="stat-num" id="st-upload"></div><div class="stat-lbl">UPLOADURI</div></div>
<div class="stat-box"><div class="stat-num" id="st-login"></div><div class="stat-lbl">AUTENTIFICĂRI</div></div>
</div>
<div class="filter-row fade-in-2">
<button class="filter-btn active" onclick="setFilter('all',this)">TOATE</button>
<button class="filter-btn" onclick="setFilter('login',this)">LOGIN</button>
<button class="filter-btn" onclick="setFilter('upload',this)">UPLOAD</button>
<button class="filter-btn" onclick="setFilter('err_pass',this)">PAROLA GREȘITĂ</button>
<button class="filter-btn" onclick="setFilter('eroare',this)">ERORI</button>
<button class="filter-btn" onclick="setFilter('signup',this)">ÎNREGISTRARE</button>
<button class="filter-btn" onclick="setFilter('cleanup',this)">CLEANUP</button>
</div>
<div class="data-table fade-in-3">
<div class="dt-head log-row" style="background:rgba(255,255,255,0.025);">
<div>TIP</div><div>CINE</div><div>DETALII</div><div>CÂND</div>
</div>
<div id="logs-list">
<div class="log-empty">Se încarcă logurile...</div>
</div>
</div>
<footer class="footer">
<div class="footer-top"><img src="logo.svg" alt=""><span>IDEA</span></div>
<div class="footer-divider"></div>
<div class="footer-meta">Mîndrești, Telenești, Moldova</div>
<div class="footer-copy">&copy; 2026 Victor Roșca — v2.3 IDEA</div>
</footer>
</div>
<script>
if (sessionStorage.getItem('vs_role') !== 'admin') { window.location.href='index.html'; }
let _allLogs = [], _filter = 'all';
function tipClass(tip) {
if (!tip) return 'default';
if (tip==='login') return 'login';
if (tip==='logout') return 'logout';
if (tip==='upload') return 'upload';
if (tip==='err_pass' || tip==='eroare') return 'err_pass';
if (tip.includes('signup')||tip.includes('reset')) return 'signup';
if (tip.includes('cleanup')) return 'cleanup';
return 'default';
}
function tipLabel(tip) {
const m = {
'login':'LOGIN','logout':'LOGOUT','upload':'UPLOAD',
'err_pass':'PAROLA','eroare':'EROARE',
'signup_request':'SIGNUP','reset_request':'RESET',
'cleanup_delete':'CLEANUP','signup':'SIGNUP'
};
return m[tip] || (tip||'LOG').toUpperCase().slice(0,9);
}
function tsToStr(ts) {
if (!ts) return '—';
const d = new Date(parseInt(ts)*1000);
return d.toLocaleString('ro',{day:'2-digit',month:'short',hour:'2-digit',minute:'2-digit'});
}
async function loadLogs() {
document.getElementById('logs-list').innerHTML = '<div class="log-empty">Se încarcă...</div>';
try {
const r = await fetch('/api/logs');
const data = await r.json();
_allLogs = data.logs || [];
// Update stats
document.getElementById('st-total').textContent = _allLogs.length;
document.getElementById('st-erori').textContent = _allLogs.filter(l=>l.tip==='eroare'||l.tip==='err_pass').length;
document.getElementById('st-upload').textContent = _allLogs.filter(l=>l.tip==='upload').length;
document.getElementById('st-login').textContent = _allLogs.filter(l=>l.tip==='login').length;
renderLogs();
} catch(e) {
document.getElementById('logs-list').innerHTML = '<div class="log-empty">Eroare la încărcarea logurilor.</div>';
}
}
function renderLogs() {
const el = document.getElementById('logs-list');
el.innerHTML = '';
const filtered = _filter==='all'
? _allLogs
: _allLogs.filter(l => tipClass(l.tip)===_filter || l.tip===_filter);
if (!filtered.length) {
el.innerHTML = '<div class="log-empty">Niciun log pentru acest filtru.</div>';
return;
}
filtered.forEach(l => {
const row = document.createElement('div');
row.className = 'log-row';
let detalii = '';
if (l.tip==='eroare')
detalii = `<strong>${l.cod||'?'}</strong> — ${l.desc||'eroare necunoscută'}`;
else if (l.tip==='upload')
detalii = `<strong>${l.elevVpass||'?'}</strong> → <em>${l.fisier||'?'}</em> &nbsp;[${l.materie||'?'}]`;
else if (l.tip==='login')
detalii = `<strong>${l.vpass||'?'}</strong> s-a conectat ca ${l.role||'?'}`;
else if (l.tip==='logout')
detalii = `<strong>${l.vpass||'?'}</strong> s-a deconectat`;
else if (l.tip==='err_pass')
detalii = `Parolă greșită — <strong>${l.vpass||'?'}</strong>`;
else if (l.tip==='signup_request'||l.tip==='signup')
detalii = `Cerere înregistrare: <strong>${l.elevNume||l.elevVpass||'?'}</strong>`;
else if (l.tip==='reset_request')
detalii = `Reset parolă: <strong>${l.elevNume||l.elevVpass||'?'}</strong>`;
else if (l.tip==='cleanup_delete')
detalii = `Șters (expirat): <em>${l.fisier||l.fileId||'?'}</em>`;
else
detalii = JSON.stringify(l).slice(0,90);
row.innerHTML = `
<div><span class="log-type ${tipClass(l.tip)}">${tipLabel(l.tip)}</span></div>
<div style="font-size:10px;color:var(--white-dim);letter-spacing:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
${l.elevVpass||l.vpass||'sistem'}
</div>
<div style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${detalii}</div>
<div style="font-size:9px;color:var(--white-faint);letter-spacing:1px;">${tsToStr(l.ts)}</div>`;
el.appendChild(row);
});
}
function setFilter(f, btn) {
_filter = f;
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
renderLogs();
}
loadLogs();
setInterval(loadLogs, 30000); // auto-refresh la 30s
</script>
</body>
</html>