Matrix klickbar: Feld-Info-Modal mit Bürger:innen-Erklärungen + Spalten nummeriert

Klick auf jedes Matrix-Feld öffnet ein Modal mit:
- Feld-Code + voller Name (z.B. "D4: Soziale Gestaltung")
- Zeile + Spalte in Klartext
- "Was bedeutet das für Bürger:innen?" Erklärung (25 Texte)
- Falls bewertet: Aspekt aus der LLM-Analyse + Rating-Farbe
- Falls nicht bewertet: "Dieses Feld wird vom Antrag nicht berührt"

Spaltenüberschriften: "1. Menschenwürde" statt nur "Menschenwürde"
This commit is contained in:
Dotty Dotter 2026-04-10 23:38:37 +02:00
parent 3e7154720b
commit 14e2e1eee2
2 changed files with 68 additions and 4 deletions

View File

@ -167,6 +167,33 @@ async def index(request: Request):
"bundeslaender": bl_list,
"parlament_names": parlament_names,
"matrix_labels": MATRIX_LABELS,
"matrix_explanations": {
"A1": "Werden bei öffentlichen Aufträgen Grundrechte in der Lieferkette beachtet?",
"A2": "Fließt öffentliches Geld in regionale Wertschöpfung statt Großkonzerne?",
"A3": "Achten Lieferant:innen auf Klimaschutz und Ressourcenschonung?",
"A4": "Werden faire Löhne bei externen Dienstleistern sichergestellt?",
"A5": "Ist die Vergabe öffentlicher Aufträge transparent nachvollziehbar?",
"B1": "Wird mit öffentlichen Geldern ethisch umgegangen?",
"B2": "Werden Steuergelder für den Nutzen aller eingesetzt?",
"B3": "Wird bei Investitionen der ökologische Fußabdruck berücksichtigt?",
"B4": "Ist die Verteilung öffentlicher Mittel sozial gerecht?",
"B5": "Können Bürger:innen mitentscheiden, wofür Geld ausgegeben wird?",
"C1": "Gibt es Gleichstellung und Diskriminierungsschutz in der Verwaltung?",
"C2": "Arbeiten Verwaltung und Politik an gemeinsamen Gemeinwohl-Zielen?",
"C3": "Fördert die Verwaltung umweltbewusstes Handeln?",
"C4": "Gibt es Chancengleichheit und familienfreundliche Arbeitszeiten?",
"C5": "Sind Entscheidungsprozesse in Politik und Verwaltung transparent?",
"D1": "Werden Grundrechte geschützt? Gleichheit vor dem Gesetz?",
"D2": "Profitieren möglichst viele Menschen — nicht nur einzelne Gruppen?",
"D3": "Wird die Daseinsvorsorge ökologisch nachhaltig gestaltet?",
"D4": "Haben alle Zugang zu Bildung, Gesundheit, Wohnen — unabhängig vom Einkommen?",
"D5": "Werden Bürger:innen bei Entscheidungen einbezogen?",
"E1": "Werden die Rechte künftiger Generationen mitgedacht?",
"E2": "Hat der Antrag positive Wirkung über die Gemeindegrenzen hinaus?",
"E3": "Werden ökologische Auswirkungen global bedacht?",
"E4": "Trägt der Antrag zum sozialen Ausgleich bei — auch überregional?",
"E5": "Fördert der Antrag demokratische Mitbestimmung über die Gemeinde hinaus?",
},
})

View File

@ -980,6 +980,41 @@
}
}
// Matrix-Feld-Info-Modal
function showFieldInfo(field, aspect, rating) {
const labels = {{ matrix_labels | tojson }};
const explains = {{ matrix_explanations | tojson }};
const rowNames = {'A':'Ausgelagerte Betriebe, Lieferant:innen','B':'Finanzpartner:innen, Steuerzahler:innen','C':'Politische Führung, Verwaltung','D':'Bürger:innen und Wirtschaft','E':'Staat, Gesellschaft und Natur'};
const colNames = {1:'Menschenwürde',2:'Solidarität',3:'Ökologische Nachhaltigkeit',4:'Soziale Gerechtigkeit',5:'Transparenz & Mitbestimmung'};
const row = field[0], col = parseInt(field[1]);
const ratingText = rating >= 4 ? '++ stark fördernd' : rating >= 1 ? '+ fördernd' : rating === 0 ? '○ neutral / nicht bewertet' : rating >= -3 ? ' widersprechend' : ' stark widersprechend';
const ratingColor = rating > 0 ? '#889e33' : rating < 0 ? '#dc3545' : '#888';
const html = `
<div style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.4);z-index:300;display:flex;justify-content:center;align-items:center;" onclick="if(event.target===this)this.remove()">
<div style="background:white;border-radius:8px;padding:1.5rem;max-width:500px;width:90%;box-shadow:0 8px 24px rgba(0,0,0,0.2);">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;">
<h3 style="color:var(--color-blue);margin:0;">${field}: ${labels[field] || field}</h3>
<button onclick="this.closest('[style*=fixed]').remove()" style="background:none;border:none;font-size:1.2rem;cursor:pointer;"></button>
</div>
<div style="font-size:0.85rem;color:#666;margin-bottom:0.75rem;">
<strong>Zeile ${row}:</strong> ${rowNames[row] || ''}<br>
<strong>Spalte ${col}:</strong> ${colNames[col] || ''}
</div>
<div style="background:#f8f9fa;padding:0.75rem;border-radius:6px;margin-bottom:0.75rem;font-size:0.9rem;">
<strong>Was bedeutet das für Bürger:innen?</strong><br>
${explains[field] || 'Keine Erklärung verfügbar.'}
</div>
${aspect ? `<div style="background:#fffbf0;padding:0.75rem;border-radius:6px;margin-bottom:0.75rem;font-size:0.9rem;border-left:3px solid ${ratingColor};">
<strong>Bewertung dieses Antrags:</strong><br>
${aspect}<br>
<span style="color:${ratingColor};font-weight:bold;">Bewertung: ${rating} (${ratingText})</span>
</div>` : '<p style="color:#aaa;font-size:0.85rem;">Dieses Feld wird vom Antrag nicht berührt.</p>'}
</div>
</div>`;
document.body.insertAdjacentHTML('beforeend', html);
}
// Sortierung (#100)
function setSortOrder(order) {
currentSort = order;
@ -1890,8 +1925,11 @@
const fieldLabels = {{ matrix_labels | tojson }};
const ratingExplain = (r) => r >= 4 ? '++ stark fördernd' : r >= 1 ? '+ fördernd' : r === 0 ? '○ neutral' : r >= -3 ? ' widersprechend' : ' stark widersprechend';
// Bürger:innen-Erklärungen pro Feld
const fieldExplain = {{ matrix_explanations | tojson }};
let matrixTableHtml = '<table class="matrix-table"><thead><tr><th style="min-width:120px;"></th>';
for (let col = 1; col <= 5; col++) matrixTableHtml += `<th title="${colPrinzip[col]}" style="cursor:help;">${colLabels[col]}</th>`;
for (let col = 1; col <= 5; col++) matrixTableHtml += `<th title="${colPrinzip[col]}" style="cursor:help;">${col}. ${colLabels[col]}</th>`;
matrixTableHtml += '</tr></thead><tbody>';
['A', 'B', 'C', 'D', 'E'].forEach(row => {
@ -1902,10 +1940,9 @@
const fullLabel = fieldLabels[field] || field;
if (entry) {
const cssClass = entry.rating > 0 ? 'positive' : (entry.rating < 0 ? 'negative' : 'neutral');
const tooltip = `${field}: ${fullLabel}\n\n${entry.aspect || ''}\n\nBewertung: ${entry.rating} (${ratingExplain(entry.rating)})`;
matrixTableHtml += `<td class="${cssClass}" title="${tooltip.replace(/"/g,'&quot;')}" style="cursor:help;">${entry.symbol}</td>`;
matrixTableHtml += `<td class="${cssClass}" style="cursor:pointer;" onclick="showFieldInfo('${field}', ${JSON.stringify(entry.aspect||'').replace(/'/g,'\\x27')}, ${entry.rating})">${entry.symbol}</td>`;
} else {
matrixTableHtml += `<td title="${field}: ${fullLabel}\n\n○ Nicht bewertet (Antrag berührt dieses Feld nicht)" style="cursor:help;color:#ccc;"></td>`;
matrixTableHtml += `<td style="cursor:pointer;color:#ccc;" onclick="showFieldInfo('${field}', '', 0)"></td>`;
}
}
matrixTableHtml += '</tr>';