🔽 Frontend-Filter: Dropdown nach Hallen (H1-H7) statt Einzelstände + .gitignore gehärtet
This commit is contained in:
+35
-6
@@ -1,8 +1,37 @@
|
|||||||
|
# Secrets
|
||||||
.env
|
.env
|
||||||
*.pyc
|
*.env
|
||||||
__pycache__/
|
.env.bak
|
||||||
media/
|
|
||||||
*.db
|
|
||||||
app.py.bak*
|
|
||||||
*.bak
|
|
||||||
.cloudflare_token
|
.cloudflare_token
|
||||||
|
credentials.json
|
||||||
|
*.key
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*.egg-info/
|
||||||
|
*.bak
|
||||||
|
*.bak2
|
||||||
|
*.bak3
|
||||||
|
*.bak4
|
||||||
|
*.bak5
|
||||||
|
venv/
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
# Database
|
||||||
|
*.db
|
||||||
|
*.db-journal
|
||||||
|
*.db-wal
|
||||||
|
|
||||||
|
# Media (too large, stored on disk)
|
||||||
|
media/uploads/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|||||||
@@ -1486,10 +1486,17 @@ def public_frontend():
|
|||||||
query += " ORDER BY published_at DESC LIMIT 50"
|
query += " ORDER BY published_at DESC LIMIT 50"
|
||||||
rows = db.execute(query, params).fetchall()
|
rows = db.execute(query, params).fetchall()
|
||||||
|
|
||||||
# Get available filter values
|
# Get available filter values — group by hall number (H1-H7)
|
||||||
hallen = [r[0] for r in db.execute(
|
hallen = []
|
||||||
|
hall_rows = db.execute(
|
||||||
"SELECT DISTINCT halle FROM submissions WHERE halle IS NOT NULL AND status='published' ORDER BY halle"
|
"SELECT DISTINCT halle FROM submissions WHERE halle IS NOT NULL AND status='published' ORDER BY halle"
|
||||||
).fetchall()]
|
).fetchall()
|
||||||
|
seen = set()
|
||||||
|
for r in hall_rows:
|
||||||
|
hnum = r[0][:2] if r[0] else ""
|
||||||
|
if hnum and hnum[0] == 'H' and hnum[1:].isdigit() and hnum not in seen:
|
||||||
|
seen.add(hnum)
|
||||||
|
hallen.append(hnum)
|
||||||
categories = [r[0] for r in db.execute(
|
categories = [r[0] for r in db.execute(
|
||||||
"SELECT DISTINCT category FROM submissions WHERE category IS NOT NULL AND status='published' ORDER BY category"
|
"SELECT DISTINCT category FROM submissions WHERE category IS NOT NULL AND status='published' ORDER BY category"
|
||||||
).fetchall()]
|
).fetchall()]
|
||||||
@@ -1515,27 +1522,30 @@ def public_frontend():
|
|||||||
if not rows:
|
if not rows:
|
||||||
return empty_state
|
return empty_state
|
||||||
|
|
||||||
# Build filter bar HTML
|
# Build filter bar HTML — hallen as dropdown
|
||||||
filter_html = '<div class="frontend-filter"><span class="filter-label">📍 Halle:</span> '
|
filter_html = '<div class="frontend-filter"><span class="filter-label">📍 Halle:</span> '
|
||||||
filter_html += f'<a href="/{"?cat="+cat_filter if cat_filter else ""}" class="filter-pill{"" if halle_filter else " active"}">Alle</a> '
|
filter_html += '<form method="get" class="filter-form-inline" style="display:inline;">'
|
||||||
for h in hallen:
|
if cat_filter:
|
||||||
active = " active" if halle_filter and h.startswith(halle_filter) else ""
|
filter_html += f'<input type="hidden" name="cat" value="{cat_filter}">'
|
||||||
url = f"/?halle={h}"
|
filter_html += '<select name="halle" onchange="this.form.submit()" class="hall-select">'
|
||||||
if cat_filter:
|
filter_html += f'<option value="" {"selected" if not halle_filter else ""}>Alle Hallen</option>'
|
||||||
url += f"&cat={cat_filter}"
|
for hnum in hallen:
|
||||||
filter_html += f'<a href="{url}" class="filter-pill{active}">{h}</a> '
|
selected = " selected" if halle_filter == hnum else ""
|
||||||
|
filter_html += f'<option value="{hnum}"{selected}>Halle {hnum[1:]}</option>'
|
||||||
|
filter_html += '</select></form> '
|
||||||
if categories:
|
if categories:
|
||||||
filter_html += '<span class="filter-label" style="margin-left:0.8rem;">📂 Kategorie:</span> '
|
filter_html += '<span class="filter-label" style="margin-left:0.8rem;">📂 Kategorie:</span> '
|
||||||
url = "/"
|
filter_html += '<form method="get" class="filter-form-inline" style="display:inline;">'
|
||||||
if halle_filter:
|
if halle_filter:
|
||||||
url += f"?halle={halle_filter}"
|
filter_html += f'<input type="hidden" name="halle" value="{halle_filter}">'
|
||||||
filter_html += f'<a href="{url}" class="filter-pill{" active" if not cat_filter else ""}">Alle</a> '
|
filter_html += '<select name="cat" onchange="this.form.submit()" class="hall-select">'
|
||||||
|
filter_html += f'<option value="" {"selected" if not cat_filter else ""}>Alle Kategorien</option>'
|
||||||
for c in categories:
|
for c in categories:
|
||||||
active = " active" if cat_filter == c else ""
|
selected = " selected" if cat_filter == c else ""
|
||||||
url = f"/?cat={c}"
|
filter_html += f'<option value="{c}"{selected}>{c}</option>'
|
||||||
if halle_filter:
|
filter_html += '</select></form> '
|
||||||
url += f"&halle={halle_filter}"
|
if halle_filter or cat_filter:
|
||||||
filter_html += f'<a href="{url}" class="filter-pill{active}">{c}</a> '
|
filter_html += '<a href="/" class="filter-reset">✕ Filter zurücksetzen</a>'
|
||||||
filter_html += "</div>"
|
filter_html += "</div>"
|
||||||
|
|
||||||
cards = ""
|
cards = ""
|
||||||
@@ -1699,6 +1709,9 @@ def public_frontend():
|
|||||||
.frontend-filter a.filter-pill:hover { border-color:#20228a; color:#20228a; }
|
.frontend-filter a.filter-pill:hover { border-color:#20228a; color:#20228a; }
|
||||||
.frontend-filter a.filter-pill.active { background:#20228a; color:#fff; border-color:#20228a; font-weight:700; }
|
.frontend-filter a.filter-pill.active { background:#20228a; color:#fff; border-color:#20228a; font-weight:700; }
|
||||||
.frontend-filter a.filter-reset { color:#999; font-size:0.75rem; }
|
.frontend-filter a.filter-reset { color:#999; font-size:0.75rem; }
|
||||||
|
.hall-select { appearance:none; -webkit-appearance:none; background:#fff; color:#20228a; border:1.5px solid #ddd; border-radius:999px; padding:0.35rem 2rem 0.35rem 0.9rem; font-size:0.78rem; font-weight:600; font-family:inherit; cursor:pointer; transition:all 0.15s; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2320228a' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'%3E%3C/path%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 0.55rem center; }
|
||||||
|
.hall-select:hover { border-color:#20228a; }
|
||||||
|
.hall-select:focus { outline:none; border-color:#20228a; box-shadow:0 0 0 3px rgba(32,34,138,0.12); }
|
||||||
.story-card audio { width:100%; margin-top:0.8rem; }
|
.story-card audio { width:100%; margin-top:0.8rem; }
|
||||||
.story-card img:not(:first-child) { height:auto; max-height:300px; object-fit:contain; margin-top:0.8rem; border-radius:8px; }
|
.story-card img:not(:first-child) { height:auto; max-height:300px; object-fit:contain; margin-top:0.8rem; border-radius:8px; }
|
||||||
.story-card video:not(:first-child) { height:auto; max-height:300px; margin-top:0.8rem; border-radius:8px; }
|
.story-card video:not(:first-child) { height:auto; max-height:300px; margin-top:0.8rem; border-radius:8px; }
|
||||||
|
|||||||
Reference in New Issue
Block a user