Slika 3: Savez 3 KPI (ukupna potpora, sportaša, dokumenata)
Endpoint:
- /api/v2/savez/{id}/kpi (ukupna_potpora, broj_sportasa, broj_klubova, najvisi_rang, broj_dokumenata, broj_manifestacija)
Frontend sport2.html:
- loadSavezKpi() function
- Auto-call after openSavez(id) panel render
This commit is contained in:
+23
-1
@@ -2531,7 +2531,9 @@ def sportasi_filtered(sport: str = None, klub_id: int = None, kategorija: str =
|
||||
rows = fetch(f"""
|
||||
SELECT c.id, c.ime, c.prezime, c.spol, c.datum_rodenja, c.godina_rodenja,
|
||||
c.kategorija, c.pozicija, c.sport, c.klub_id, k.naziv AS klub_naziv,
|
||||
c.hns_igrac_id, c.source, c.source_url
|
||||
c.hns_igrac_id, c.source, c.source_url, c.slika_url,
|
||||
c.reprezentativac, c.kategoriziran, c.stipendiran, c.aktivan,
|
||||
c.hoo_kategorija, c.broj_dresa
|
||||
FROM pgz_sport.clanovi c
|
||||
LEFT JOIN pgz_sport.klubovi k ON k.id = c.klub_id
|
||||
{where_sql}
|
||||
@@ -2762,6 +2764,26 @@ def export_klubovi_roster_xlsx(klub_id: Optional[int] = None, sport: Optional[st
|
||||
)
|
||||
|
||||
|
||||
|
||||
@app.get("/api/v2/savez/{savez_id}/kpi")
|
||||
def savez_kpi(savez_id: int, godina: int = None):
|
||||
"""KPI metrike za savez: ukupna potpora, broj sportaša, najviši rang."""
|
||||
rows = fetch("""
|
||||
SELECT
|
||||
(SELECT COALESCE(SUM(pn.iznos), 0)::numeric(12,2) FROM pgz_sport.potpore_nositelji pn
|
||||
JOIN pgz_sport.klubovi k ON k.id = pn.klub_id
|
||||
WHERE k.savez_id = %s) AS ukupna_potpora,
|
||||
(SELECT count(DISTINCT c.id) FROM pgz_sport.clanovi c
|
||||
JOIN pgz_sport.klubovi k ON k.id = c.klub_id
|
||||
WHERE k.savez_id = %s AND c.aktivan = true) AS broj_sportasa,
|
||||
(SELECT count(DISTINCT k.id) FROM pgz_sport.klubovi k WHERE k.savez_id = %s AND k.aktivan = true) AS broj_klubova,
|
||||
(SELECT COALESCE(MIN(k.razina), 'n/a') FROM pgz_sport.klubovi k
|
||||
WHERE k.savez_id = %s AND k.razina IS NOT NULL AND k.razina <> '') AS najvisi_rang,
|
||||
(SELECT count(*) FROM pgz_sport.dokumenti d WHERE d.savez_id = %s) AS broj_dokumenata,
|
||||
(SELECT count(*) FROM pgz_sport.manifestacije m WHERE m.savez_id = %s) AS broj_manifestacija
|
||||
""", (savez_id, savez_id, savez_id, savez_id, savez_id, savez_id))
|
||||
return rows[0] if rows else {}
|
||||
|
||||
@app.get("/")
|
||||
def root(request: Request):
|
||||
host = request.headers.get("host", "")
|
||||
|
||||
@@ -5990,23 +5990,23 @@ def manifestacije_meta():
|
||||
@router.get("/manifestacije")
|
||||
def manifestacije_list(mjesto: str = None, razina: str = None, organizator: str = None, q: str = None, limit: int = 200):
|
||||
"""Lista manifestacija s filterima."""
|
||||
where = ["aktivna = true"]
|
||||
where = ["m.aktivna = true"]
|
||||
params = []
|
||||
if mjesto:
|
||||
where.append("mjesto = %s")
|
||||
where.append("m.mjesto = %s")
|
||||
params.append(mjesto)
|
||||
if razina:
|
||||
where.append("razina = %s")
|
||||
where.append("m.razina = %s")
|
||||
params.append(razina)
|
||||
if organizator:
|
||||
where.append("organizator ILIKE %s")
|
||||
where.append("m.organizator ILIKE %s")
|
||||
params.append(f"%{organizator}%")
|
||||
if q:
|
||||
where.append("(naziv ILIKE %s OR napomena ILIKE %s)")
|
||||
where.append("(m.naziv ILIKE %s OR m.napomena ILIKE %s)")
|
||||
params.extend([f"%{q}%", f"%{q}%"])
|
||||
|
||||
|
||||
rows = db_query(f"""
|
||||
SELECT m.id, m.naziv, m.mjesto, m.organizator, m.razina, m.broj_ucesnika,
|
||||
SELECT m.id, m.naziv, m.mjesto, m.organizator, m.razina, m.broj_ucesnika,
|
||||
m.godina_od, m.spol_kategorija, m.napomena, m.source_url,
|
||||
s.naziv AS savez_naziv, s.id AS savez_id
|
||||
FROM pgz_sport.manifestacije m
|
||||
|
||||
@@ -1466,6 +1466,7 @@ function renderSaveziTable(rows){
|
||||
|
||||
async function openSavez(id){
|
||||
openPanel('Savez', '<div class="loading">Učitavanje saveza…</div>');
|
||||
setTimeout(() => loadSavezKpi(id), 100);
|
||||
const s = await api('/savezi/'+id);
|
||||
if(!s || s.detail){
|
||||
openPanel('Savez', '<div class="empty">Savez nije pronađen</div>');
|
||||
|
||||
Reference in New Issue
Block a user