Dashboard: - Neuer Endpoint GET /api/stats/dashboard mit allen Kennzahlen - Klickbare Kacheln: Vorlagen nach Typ, Ketten nach Status → navigieren zu Filterlisten - Umsetzungsquote als horizontaler Balken mit klickbaren Segmenten Abstimmungen: - Stimmverhalten-Tabelle klickbar: Fraktion oder Ja/Nein/Enthaltung → filtert - Neuer Endpoint GET /api/abstimmungen/details (?fraktion=&stimme=) mit Pagination - Neuer Endpoint GET /api/abstimmungen/vergleich (?f1=&f2=) für Koalitionsmatrix-Drill-Down - Koalitionsmatrix-Zellen klickbar → zeigt Abstimmungsvergleich beider Fraktionen Fraktions-Normalisierung: - fraktionen_mapping.py: 40+ DB-Varianten → kanonische Namen - 'Bündnis 90 / Die Grünen' / 'Bündnis 90/Die Grünen' / 'Grüne' → 'Grüne' - 'Die Linke' / 'Die Linke.' / 'Linke' → 'Linke' - BfHo-Varianten, Hagen Aktiv, Einzelvertreter etc. normalisiert - Mapping in allen Abstimmungs-Endpoints aktiv - ist_ratsfraktion Flag in Fraktionen-Response Closes #14
2 lines
11 KiB
JavaScript
2 lines
11 KiB
JavaScript
import{d as Re,a as i,f as m,b as f,t as T}from"../chunks/B89f14j0.js";import{p as Fe,s as M,a as He,b as n,f as xe,c as Me,d as U,e as Oe,$ as Ze,g as e,h as a,r,t as u,n as O,u as Ge}from"../chunks/reyx9_7L.js";import{s as o}from"../chunks/BwTTNG21.js";import{i as p}from"../chunks/Do7Yo2YN.js";import{h as Je,e as te,i as re}from"../chunks/D5EBvEcH.js";import{s as V}from"../chunks/B-WTs0fq.js";import{s as K}from"../chunks/C7sCDBjT.js";import{s as D}from"../chunks/DnBxR3jh.js";/* empty css */import{g as w}from"../chunks/BHBF0lbh.js";var Ne=m('<div class="bg-red-50 text-red-700 p-4 rounded-lg mb-6"> </div>'),Qe=m('<div class="flex justify-center py-20"><div class="animate-spin rounded-full h-12 w-12 border-b-2 border-green-600"></div></div>'),We=m('<button class="border border-gray-200 rounded-lg p-4 text-left cursor-pointer hover:shadow-md hover:border-green-300 transition-all group"><div class="text-2xl mb-1"> </div> <div class="text-xl font-bold text-gray-900 group-hover:text-green-700"> </div> <div class="text-sm text-gray-500"> </div></button>'),Xe=m('<button><div class="text-xl font-bold"> </div> <div class="text-sm opacity-80"> </div></button>'),Ye=m("<button><!></button>"),et=m("<button><!></button>"),tt=m("<button><!></button>"),rt=m("<button><!></button>"),at=m("<button><!></button>"),st=m('<section class="bg-white rounded-xl shadow-sm border border-gray-200 p-5 mb-8"><h2 class="text-lg font-semibold text-gray-900 mb-1">📈 Umsetzungsquote</h2> <p class="text-sm text-gray-500 mb-4"> </p> <div class="flex rounded-full overflow-hidden h-8 mb-4"><!> <!> <!> <!> <!></div> <div class="flex flex-wrap gap-4 text-sm"><span class="flex items-center gap-1.5"><span class="w-3 h-3 rounded-full bg-green-500"></span> </span> <span class="flex items-center gap-1.5"><span class="w-3 h-3 rounded-full bg-amber-400"></span> </span> <span class="flex items-center gap-1.5"><span class="w-3 h-3 rounded-full bg-blue-400"></span> </span> <span class="flex items-center gap-1.5"><span class="w-3 h-3 rounded-full bg-gray-400"></span> </span> <span class="flex items-center gap-1.5"><span class="w-3 h-3 rounded-full bg-red-400"></span> </span></div></section>'),nt=m('<div class="p-6 text-center text-gray-500">Keine Anträge gefunden</div>'),ot=m('<li><a class="block px-5 py-4 hover:bg-gray-50 transition-colors"><div class="flex justify-between items-start"><div class="flex-1 min-w-0"><div class="flex items-center gap-2 flex-wrap"><span class="font-mono text-sm text-green-700 bg-green-50 px-2 py-0.5 rounded"> </span> <span class="text-xs text-gray-400"> </span></div> <p class="mt-1 text-gray-700 text-sm line-clamp-2"> </p></div></div></a></li>'),it=m('<ul class="divide-y divide-gray-100"></ul>'),lt=m('<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8"><button class="bg-white rounded-xl shadow-sm border border-gray-200 p-5 text-center cursor-pointer hover:shadow-md transition-shadow"><div class="text-3xl font-bold text-green-600"> </div> <div class="text-gray-500 text-sm mt-1">Vorlagen</div></button> <button class="bg-white rounded-xl shadow-sm border border-gray-200 p-5 text-center cursor-pointer hover:shadow-md transition-shadow"><div class="text-3xl font-bold text-blue-600"> </div> <div class="text-gray-500 text-sm mt-1">Ketten</div></button> <button class="bg-white rounded-xl shadow-sm border border-gray-200 p-5 text-center cursor-pointer hover:shadow-md transition-shadow"><div class="text-3xl font-bold text-purple-600"> </div> <div class="text-gray-500 text-sm mt-1">Abstimmungen</div></button> <div class="bg-white rounded-xl shadow-sm border border-gray-200 p-5 text-center"><div class="text-3xl font-bold text-orange-600">2004–2026</div> <div class="text-gray-500 text-sm mt-1">Zeitraum</div></div></div> <section class="bg-white rounded-xl shadow-sm border border-gray-200 p-5 mb-8"><h2 class="text-lg font-semibold text-gray-900 mb-4">📊 Vorlagen nach Typ</h2> <div class="grid grid-cols-2 md:grid-cols-4 gap-3"></div></section> <section class="bg-white rounded-xl shadow-sm border border-gray-200 p-5 mb-8"><h2 class="text-lg font-semibold text-gray-900 mb-4">🔗 Ketten nach Status</h2> <div class="grid grid-cols-2 md:grid-cols-4 gap-3"></div></section> <!> <section class="bg-white rounded-xl shadow-sm border border-gray-200"><div class="px-5 py-4 border-b border-gray-200 flex items-center justify-between"><h2 class="text-lg font-semibold text-gray-900">📋 Aktuelle Anträge</h2> <a href="/vorlagen?typ=antrag" class="text-sm text-green-600 hover:text-green-800 font-medium">Alle →</a></div> <!></section>',1),dt=m('<div class="mb-6"><h1 class="text-2xl font-bold text-gray-900">🏛️ Dashboard</h1> <p class="text-gray-500 text-sm mt-1">Kommunale Anträge & Anfragen auf einen Blick</p></div> <!> <!>',1);function ft(he,pe){Fe(pe,!0);let y=M(null),Z=M(He([])),ae=M(!0),I=M("");const se=typeof window<"u"&&window.location.port==="5173"?`http://${window.location.hostname}:8099/api`:"/api",_e={umgesetzt:"bg-green-100 text-green-800 border-green-200",teilweise_umgesetzt:"bg-amber-100 text-amber-800 border-amber-200",versandet:"bg-gray-100 text-gray-700 border-gray-200",beschlossen:"bg-blue-100 text-blue-800 border-blue-200",abgelehnt:"bg-red-100 text-red-800 border-red-200",in_beratung:"bg-purple-100 text-purple-800 border-purple-200",angefragt:"bg-cyan-100 text-cyan-800 border-cyan-200",beantwortet:"bg-teal-100 text-teal-800 border-teal-200",verwiesen:"bg-indigo-100 text-indigo-800 border-indigo-200",offen:"bg-yellow-100 text-yellow-800 border-yellow-200"},fe={umgesetzt:"Umgesetzt",teilweise_umgesetzt:"Teilw. umgesetzt",versandet:"Versandet",beschlossen:"Beschlossen",abgelehnt:"Abgelehnt",in_beratung:"In Beratung",angefragt:"Angefragt",beantwortet:"Beantwortet",verwiesen:"Verwiesen",offen:"Offen"},we={antrag:"Anträge",anfrage:"Anfragen",bericht:"Berichte",beschlussvorlage:"Beschlussvorlagen",mitteilungsvorlage:"Mitteilungen",stellungnahme:"Stellungnahmen",sonstig:"Sonstige"},ye={antrag:"📋",anfrage:"❓",bericht:"📄",beschlussvorlage:"📑",mitteilungsvorlage:"📨",stellungnahme:"💬",sonstig:"📁"},q={umgesetzt:"bg-green-500",teilweise:"bg-amber-400",beschlossen:"bg-blue-400",versandet:"bg-gray-400",abgelehnt:"bg-red-400"};async function $e(){try{const[g,_]=await Promise.all([fetch(`${se}/stats/dashboard`),fetch(`${se}/vorlagen?typ=antrag&page_size=10`)]);if(g.ok?U(y,await g.json(),!0):U(I,`Dashboard-Stats fehler: ${g.status}`),_.ok){const S=await _.json();U(Z,S.items,!0)}}catch(g){U(I,`Fehler: ${g}`)}finally{U(ae,!1)}}$e();var ne=dt();Je("1uha8ag",g=>{Oe(()=>{Ze.title="Antragstracker Hagen"})});var oe=n(xe(ne),2);{var ze=g=>{var _=Ne(),S=a(_,!0);r(_),u(()=>o(S,e(I))),i(g,_)};p(oe,g=>{e(I)&&g(ze)})}var ke=n(oe,2);{var Ae=g=>{var _=Qe();i(g,_)},je=g=>{var _=lt(),S=xe(_),C=a(S),ie=a(C),Be=a(ie,!0);r(ie),O(2),r(C);var E=n(C,2),le=a(E),Se=a(le,!0);r(le),O(2),r(E);var G=n(E,2),de=a(G),Le=a(de,!0);r(de),O(2),r(G),O(2),r(S);var J=n(S,2),ve=n(a(J),2);te(ve,21,()=>e(y).vorlagen_nach_typ,re,(b,t)=>{var v=We(),c=a(v),$=a(c,!0);r(c);var x=n(c,2),z=a(x,!0);r(x);var k=n(x,2),B=a(k,!0);r(k),r(v),u(L=>{o($,ye[e(t).typ]||"📁"),o(z,L),o(B,we[e(t).typ]||e(t).typ)},[()=>e(t).anzahl.toLocaleString()]),f("click",v,()=>w(`/vorlagen?typ=${e(t).typ}`)),i(b,v)}),r(ve),r(J);var N=n(J,2),ge=n(a(N),2);te(ge,21,()=>e(y).ketten_nach_status,re,(b,t)=>{var v=Xe(),c=a(v),$=a(c,!0);r(c);var x=n(c,2),z=a(x,!0);r(x),r(v),u(k=>{K(v,1,`border rounded-lg p-4 text-left cursor-pointer hover:shadow-md transition-all ${(_e[e(t).status]||"bg-gray-50 text-gray-700 border-gray-200")??""}`),o($,k),o(z,fe[e(t).status]||e(t).status)},[()=>e(t).anzahl.toLocaleString()]),f("click",v,()=>w(`/ketten?status=${e(t).status}`)),i(b,v)}),r(ge),r(N);var be=n(N,2);{var Ve=b=>{const t=Ge(()=>e(y).umsetzungsquote);var v=st(),c=n(a(v),2),$=a(c);r(c);var x=n(c,2),z=a(x);{var k=l=>{var s=Ye(),A=a(s);{var j=d=>{var h=T();u(()=>o(h,e(t).umgesetzt)),i(d,h)};p(A,d=>{e(t).umgesetzt/e(t).total_bewertet>.05&&d(j)})}r(s),u(()=>{K(s,1,`${q.umgesetzt} hover:brightness-110 transition-all cursor-pointer flex items-center justify-center text-white text-xs font-medium`),D(s,`width: ${e(t).umgesetzt/e(t).total_bewertet*100}%`),V(s,"title",`Umgesetzt: ${e(t).umgesetzt??""}`)}),f("click",s,()=>w("/ketten?status=umgesetzt")),i(l,s)};p(z,l=>{e(t).umgesetzt>0&&l(k)})}var B=n(z,2);{var L=l=>{var s=et(),A=a(s);{var j=d=>{var h=T();u(()=>o(h,e(t).teilweise)),i(d,h)};p(A,d=>{e(t).teilweise/e(t).total_bewertet>.05&&d(j)})}r(s),u(()=>{K(s,1,`${q.teilweise} hover:brightness-110 transition-all cursor-pointer flex items-center justify-center text-white text-xs font-medium`),D(s,`width: ${e(t).teilweise/e(t).total_bewertet*100}%`),V(s,"title",`Teilweise umgesetzt: ${e(t).teilweise??""}`)}),f("click",s,()=>w("/ketten?status=teilweise_umgesetzt")),i(l,s)};p(B,l=>{e(t).teilweise>0&&l(L)})}var P=n(B,2);{var R=l=>{var s=tt(),A=a(s);{var j=d=>{var h=T();u(()=>o(h,e(t).beschlossen)),i(d,h)};p(A,d=>{e(t).beschlossen/e(t).total_bewertet>.05&&d(j)})}r(s),u(()=>{K(s,1,`${q.beschlossen} hover:brightness-110 transition-all cursor-pointer flex items-center justify-center text-white text-xs font-medium`),D(s,`width: ${e(t).beschlossen/e(t).total_bewertet*100}%`),V(s,"title",`Beschlossen: ${e(t).beschlossen??""}`)}),f("click",s,()=>w("/ketten?status=beschlossen")),i(l,s)};p(P,l=>{e(t).beschlossen>0&&l(R)})}var F=n(P,2);{var H=l=>{var s=rt(),A=a(s);{var j=d=>{var h=T();u(()=>o(h,e(t).versandet)),i(d,h)};p(A,d=>{e(t).versandet/e(t).total_bewertet>.05&&d(j)})}r(s),u(()=>{K(s,1,`${q.versandet} hover:brightness-110 transition-all cursor-pointer flex items-center justify-center text-white text-xs font-medium`),D(s,`width: ${e(t).versandet/e(t).total_bewertet*100}%`),V(s,"title",`Versandet: ${e(t).versandet??""}`)}),f("click",s,()=>w("/ketten?status=versandet")),i(l,s)};p(F,l=>{e(t).versandet>0&&l(H)})}var Q=n(F,2);{var Ue=l=>{var s=at(),A=a(s);{var j=d=>{var h=T();u(()=>o(h,e(t).abgelehnt)),i(d,h)};p(A,d=>{e(t).abgelehnt/e(t).total_bewertet>.05&&d(j)})}r(s),u(()=>{K(s,1,`${q.abgelehnt} hover:brightness-110 transition-all cursor-pointer flex items-center justify-center text-white text-xs font-medium`),D(s,`width: ${e(t).abgelehnt/e(t).total_bewertet*100}%`),V(s,"title",`Abgelehnt: ${e(t).abgelehnt??""}`)}),f("click",s,()=>w("/ketten?status=abgelehnt")),i(l,s)};p(Q,l=>{e(t).abgelehnt>0&&l(Ue)})}r(x);var ue=n(x,2),W=a(ue),De=n(a(W));r(W);var X=n(W,2),Ie=n(a(X));r(X);var Y=n(X,2),Ce=n(a(Y));r(Y);var ee=n(Y,2),Ee=n(a(ee));r(ee);var me=n(ee,2),Pe=n(a(me));r(me),r(ue),r(v),u(()=>{o($,`${e(t).total_bewertet??""} Ketten mit Endergebnis`),o(De,` Umgesetzt (${e(t).umgesetzt??""})`),o(Ie,` Teilweise (${e(t).teilweise??""})`),o(Ce,` Beschlossen (${e(t).beschlossen??""})`),o(Ee,` Versandet (${e(t).versandet??""})`),o(Pe,` Abgelehnt (${e(t).abgelehnt??""})`)}),i(b,v)};p(be,b=>{e(y).umsetzungsquote.total_bewertet>0&&b(Ve)})}var ce=n(be,2),Ke=n(a(ce),2);{var qe=b=>{var t=nt();i(b,t)},Te=b=>{var t=it();te(t,21,()=>e(Z),re,(v,c)=>{var $=ot(),x=a($),z=a(x),k=a(z),B=a(k),L=a(B),P=a(L,!0);r(L);var R=n(L,2),F=a(R,!0);r(R),r(B);var H=n(B,2),Q=a(H,!0);r(H),r(k),r(z),r(x),r($),u(()=>{V(x,"href",`/vorlagen/${e(c).id??""}`),o(P,e(c).aktenzeichen),o(F,e(c).datum_eingang),o(Q,e(c).betreff)}),i(v,$)}),r(t),i(b,t)};p(Ke,b=>{e(Z).length===0?b(qe):b(Te,-1)})}r(ce),u((b,t,v)=>{o(Be,b),o(Se,t),o(Le,v)},[()=>e(y).vorlagen_total.toLocaleString(),()=>e(y).ketten_total.toLocaleString(),()=>e(y).abstimmungen_total.toLocaleString()]),f("click",C,()=>w("/vorlagen")),f("click",E,()=>w("/ketten")),f("click",G,()=>w("/abstimmungen")),i(g,_)};p(ke,g=>{e(ae)?g(Ae):e(y)&&g(je,1)})}i(he,ne),Me()}Re(["click"]);export{ft as component};
|