diff --git a/backend/static/js/pages/admin.js b/backend/static/js/pages/admin.js
index 03e3ad0..c871275 100644
--- a/backend/static/js/pages/admin.js
+++ b/backend/static/js/pages/admin.js
@@ -683,9 +683,13 @@ window.Page_admin = (() => {
+
@@ -741,6 +745,62 @@ window.Page_admin = (() => {
}
});
+ el.querySelector('#adm-evaluate-breeds').addEventListener('click', async (e) => {
+ const btn = e.currentTarget;
+ const res = el.querySelector('#adm-maint-result');
+ const box = el.querySelector('#adm-eval-result');
+ btn.disabled = true;
+ res.textContent = 'Bewertung läuft… (ca. 30s)';
+ box.style.display = 'none';
+ try {
+ const d = await API.get('/admin/wiki/evaluate?sample=20');
+ if (d.error) { res.textContent = '✗ ' + d.error; return; }
+ const avg = d.averages;
+ const scoreColor = v => v >= 4 ? 'var(--c-success)' : v >= 3 ? 'var(--c-warning)' : 'var(--c-danger)';
+ const scoreBar = v => `
${v.toFixed(1)}`;
+ const rows = d.results.filter(r => !r.error).map(r =>
+ `
+ | ${_esc(r.name)} |
+ ${scoreBar(r.vollstaendigkeit)} |
+ ${scoreBar(r.korrektheit)} |
+ ${scoreBar(r.sprachqualitaet)} |
+ ${scoreBar(r.konsistenz)} |
+ ${scoreBar(r.gesamt)} |
+ ${_esc(r.hinweis || '')} |
+
`
+ ).join('');
+ box.style.display = 'block';
+ box.innerHTML = `
+
+ Ø-Scores (${d.evaluated}/${d.sample_size} Rassen bewertet)
+
+
+ ${['vollstaendigkeit','korrektheit','sprachqualitaet','konsistenz','gesamt'].map(k =>
+ `
+
${avg[k]?.toFixed(1) ?? '–'}
+
${{vollstaendigkeit:'Vollst.',korrektheit:'Korrekt.',sprachqualitaet:'Sprache',konsistenz:'Konsistenz',gesamt:'Gesamt'}[k]}
+
`
+ ).join('')}
+
+
+
+
+ | Rasse |
+ Vollst. | Korrekt. |
+ Sprache | Konsis. |
+ Ges. | Hinweis |
+
+ ${rows}
+
+
`;
+ res.textContent = `✓ Bewertung abgeschlossen`;
+ } catch (err) {
+ res.textContent = '✗ Fehler: ' + (err.message || err);
+ } finally {
+ btn.disabled = false;
+ }
+ });
+
await _loadSystemCards(el.querySelector('#adm-sys-cards'));
await loadLogs();
}