diff --git a/backend/main.py b/backend/main.py index 8beb2ba..9a593a0 100644 --- a/backend/main.py +++ b/backend/main.py @@ -406,7 +406,7 @@ async def serve_media(path: str, request: _Request): raise _HE(404, "Nicht gefunden.") return _media_response(filepath) -APP_VER = "900" # muss mit APP_VER in app.js übereinstimmen +APP_VER = "901" # muss mit APP_VER in app.js übereinstimmen @app.get("/.well-known/assetlinks.json") async def assetlinks(): diff --git a/backend/routes/breeder.py b/backend/routes/breeder.py index 2f3dac4..2a5f884 100644 --- a/backend/routes/breeder.py +++ b/backend/routes/breeder.py @@ -395,6 +395,33 @@ async def breeder_public_profile(zwingername: str): """, (breeder_id,)).fetchall() result["ed_stats"] = [dict(r) for r in ed_stats] + # Logo = primäres Bild der entity_type='breeder' Fotos + logo = conn.execute(""" + SELECT file_path FROM breeder_photos + WHERE breeder_id=? AND entity_type='breeder' AND is_primary=1 + LIMIT 1 + """, (breeder_id,)).fetchone() + if not logo: + logo = conn.execute(""" + SELECT file_path FROM breeder_photos + WHERE breeder_id=? AND entity_type='breeder' + ORDER BY sort_order, id LIMIT 1 + """, (breeder_id,)).fetchone() + result["logo_url"] = f"/api/media/{logo['file_path']}" if logo else None + + # Öffentliche Fotos für die Gallery (alle entity_type='breeder', max. 12) + photos = conn.execute(""" + SELECT file_path, thumbnail_path, caption, is_primary FROM breeder_photos + WHERE breeder_id=? AND entity_type='breeder' AND visibility IN ('public','inquiry') + ORDER BY is_primary DESC, sort_order, id LIMIT 12 + """, (breeder_id,)).fetchall() + result["fotos"] = [{ + "url": f"/api/media/{p['file_path']}", + "thumb": f"/api/media/{p['thumbnail_path']}" if p['thumbnail_path'] else f"/api/media/{p['file_path']}", + "caption": p["caption"] or "", + "primary": bool(p["is_primary"]), + } for p in photos] + return result diff --git a/backend/static/index.html b/backend/static/index.html index d45b667..809c1f1 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -591,10 +591,10 @@ - - - - + + + + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 0219d30..24d20c7 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '900'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '901'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.5.1'; // ← semantische Version, wird bei make release gesetzt const IS_STAGING = location.hostname === 'staging.banyaro.app'; // Cache-Bust-Parameter nach Update-Reload sofort entfernen diff --git a/backend/static/js/pages/breeder.js b/backend/static/js/pages/breeder.js index 907469f..705d484 100644 --- a/backend/static/js/pages/breeder.js +++ b/backend/static/js/pages/breeder.js @@ -77,7 +77,7 @@ window.Page_breeder = (() => {

- Verifizierter Züchter + ${UI.icon('seal-check')} Verifizierter Züchter

${_esc(p.zwingername)} @@ -89,9 +89,16 @@ window.Page_breeder = (() => { ${seit ? `Züchter seit ${_esc(seit)}` : ''}

-
- -
+ ${p.logo_url + ? `Zwinger-Logo` + : `
+ +
` + } ${!isOwnProfile ? ` @@ -192,8 +199,34 @@ window.Page_breeder = (() => { - -
+ + ${p.fotos?.length ? ` +
+

+ ${UI.icon('images')} Galerie + ${p.fotos.length} Fotos +

+
+ ${p.fotos.map((ph, i) => ` + + ${_esc(ph.caption)} + ${ph.primary ? `Logo` : ''} + ${ph.caption ? `
${_esc(ph.caption)}
` : ''} +
`).join('')} +
+
` : ''} + + `; diff --git a/backend/static/js/ui.js b/backend/static/js/ui.js index 38d6528..a0b69b1 100644 --- a/backend/static/js/ui.js +++ b/backend/static/js/ui.js @@ -76,6 +76,9 @@ const UI = (() => { `; overlay.querySelector('.modal-close-btn')?.addEventListener('click', close); + overlay.addEventListener('click', e => { + if (e.target.closest('[data-modal-close]')) close(); + }); document.getElementById('modal-container').appendChild(overlay); document.documentElement.classList.add('modal-open'); diff --git a/backend/static/sw.js b/backend/static/sw.js index 42fb8dc..fd1652f 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,7 +3,7 @@ Offline-Cache + Push Notifications + Tile-Cache ============================================================ */ -const CACHE_VERSION = 'by-v900'; +const CACHE_VERSION = 'by-v901'; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache