gwoe-antragspruefer/app/templates/v3/screens/antrag_detail.html
Dotty Dotter f471586f33 feat(v3): Themen, Kernpunkte, Schwerpunkt, Konfidenz, fehlende Programme, Wahlperiode + Ähnliche Anträge
DB-Felder die bisher in der UI fehlten, jetzt in v3 sichtbar:

- _row_to_detail() liefert themen, kernpunkte, schwerpunkt, link,
  konfidenz, fehlende_programme, wahlperiode an's Frontend.
- _wahlperiode_silent() leitet die WP aus datum+bundesland ab via
  wahlperioden.wahlperiode_for() — silent-fail bei Lookup-Fehler.

v3-Template:
- Wahlperiode in der Antrag-ID-Zeile ("18. Wahlperiode")
- Themen-Chips als Reihe unter byline
- Kernforderungen als Bullet-Liste in der Zusammenfassungs-Sektion
- Konfidenz-Pille (hoch/mittel/niedrig) neben der Empfehlung
- Schwerpunkt-Felder (Top-Matrix-Cells) als Chips über der Matrix
- Disclaimer "fehlende Programme" am Programm-Treue-Block
- Original-PDF-Link im Aktions-Block
- Ähnliche Anträge als eigener Block, geladen via JS aus
  /api/assessment/similar (Re-Use des bestehenden Endpoints aus #108)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 11:01:18 +02:00

536 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{# ─────────────────────────────────────────────────────────────────────
v3/screens/antrag_detail.html — Bürger:innen-Modus, single column
Override-Strategie: extendet v2/screens/antrag_detail.html und
ersetzt nur `block main` komplett. body_scripts erbt via super(), so
dass alle v2-JS-Handler (vote, merkliste, share, comments, history,
matrix-modal) ohne Code-Duplikation weiterlaufen — sie hängen sich an
DOM-IDs (v2-vote-up, v2-merkliste-btn, v2-comments-list, …), die wir
in der neuen Layout-Reihenfolge wiederverwenden.
Reihenfolge (single column):
1. Metadaten/Titel
2. Zusammenfassung
3. Bewertung (Score xl + Empfehlung daneben + Begründung darunter)
4. Merken / Bewertung treffend
5. Matrix 5×5
6. Programm-Treue (default-closed Klappmechanismus pro Programm)
7. Verbesserungsvorschläge (volle Breite, nicht kollabiert)
8. Abstimmungsergebnis
9. Rest: PDF/Teilen/Neu/Historie + Stärken/Schwächen + Konsistenz +
Marker-Legende + News + Kommentare
───────────────────────────────────────────────────────────────────── #}
{% extends "v2/screens/antrag_detail.html" %}
{% from "v2/components/score_hero.html" import score_hero %}
{% from "v2/components/matrix_mini.html" import matrix_mini %}
{% from "v2/components/quote_card.html" import quote_card %}
{% from "v2/components/redline.html" import redline %}
{% block head_extra %}
{{ super() }}
<link rel="stylesheet" href="/static/v3/v3.css?v={{ app_version|default('1') }}">
{% endblock %}
{% block main %}
{% if error is defined and error %}
<div class="v2-kasten" style="border-color:var(--redline-contra);margin-top:32px;">
<h3 style="color:var(--redline-contra);">Antrag nicht gefunden</h3>
<p>{{ error }}</p>
<p><a href="/">← Zurück zur Übersicht</a></p>
</div>
{% elif antrag is defined and antrag %}
<div class="v3-page">
<p class="v3-back">
<a href="/">← Zurück zur Übersicht</a>
</p>
{# 1 ── Metadaten + Titel ─────────────────────────────────────────── #}
<section class="v3-section v3-meta">
<div class="v3-antrag-id">
{{ antrag.bundesland | default("") }}
{% if antrag.drucksache %} · Drs. {{ antrag.drucksache }}{% endif %}
{% if antrag.typ %} · {{ antrag.typ }}{% endif %}
{% if antrag.wahlperiode %} · {{ antrag.wahlperiode }}. Wahlperiode{% endif %}
{% if antrag.datum %} · eingebracht {{ antrag.datum }}{% endif %}
</div>
<h1 class="v3-title">{{ antrag.title | default("Antrag") }}</h1>
{% if antrag.parteien or antrag.analysiert %}
<div class="v3-byline">
{% if antrag.parteien %}Eingebracht von {{ antrag.parteien | join(", ") }}{% endif %}
{% if antrag.analysiert %} — Analyse {{ antrag.analysiert }}{% endif %}
{% if antrag.modell %}, {{ antrag.modell }}{% endif %}
{% if antrag.zitate_count %} · {{ antrag.zitate_count }} Zitat{{ "e" if antrag.zitate_count != 1 else "" }} verifiziert{% endif %}
</div>
{% endif %}
{% if antrag.themen %}
<div class="v3-themen">
{% for t in antrag.themen %}<span class="v3-theme-chip">{{ t }}</span>{% endfor %}
</div>
{% endif %}
</section>
{# 2 ── Zusammenfassung + Kernpunkte ─────────────────────────────── #}
{% if antrag.zusammenfassung or antrag.kernpunkte %}
<section class="v3-section">
<h3 class="v3-h3">Zusammenfassung</h3>
{% if antrag.zusammenfassung %}
<p class="v3-prose">{{ antrag.zusammenfassung }}</p>
{% endif %}
{% if antrag.kernpunkte %}
<div class="v3-kernpunkte">
<div class="v3-kernpunkte-label">Kernforderungen</div>
<ul class="v3-kernpunkte-list">
{% for kp in antrag.kernpunkte %}<li>{{ kp }}</li>{% endfor %}
</ul>
</div>
{% endif %}
</section>
{% endif %}
{# 3 ── Bewertung ─────────────────────────────────────────────────── #}
<section class="v3-section v3-bewertung">
{% set s = (antrag.score | default(0)) | float %}
<div class="v3-bewertung-head">
<div class="v3-score-num">
{{ "%.1f"|format(s) }}<span class="v3-score-slash">/10</span>
</div>
{% if antrag.verdict_title %}
<div class="v3-empfehlung-wrap">
<div class="v3-empfehlung
{% if s >= 7 %}good{% elif s >= 4 %}mid{% else %}low{% endif %}">
{{ antrag.verdict_title }}
</div>
{% if antrag.konfidenz %}
<span class="v3-konfidenz v3-konfidenz-{{ antrag.konfidenz | lower }}"
title="Bewertungs-Konfidenz: wie sicher ist das LLM in dieser Einschätzung?">
Konfidenz: {{ antrag.konfidenz }}
</span>
{% endif %}
</div>
{% endif %}
</div>
{% if antrag.verdict_body %}
<p class="v3-bewertung-body">{{ antrag.verdict_body }}</p>
{% endif %}
</section>
{# 4 ── Merken + Bewertung treffend (User-Aktionen) ──────────────── #}
<section class="v3-section v3-userrow">
<button id="v2-merkliste-btn" onclick="v2DetailMerklisteToggle()" class="v3-action-btn">
<span id="v2-merkliste-star"></span>
<span id="v2-merkliste-label">Merken</span>
</button>
<div class="v3-userrow-vote">
<span class="v3-userrow-label">Bewertung treffend?</span>
<div id="v2-vote-overall" class="v3-vote-buttons">
<button id="v2-vote-up" onclick="v2DetailCastVote('{{ antrag.drucksache | e }}','up')" class="v3-action-btn">
👍 <span id="v2-vote-up-count">0</span>
</button>
<button id="v2-vote-down" onclick="v2DetailCastVote('{{ antrag.drucksache | e }}','down')" class="v3-action-btn">
👎 <span id="v2-vote-down-count">0</span>
</button>
</div>
</div>
</section>
{# 5 ── Matrix 5×5 (volle Profi-Variante, mit Klick-Modal) ────────── #}
{% if antrag.matrix %}
<section class="v3-section">
<h3 class="v3-h3">Matrix 2.0 · 25 Felder</h3>
{% if antrag.schwerpunkt %}
<div class="v3-schwerpunkt">
<span class="v3-schwerpunkt-label">Schwerpunkt-Felder:</span>
{% for f in antrag.schwerpunkt %}<span class="v3-schwerpunkt-chip">{{ f }}</span>{% endfor %}
</div>
{% endif %}
{{ matrix_mini(antrag.matrix) }}
</section>
{% endif %}
{# 6 ── Programm-Treue ─────────────────────────────────────────────── #}
{% if antrag.fraktions_scores %}
<section class="v3-section">
<h3 class="v3-h3">Programm-Treue pro Fraktion</h3>
{% if antrag.fehlende_programme %}
<div class="v3-disclaimer">
<strong>Hinweis:</strong> Für folgende Parteien lag kein Wahl-/Parteiprogramm vor — keine Treue-Bewertung möglich:
{{ antrag.fehlende_programme | join(", ") }}.
</div>
{% endif %}
<div class="v3-fraktionen">
{% for fs in antrag.fraktions_scores %}
<div class="v3-fraktion">
<div class="v3-fraktion-head">
<span class="v3-fraktion-name">{{ fs.fraktion }}</span>
{% if fs.ist_antragsteller %}<span class="v3-pill v3-pill-antrag">Antragsteller:in</span>{% endif %}
{% if fs.ist_regierung %}<span class="v3-pill v3-pill-reg">Regierungsfraktion</span>{% endif %}
</div>
{% for prog_key, prog_label in [("wahlprogramm","Wahlprogramm"),("parteiprogramm","Parteiprogramm")] %}
{% set p = fs[prog_key] %}
{% set p_score = p.score | float %}
<details class="v3-prog">
<summary class="v3-prog-row">
<span class="v3-prog-label">{{ prog_label }}</span>
<span class="v3-prog-spacer"></span>
<span class="v3-prog-score
{% if p_score >= 7 %}good{% elif p_score >= 4 %}mid{% else %}low{% endif %}">{{ "%.0f"|format(p_score) }}/10</span>
</summary>
<div class="v3-prog-body">
{% if p.begruendung %}<p class="v3-prog-text">{{ p.begruendung }}</p>{% endif %}
{% if p.zitate %}
<div class="v3-prog-zitate">
{% for z in p.zitate %}
{{ quote_card(z.text, z.source, True, False, z.pdf_href) }}
{% endfor %}
</div>
{% endif %}
</div>
</details>
{% endfor %}
</div>
{% endfor %}
</div>
</section>
{% endif %}
{# 7 ── Verbesserungsvorschläge — volle Breite, nicht kollabiert ───── #}
{% if antrag.verbesserungen %}
<section class="v3-section v3-verbesserungen">
<h3 class="v3-h3">Verbesserungsvorschläge</h3>
{% for v in antrag.verbesserungen %}
<div class="v3-verbesserung">
{% if antrag.verbesserungen | length > 1 %}
<div class="v3-verbesserung-num">Vorschlag {{ loop.index }} von {{ antrag.verbesserungen | length }}</div>
{% endif %}
{% if v.segments %}
{{ redline(original=v.original | default(""), segments=v.segments) }}
{% else %}
{{ redline(original=v.original | default(""), vorschlag=v.vorschlag | default("")) }}
{% endif %}
{% if v.begruendung %}
<p class="v3-verbesserung-begr">{{ v.begruendung }}</p>
{% endif %}
</div>
{% endfor %}
</section>
{% elif antrag.redline and antrag.redline.segments %}
<section class="v3-section v3-verbesserungen">
<h3 class="v3-h3">Verbesserungsvorschlag</h3>
{{ redline(segments=antrag.redline.segments) }}
</section>
{% endif %}
{# 8 ── Abstimmungsergebnis (Plenum + namentlich) ──────────────────── #}
{% if antrag.plenum_votes %}
<section class="v3-section v3-vote-section">
<h3 class="v3-h3">Abstimmungsergebnis</h3>
{% set ergebnis_color = {
"angenommen":"#2da44e","abgelehnt":"#cf222e","überwiesen":"#0969da",
"zurückgezogen":"#8250df","bestätigt":"#2da44e","sammel":"#0969da",
} %}
{% for v in antrag.plenum_votes %}
<div class="v3-vote-card">
<div class="v3-vote-card-head">
<span class="v3-vote-ergebnis" style="color:{{ ergebnis_color.get(v.ergebnis, '#6e7781') }};">
{{ v.ergebnis | capitalize }}{% if v.einstimmig %} · einstimmig{% endif %}
</span>
{% if v.quelle_url %}
<a href="{{ v.quelle_url }}" target="_blank" rel="noopener" class="v3-vote-quelle"
title="Plenarprotokoll im neuen Tab öffnen">
{{ v.quelle_protokoll }} ↗
</a>
{% else %}
<span class="v3-vote-quelle">{{ v.quelle_protokoll }}</span>
{% endif %}
</div>
{% if v.fraktionen_ja or v.fraktionen_nein or v.fraktionen_enthaltung %}
{% set _n_ja = v.fraktionen_ja | length %}
{% set _n_nein = v.fraktionen_nein | length %}
{% set _n_enth = v.fraktionen_enthaltung | length %}
{% set _n_total = _n_ja + _n_nein + _n_enth %}
{% if _n_total > 0 %}
<div class="v3-vote-bar"
title="Fraktions-Mehrheit: {{ _n_ja }} Ja · {{ _n_nein }} Nein · {{ _n_enth }} Enth.">
{% if _n_ja %}<div class="v3-vote-bar-ja" style="width:{{ (100 * _n_ja / _n_total) }}%;"></div>{% endif %}
{% if _n_enth %}<div class="v3-vote-bar-enth" style="width:{{ (100 * _n_enth / _n_total) }}%;"></div>{% endif %}
{% if _n_nein %}<div class="v3-vote-bar-nein" style="width:{{ (100 * _n_nein / _n_total) }}%;"></div>{% endif %}
</div>
<div class="v3-vote-bar-caption">
{{ _n_ja }}/{{ _n_total }} Fraktionen Ja · {{ _n_nein }} Nein · {{ _n_enth }} Enth.
</div>
{% endif %}
<div class="v3-vote-pills">
{% if v.fraktionen_ja %}
<div><span class="v3-vote-side ja">Ja:</span>
{% for f in v.fraktionen_ja %}
{% set _opp = opportunismus_score(f, antrag.fraktions_scores) %}
<span class="v3-vote-pill ja">{{ f }}{% if _opp is not none %}<span class="v3-marker opp" tabindex="0" role="button" title="Opportunismus-Marker — Ja trotz schwacher Wahlprogramm-Übereinstimmung (WP-Score {{ '%.0f' | format(_opp) }}/10).">!</span>{% endif %}</span>
{% endfor %}
</div>
{% endif %}
{% if v.fraktionen_nein %}
<div><span class="v3-vote-side nein">Nein:</span>
{% for f in v.fraktionen_nein %}
{% set _wp = heuchelei_score(f, antrag.fraktions_scores) %}
<span class="v3-vote-pill nein">{{ f }}{% if _wp is not none %}<span class="v3-marker heuchelei" tabindex="0" role="button" title="Heuchelei-Marker — Nein trotz hoher Wahlprogramm-Übereinstimmung (WP-Score {{ '%.0f' | format(_wp) }}/10)."></span>{% endif %}</span>
{% endfor %}
</div>
{% endif %}
{% if v.fraktionen_enthaltung %}
<div><span class="v3-vote-side enth">Enth.:</span>
{% for f in v.fraktionen_enthaltung %}<span class="v3-vote-pill enth">{{ f }}</span>{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
</div>
{% endfor %}
<div class="v3-vote-source">Quelle: Plenarprotokoll · automatisch extrahiert</div>
</section>
{% endif %}
{% if antrag.abstimmungsverhalten %}
{% set aw = antrag.abstimmungsverhalten %}
<section class="v3-section">
<h3 class="v3-h3">Namentliche Abstimmung</h3>
<div class="v3-namentlich">
<div>{{ aw.protokoll | default("") }}{% if aw.datum %} · {{ aw.datum }}{% endif %}</div>
{% if aw.abstimmung %}
<div>{{ aw.abstimmung.ja | default(0) }} Ja · {{ aw.abstimmung.nein | default(0) }} Nein · {{ aw.abstimmung.enthaltung | default(0) }} Enthaltung</div>
{% endif %}
</div>
</section>
{% endif %}
{# ════════════════ 9 ── REST-Block ════════════════════════════════════ #}
<section class="v3-rest">
{# 9a Aktions-Links #}
<div class="v3-rest-aktions">
<a href="/api/assessment/pdf?drucksache={{ antrag.drucksache | urlencode }}">PDF-Bericht</a>
{% if antrag.link %}
<a href="{{ antrag.link }}" target="_blank" rel="noopener">Original-Antrag (Landtag)</a>
{% endif %}
<a href="/api/assessment?drucksache={{ antrag.drucksache | urlencode }}">JSON-Export</a>
<a href="/antrag/{{ antrag.drucksache }}">Permalink</a>
</div>
{# 9a' Ähnliche Anträge — per JS via /api/assessment/similar geladen #}
<div class="v3-rest-block v3-similar" id="v3-similar-box" data-drucksache="{{ antrag.drucksache | e }}">
<h3 class="v3-h3">Ähnliche Anträge</h3>
<div id="v3-similar-list">
<span class="v3-loading">Lade …</span>
</div>
</div>
{# 9b Teilen #}
<div class="v3-rest-block">
<h3 class="v3-h3">Teilen</h3>
<div class="v3-share-buttons">
<button onclick="v2DetailShareCopy()" class="v3-action-btn">📋 Kopieren</button>
<button onclick="v2DetailShare('threads')" class="v3-action-btn">Threads</button>
<button onclick="v2DetailShareMastodon()" class="v3-action-btn">Mastodon</button>
<button onclick="v2DetailShare('linkedin')" class="v3-action-btn">LinkedIn</button>
<button onclick="v2DetailShareEmail()" class="v3-action-btn">📧 E-Mail</button>
<button onclick="v2DetailShareImage()" class="v3-action-btn">🖼 Bild</button>
</div>
</div>
{# 9c Neu analysieren #}
<div class="v3-rest-block">
<button id="v2-reanalyze-btn" onclick="v2DetailReAnalyze(this)" class="v3-action-btn v3-action-muted">
Neu analysieren
</button>
</div>
{# 9d Bewertungs-Historie #}
<div class="v3-rest-block">
<h3 class="v3-h3">Bewertungs-Historie</h3>
<div id="v2-history-list">
<span class="v3-loading">Lade…</span>
</div>
</div>
{# 9e Stärken / Schwächen #}
{% if antrag.staerkster_wert and antrag.staerkster_wert.text %}
<div class="v2-kasten outline-green">
<h4>Stärkster Wert{% if antrag.staerkster_wert.titel %} — {{ antrag.staerkster_wert.titel }}{% endif %}</h4>
<p>{{ antrag.staerkster_wert.text }}</p>
</div>
{% elif antrag.staerken %}
<div class="v2-kasten outline-green">
<h4>Stärken</h4>
<ul>
{% for s in antrag.staerken %}<li>{{ s }}</li>{% endfor %}
</ul>
</div>
{% endif %}
{% if antrag.schwaechster_wert and antrag.schwaechster_wert.text %}
<div class="v2-kasten outline-blue">
<h4>Schwächster Wert{% if antrag.schwaechster_wert.titel %} — {{ antrag.schwaechster_wert.titel }}{% endif %}</h4>
<p>{{ antrag.schwaechster_wert.text }}</p>
</div>
{% elif antrag.schwaechen %}
<div class="v2-kasten outline-blue">
<h4>Schwächen</h4>
<ul>
{% for s in antrag.schwaechen %}<li>{{ s }}</li>{% endfor %}
</ul>
</div>
{% endif %}
{# 9f Konsistenz-Hinweis #}
{% if antrag.plenum_votes %}
{% set _state = consistency_state(antrag.verdict_title, antrag.plenum_votes) %}
{% set _decisive = decisive_outcome(antrag.plenum_votes) %}
{% if _state %}
<div class="v3-konsistenz {{ _state }}">
<strong>{% if _state == 'conflict' %}Mehrheit kontra GWÖ-Empfehlung{% else %}Mehrheit deckt sich mit GWÖ-Empfehlung{% endif %}</strong>
— Empfohlen: <em>{{ antrag.verdict_title }}</em>; Beschluss: <em>{{ _decisive | capitalize }}</em>.
</div>
{% endif %}
{% endif %}
{# 9g Marker-Legende — nur wenn ⚠ oder ! im Vote-Block vorkam #}
{% set _legende = namespace(heuchelei=false, opp=false) %}
{% for vv in (antrag.plenum_votes or []) %}
{% for f in (vv.fraktionen_nein or []) %}
{% if heuchelei_score(f, antrag.fraktions_scores) is not none %}{% set _legende.heuchelei = true %}{% endif %}
{% endfor %}
{% for f in (vv.fraktionen_ja or []) %}
{% if opportunismus_score(f, antrag.fraktions_scores) is not none %}{% set _legende.opp = true %}{% endif %}
{% endfor %}
{% endfor %}
{% if _legende.heuchelei or _legende.opp %}
<div class="v3-marker-legend">
{% if _legende.heuchelei %}
<div><span class="v3-marker heuchelei"></span> <strong>Heuchelei:</strong> Nein trotz hoher Wahlprogramm-Übereinstimmung (WP&nbsp;&nbsp;7/10).</div>
{% endif %}
{% if _legende.opp %}
<div><span class="v3-marker opp">!</span> <strong>Opportunismus:</strong> Ja trotz schwacher Wahlprogramm-Übereinstimmung (WP&nbsp;&lt;&nbsp;3/10).</div>
{% endif %}
</div>
{% endif %}
{# 9h News-Box (per JS gefuellt) #}
<div id="ad-news-box" class="v3-news-box" style="display:none;">
<h3 class="v3-h3">Aktuelle News passend zu diesem Antrag</h3>
<p class="v3-news-meta">Embedding-Match aus den letzten 90 Tagen. Quelle: Tagesschau-API + Bundestag-RSS.</p>
<div id="ad-news-list">
<div class="v3-loading">Lade …</div>
</div>
</div>
{# 9i Kommentare #}
<div class="v3-rest-block v3-comments">
<h3 class="v3-h3">Kommentare</h3>
<div id="v2-comments-list">
<span class="v3-loading">Lade…</span>
</div>
<div id="v2-comment-form" style="display:none;">
<div class="v3-comment-label">Kommentar hinzufügen</div>
<textarea id="v2-comment-input" rows="3" placeholder="Kommentar…" class="v3-comment-textarea"></textarea>
<div class="v3-comment-controls">
<select id="v2-comment-visibility" class="v3-comment-vis">
<option value="all">Öffentlich</option>
<option value="authenticated">Nur Angemeldete</option>
<option value="private">Nur ich</option>
</select>
<button onclick="v2DetailAddComment('{{ antrag.drucksache | e }}')" class="v3-action-btn primary">Absenden</button>
</div>
</div>
<div id="v2-comment-login-hint" style="display:none;">
<button onclick="v2AuthModalOpen()" class="v3-action-btn">Anmelden um zu kommentieren</button>
</div>
</div>
</section>{# v3-rest #}
{# ════════════════ Modals ═════════════════════════════════════════════ #}
{# Matrix-Feld-Info-Modal — gleiche IDs wie v2, JS aus super() greift #}
<div id="v2-matrix-field-modal"
role="dialog" aria-modal="true" aria-label="Matrix-Feld Erklärung"
class="v3-modal"
onclick="if(event.target===this)this.style.display='none'">
<div class="v3-modal-card">
<div class="v3-modal-head">
<strong id="v2-matrix-field-title" class="v3-modal-title"></strong>
<span id="v2-matrix-field-rating" class="v3-modal-rating"></span>
<button onclick="document.getElementById('v2-matrix-field-modal').style.display='none'"
class="v3-modal-close" aria-label="Schließen">×</button>
</div>
<div id="v2-matrix-field-antrag" class="v3-modal-section" style="display:none;">
<div class="v3-modal-sublabel">Bewertung in diesem Antrag</div>
<div id="v2-matrix-field-label" class="v3-modal-itemlabel"></div>
<div id="v2-matrix-field-aspect" class="v3-modal-itemtext"></div>
</div>
<div class="v3-modal-section v3-modal-section--bordered">
<div class="v3-modal-sublabel">Was misst dieses Feld?</div>
<p id="v2-matrix-field-text" class="v3-modal-itemtext"></p>
</div>
</div>
</div>
</div>{# .v3-page #}
{% endif %}{# antrag #}
{% endblock %}
{% block body_scripts %}
{{ super() }}
<script>
/* v3-Topbar-Pill + Toggle zurueck zu Profi-Modus */
(function () {
var bar = document.querySelector('.v2-topbar');
if (!bar) return;
var pill = document.createElement('span');
pill.className = 'v3-beta-badge';
pill.textContent = 'Bürger:innen-Modus · Beta';
pill.title = 'Vereinfachte Ansicht. v3 ist eine frühe Vorschau.';
var toggle = document.createElement('a');
toggle.className = 'v3-modus-toggle';
toggle.href = '/antrag/' + encodeURIComponent({{ antrag.drucksache | tojson if antrag is defined and antrag else '""' | safe }});
toggle.textContent = '→ Profi-Modus';
toggle.title = 'Volle GWÖ-Detailansicht (v2) öffnen';
bar.appendChild(pill);
bar.appendChild(toggle);
})();
/* Ähnliche Anträge: /api/assessment/similar?drucksache=…&top_k=5 */
(async function () {
var box = document.getElementById('v3-similar-box');
if (!box) return;
var drs = box.dataset.drucksache;
var list = document.getElementById('v3-similar-list');
try {
var resp = await fetch('/api/assessment/similar?drucksache=' + encodeURIComponent(drs) + '&top_k=5');
var data = await resp.json();
var items = (data && data.results) || data || [];
if (!Array.isArray(items) || items.length === 0) {
list.innerHTML = '<span class="v3-loading">Keine ähnlichen Anträge gefunden.</span>';
return;
}
list.innerHTML = items.map(function (it) {
var sim = (it.similarity != null) ? Math.round(it.similarity * 100) + '%' : '';
var bl = it.bundesland || '';
var drs = it.drucksache || '';
var title = it.title || '';
var score = (it.gwoe_score != null) ? it.gwoe_score.toFixed(1) : '';
return '<a href="/v3/antrag/' + encodeURIComponent(drs) + '" class="v3-similar-item">'
+ '<div class="v3-similar-meta">' + bl + (drs ? ' · Drs. ' + drs : '') + (sim ? ' · ' + sim + ' ähnlich' : '') + '</div>'
+ '<div class="v3-similar-title">' + title + '</div>'
+ (score ? '<div class="v3-similar-score">Score ' + score + '/10</div>' : '')
+ '</a>';
}).join('');
} catch (e) {
list.innerHTML = '<span class="v3-loading">Konnte ähnliche Anträge nicht laden.</span>';
}
})();
</script>
{% endblock %}