fix: organize admin patches and profile menu layering
This commit is contained in:
+12
-12
@@ -1620,11 +1620,21 @@ def admin_patches_page(request: Request):
|
||||
"icon": icon,
|
||||
"description": description,
|
||||
"image_path": assets.get(code),
|
||||
"category": category,
|
||||
}
|
||||
for code, name, icon, _threshold, description, _category in BADGE_DEFINITIONS
|
||||
for code, name, icon, _threshold, description, category in BADGE_DEFINITIONS
|
||||
]
|
||||
patch_groups = [
|
||||
{
|
||||
"code": category,
|
||||
"label": label,
|
||||
"patches": [patch for patch in patches if patch["category"] == category],
|
||||
}
|
||||
for category, label in BADGE_CATEGORY_LABELS.items()
|
||||
if any(patch["category"] == category for patch in patches)
|
||||
]
|
||||
template = templates.get_template("admin_patches.html")
|
||||
return template.render(user=user, patches=patches)
|
||||
return template.render(user=user, patch_groups=patch_groups)
|
||||
|
||||
|
||||
@app.get("/admin/statistics", response_class=HTMLResponse)
|
||||
@@ -2479,15 +2489,6 @@ def render_profile(
|
||||
for code, name, icon, threshold, description, category in BADGE_DEFINITIONS
|
||||
]
|
||||
badges.sort(key=lambda badge: badge["sort_key"])
|
||||
badge_groups = [
|
||||
{
|
||||
"code": category,
|
||||
"label": label,
|
||||
"badges": [badge for badge in badges if badge["earned"] and badge["category"] == category],
|
||||
}
|
||||
for category, label in BADGE_CATEGORY_LABELS.items()
|
||||
if any(badge["earned"] and badge["category"] == category for badge in badges)
|
||||
]
|
||||
|
||||
template = templates.get_template("profile.html")
|
||||
return HTMLResponse(
|
||||
@@ -2496,7 +2497,6 @@ def render_profile(
|
||||
profile=profile,
|
||||
attended_count=attendance_stats["total"],
|
||||
badges=badges,
|
||||
badge_groups=badge_groups,
|
||||
is_own_profile=force_own or is_own_profile,
|
||||
can_view_details=can_view_details,
|
||||
friendship=friendship,
|
||||
|
||||
@@ -37,7 +37,7 @@ a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
header {
|
||||
body > header {
|
||||
background: rgba(8, 8, 8, 0.96);
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: sticky;
|
||||
@@ -413,7 +413,7 @@ body::after {
|
||||
mix-blend-mode: screen;
|
||||
}
|
||||
|
||||
header, main, .container { position: relative; z-index: 1; }
|
||||
.page-header, main, .container { position: relative; z-index: 1; }
|
||||
|
||||
h1, h2, h3, .logo, .page-title h1 {
|
||||
font-family: "Nimbus Sans Narrow", Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif;
|
||||
@@ -503,6 +503,7 @@ h1, .page-title h1 {
|
||||
.advanced-filter-fields label { display:grid; gap:5px; color:var(--muted); font-size:.85rem; }
|
||||
.advanced-filter-fields select { width:100%; }
|
||||
.clear-filters { grid-column:1 / -1; display:inline-flex; align-items:center; justify-content:center; padding:8px 12px; color:#fca5a5; border:1px solid var(--border); border-radius:9px; background:#171212; white-space:nowrap; justify-self:start; }
|
||||
.advanced-filters .clear-filters { margin:0 12px 12px; }
|
||||
.clear-filters:hover { border-color:#ef4444; color:#fff; }
|
||||
.ticket-button-container, .detail-actions { display:flex; flex-wrap:wrap; justify-content:center; gap:10px; margin-top:22px; }
|
||||
.calendar-export { display:flex; justify-content:center; margin-top:12px; }
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<style>
|
||||
.patch-admin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
|
||||
.patch-admin-groups { display:grid; gap:12px; }
|
||||
.patch-admin-group { padding:12px; background:#0b0b0b; border:1px solid var(--border); border-radius:10px; }
|
||||
.patch-admin-group > summary { color:#fca5a5; cursor:pointer; font-size:1.05rem; font-weight:700; }
|
||||
.patch-admin-group .patch-admin-grid { margin-top:14px; }
|
||||
.patch-admin-card { display: grid; gap: 12px; align-content: start; }
|
||||
.patch-preview { width: 140px; height: 140px; object-fit: contain; padding: 4px; background: #242424; border: 2px dashed #78716c; border-radius: 12px; }
|
||||
.patch-placeholder { display: grid; place-items: center; font-size: 2.5rem; }
|
||||
@@ -21,8 +25,12 @@
|
||||
<div class="page-title"><h1>🧵 Patch-Bilder</h1><p>Grafiken für die Patches auf der virtuellen Kutte verwalten.</p></div>
|
||||
{% set admin_section = 'patches' %}{% include '_admin_nav.html' %}
|
||||
<section class="admin-section">
|
||||
<div class="patch-admin-groups">
|
||||
{% for group in patch_groups %}
|
||||
<details class="patch-admin-group">
|
||||
<summary>{{ group.label }} · {{ group.patches|length }}</summary>
|
||||
<div class="patch-admin-grid">
|
||||
{% for patch in patches %}
|
||||
{% for patch in group.patches %}
|
||||
<article class="admin-row patch-admin-card">
|
||||
{% if patch.image_path %}<img class="patch-preview" src="{{ patch.image_path }}" alt="{{ patch.name }}">{% else %}<div class="patch-preview patch-placeholder">{{ patch.icon }}</div>{% endif %}
|
||||
<div><strong>{{ patch.name }}</strong><div class="admin-meta">{{ patch.description }} · {{ patch.code }}</div></div>
|
||||
@@ -35,6 +43,9 @@
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</details>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<script>
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
.kutte::before, .kutte::after { content: ""; position: absolute; top: 0; width: 30%; height: 62px; background: #111; border-bottom: 3px solid #404040; }
|
||||
.kutte::before { left: 0; border-radius: 24px 0 45% 0; }
|
||||
.kutte::after { right: 0; border-radius: 0 24px 0 45%; }
|
||||
.patch-categories { display:grid; gap:10px; }
|
||||
.patch-category { padding:10px 12px; background:rgba(5,5,5,.55); border:1px solid #44403c; border-radius:10px; }
|
||||
.patch-category > summary { color:#fca5a5; cursor:pointer; font-weight:700; }
|
||||
.patch-category .patch-grid { margin-top:14px; }
|
||||
.patch-grid { display: flex; flex-wrap: wrap; gap: 14px; justify-content: flex-start; align-items: flex-start; }
|
||||
.patch { padding: 5px; display: grid; place-items: center; text-align: center; background: #242424; border: 2px dashed #78716c; border-radius: 9px; color: #f8fafc; }
|
||||
.patch-image-frame { width: fit-content; height: fit-content; }
|
||||
@@ -126,14 +122,11 @@
|
||||
</section>
|
||||
<section class="badges-card">
|
||||
<h2>🥋 Virtuelle Kutte</h2>
|
||||
<p>Deine freigeschalteten Patches nach Kategorien. Besuchs-Patches werden jeweils durch die höchste Stufe ersetzt.</p>
|
||||
<p>Deine freigeschalteten Patches. Besuchs-Patches werden jeweils durch die höchste Stufe ersetzt.</p>
|
||||
<div class="kutte">
|
||||
<div class="patch-categories">
|
||||
{% for group in badge_groups %}
|
||||
<details class="patch-category">
|
||||
<summary>{{ group.label }} · {{ group.badges|length }}</summary>
|
||||
<div class="patch-grid">
|
||||
{% for badge in group.badges %}
|
||||
{% for badge in badges %}
|
||||
{% if badge.earned %}
|
||||
<div class="patch earned {% if badge.image_path %}patch-image-frame{% else %}patch-icon-frame{% endif %}" title="{{ badge.name }} – {{ badge.description }}" aria-label="{{ badge.name }}: {{ badge.description }}">
|
||||
{% if badge.image_path %}
|
||||
<img class="patch-image" src="{{ badge.image_path }}" alt="Patch {{ badge.name }}">
|
||||
@@ -141,12 +134,10 @@
|
||||
<span class="patch-icon">{{ badge.icon }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</details>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if not badge_groups %}
|
||||
{% if not profile.earned_codes %}
|
||||
<p>Noch keine Patches – dein erstes Konzert wartet!</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user