gwoe-antragspruefer/app/templates/v3/screens/antrag_detail.html
Dotty Dotter 2821b8566e feat: Scorecards in Share-Block sichtbar + Instagram-Button
User-Frage: 'Wo kann ich jetzt die Cards angucken? Vielleicht verbunden
mit einem Instagram Sharing Button?'

Endpoints existieren laengst (#179):
- /v2/scorecard?format=og     → 1200×630 LinkedIn/Twitter-Card
- /v2/scorecard?format=square → 1080×1080 Instagram
- /api/assessment/scorecard.png?format=square&scale=2 → PNG

In der Share-Row jetzt drei neue Eintraege:

1. '📷 Instagram' — oeffnet Square-PNG (1080×1080) im neuen Tab,
   legt Begleittext in die Zwischenablage. Instagram hat keinen
   Web-Share-Endpoint, daher: Bild speichern + Text einfuegen.
2. '📊 Scorecard ansehen' — oeffnet die OG-Format-Vorschau (1200×630)
   im neuen Tab, der User sieht wie die Card auf LinkedIn/Twitter
   aussehen wird.
3. '🖼 Stock-Bild' — alter Magnific-Stockphoto-Knopf, jetzt klar
   gelabelt damit er nicht mit der Scorecard verwechselt wird.

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

507 lines
23 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>
{# Merken + Bewertung treffend — direkt unter den Metadaten ──────── #}
<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>
{# 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
{% if s >= 7 %}good{% elif s >= 4 %}mid{% else %}low{% endif %}">
{{ "%.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="Wie sicher ist die Bewertung des LLM? — wissenschaftlicher Begriff: Konfidenz.">
Bewertungs-Sicherheit: {{ antrag.konfidenz }}
</span>
{% endif %}
</div>
{% endif %}
</div>
{% if antrag.verdict_body %}
<p class="v3-bewertung-body">{{ antrag.verdict_body }}</p>
{% endif %}
</section>
{# 3b ── Stärkster + Schwächster Wert (nach Bewertung, vor User-Aktionen) #}
{% if antrag.staerkster_wert or antrag.staerken or antrag.schwaechster_wert or antrag.schwaechen %}
<section class="v3-section v3-werte-grid">
{% 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 %}
</section>
{% endif %}
{# 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>
{% else %}
<p class="v3-prog-no-zitate">
Keine wörtlich passenden Stellen im {{ prog_label }} gefunden.
Die Bewertung beruht auf inhaltlicher Auslegung — entweder benennt das Programm
das konkrete Thema nicht explizit, oder es bleibt zu allgemein, um wörtlich
zugeordnet zu werden.
</p>
{% 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>
{# Konsistenz-Hinweis: GWÖ-Empfehlung vs tatsaechlicher Beschluss #}
{% 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 gegen GWÖ-Empfehlung{% else %}Mehrheit deckt sich mit GWÖ-Empfehlung{% endif %}</strong>
— Empfohlen: <em>{{ antrag.verdict_title }}</em>; Beschluss: <em>{{ _decisive | capitalize }}</em>.
</div>
{% endif %}
{% 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="Wahlprogramm-Konflikt — Diese Fraktion stimmte mit Ja, obwohl der Antrag schlecht zum eigenen Wahlprogramm passt (Wahlprogramm-Score {{ '%.0f' | format(_opp) }}/10). Wissenschaftliche Klassifikation: Opportunismus-Indikator.">!</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="Wahlprogramm-Konflikt — Diese Fraktion stimmte mit Nein, obwohl der Antrag inhaltlich gut zum eigenen Wahlprogramm passt (Wahlprogramm-Score {{ '%.0f' | format(_wp) }}/10). Wissenschaftliche Klassifikation: Heuchelei-Indikator."></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">
{# Ä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>
{# Teilen #}
<div class="v3-rest-block v3-rest-divider-top">
<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="v2DetailShareInstagram()" class="v3-action-btn">📷 Instagram</button>
<button onclick="v2DetailShareEmail()" class="v3-action-btn">📧 E-Mail</button>
<button onclick="v2DetailShareScorecard()" class="v3-action-btn">📊 Scorecard ansehen</button>
<button onclick="v2DetailShareImage()" class="v3-action-btn" title="Stockphoto-Suche bei Magnific zum Antragsthema">🖼 Stock-Bild</button>
</div>
</div>
{# Aktions-Links: PDF, Original, JSON, Permalink — unter Teilen #}
<div class="v3-rest-aktions v3-rest-divider-top">
<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>
{# News-Box (per JS gefuellt) — eine Nachricht, max 9 Zeilen #}
<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>
{# 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>
{# 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>
/* Ä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 %}