feat(dashboard): add data verification status section to overview tab

This commit is contained in:
Rene Fichtmueller 2026-04-05 12:11:23 +02:00
parent a1223e8967
commit d3780ef4fc

View File

@ -832,6 +832,12 @@
<div class="stat-val" id="ov-news">&mdash;</div> <div class="stat-val" id="ov-news">&mdash;</div>
</div> </div>
</div> </div>
<!-- VERIFICATION STATUS -->
<div class="card mb" id="verification-card">
<div class="card-label">Data Verification Status</div>
<div id="verification-overview" class="mt" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1rem"></div>
</div>
<div class="grid g2 mb"> <div class="grid g2 mb">
<div class="card"> <div class="card">
<div class="card-label">Vector Collections</div> <div class="card-label">Vector Collections</div>
@ -1883,6 +1889,31 @@ async function loadOverview() {
animateValue(el('ov-switches'), h.database.stats.switch_count, 600); animateValue(el('ov-switches'), h.database.stats.switch_count, 600);
animateValue(el('ov-standards'), h.database.stats.standard_count, 700); animateValue(el('ov-standards'), h.database.stats.standard_count, 700);
animateValue(el('ov-news'), h.database.stats.news_count, 900); animateValue(el('ov-news'), h.database.stats.news_count, 900);
// Verification status section
if (h.verification) {
var v = h.verification;
var total = v.total || 1;
var items = [
{ label: 'Price Verified', count: v.price_verified, pct: v.price_coverage_pct || Math.round(v.price_verified / total * 100), color: '#22c55e' },
{ label: 'Image Verified', count: v.image_verified, pct: Math.round(v.image_verified / total * 100), color: '#3b82f6' },
{ label: 'Details Verified', count: v.details_verified, pct: Math.round(v.details_verified / total * 100), color: '#a855f7' },
{ label: 'Fully Verified', count: v.fully_verified, pct: v.fully_verified_pct || Math.round(v.fully_verified / total * 100), color: '#f97316' },
];
buildDOM(el('verification-overview'), items.map(function(item) {
return '<div style="background:var(--surface2);border:1px solid var(--border);border-radius:8px;padding:0.75rem 1rem">'
+ '<div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:0.4rem">'
+ '<span style="font-size:0.75rem;color:var(--text-dim)">' + item.label + '</span>'
+ '<span style="font-size:0.9rem;font-weight:700;color:var(--text-bright);font-family:var(--mono)">' + (item.count || 0).toLocaleString() + '</span>'
+ '</div>'
+ '<div style="background:var(--surface3);border-radius:4px;height:6px;overflow:hidden">'
+ '<div style="height:100%;width:' + (item.pct || 0) + '%;background:' + item.color + ';border-radius:4px;transition:width 1s ease"></div>'
+ '</div>'
+ '<div style="font-size:0.7rem;color:var(--text-dim);margin-top:0.3rem;text-align:right">' + (item.pct || 0) + '% of ' + total.toLocaleString() + '</div>'
+ '</div>';
}).join(''));
}
el('version-label').textContent = 'v' + h.version; el('version-label').textContent = 'v' + h.version;
el('api-status').className = 'dot ' + (h.success ? 'dot-ok' : 'dot-err'); el('api-status').className = 'dot ' + (h.success ? 'dot-ok' : 'dot-err');
el('db-status').className = 'dot ' + (h.database.connected ? 'dot-ok' : 'dot-err'); el('db-status').className = 'dot ' + (h.database.connected ? 'dot-ok' : 'dot-err');