From dfffd07a96665f3aab3c9988b82c5941ff45b9f7 Mon Sep 17 00:00:00 2001 From: rene Date: Sun, 7 Jun 2026 20:36:19 +0200 Subject: [PATCH] =?UTF-8?q?Settings=20entr=C3=BCmpelt:=20Z=C3=BCchter-Bloc?= =?UTF-8?q?k=20komplett=20in=20den=20Z=C3=BCchter-Bereich=20umgezogen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rene: 'Dieser Bereich könnte auch in den Züchter-Bereich, dann ist alles sauber.' - Settings zeigt für verifizierte Züchter/Admins KEINE Züchter-Karte mehr — der Welten-Chip ist der Einstieg (wie beim Partner). Antrag/Prüfung/Abgelehnt bleiben in Settings (Nicht-Züchter sehen den Chip nicht). - Züchter-Bereich neu: KI-Züchter-Assistenz-Karte (5 Toggles, optimistisches Update + Revert), Status-Badge unterscheidet Admin/Züchter, Admin ohne Profil bekommt 'Profil anlegen' direkt im Hub. - Toter Code raus: _openBreederEditModal (75 Z., Settings-Doppel-Editor — breeder-editor-Seite ist der vollwertige), _kiToggleRow + 3 verwaiste Bindings aus settings.js. --- VERSION | 2 +- backend/static/index.html | 24 +- backend/static/js/app.js | 2 +- backend/static/js/pages/breeder-dashboard.js | 96 ++++++- backend/static/js/pages/settings.js | 276 +------------------ backend/static/landing.html | 2 +- backend/static/sw.js | 2 +- 7 files changed, 111 insertions(+), 293 deletions(-) diff --git a/VERSION b/VERSION index 1080e3f..d3e6945 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1268 \ No newline at end of file +1269 \ No newline at end of file diff --git a/backend/static/index.html b/backend/static/index.html index e5a2150..8c68db2 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -86,14 +86,14 @@ Ban Yaro - + - - - - - + + + + + @@ -620,11 +620,11 @@ - - - - - + + + + + @@ -634,7 +634,7 @@ - + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index a8bf102..3820110 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 = '1268'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '1269'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator) window.APP_VERSION = APP_VERSION; diff --git a/backend/static/js/pages/breeder-dashboard.js b/backend/static/js/pages/breeder-dashboard.js index ac66f30..d8788b6 100644 --- a/backend/static/js/pages/breeder-dashboard.js +++ b/backend/static/js/pages/breeder-dashboard.js @@ -7,9 +7,11 @@ window.Page_breeder_dashboard = (() => { let _container = null; + let _appState = null; - async function init(container) { + async function init(container, appState) { _container = container; + _appState = appState; _render(); await _load(); } @@ -73,15 +75,35 @@ window.Page_breeder_dashboard = (() => {
${UI.escape(profile?.zwingername || 'Noch kein Profil angelegt')}
${profile?.rasse_text ? `
${UI.escape(profile.rasse_text)}
` : ''} - ${UI.icon('check-circle')} Verifizierter Züchter + ${UI.icon('check-circle')} ${status?.rolle === 'admin' ? 'Admin — alle Züchter-Features' : 'Verifizierter Züchter'} - + ${profile + ? `` + : status?.rolle === 'admin' + ? `` : ''} + ${profile ? ` + +
+
KI-Züchter-Assistenz
+ ${_kiToggleRow('ki_zucht_wurfankuendigung', 'Wurfankündigungen schreiben')} + ${_kiToggleRow('ki_zucht_genetik', 'Genetik-Erklärung für Käufer')} + ${_kiToggleRow('ki_zucht_paarung', 'Paarungsanalyse')} + ${_kiToggleRow('ki_zucht_beschreibung', 'Hunde-Beschreibungen')} + ${_kiToggleRow('ki_zucht_jahresbericht', 'Jahresauswertung')} +
+ ${UI.icon('info')} Der Tierschutz-Check läuft immer automatisch und ist nicht abschaltbar. +
+
` : ''} +
@@ -129,10 +151,74 @@ window.Page_breeder_dashboard = (() => { `; } + // KI-Toggle-Zeile (aus settings.js umgezogen — Zustand kommt aus _appState.user) + function _kiToggleRow(key, label) { + const user = _appState?.user || {}; + const active = user[key] !== 0; + return ` +
+ ${UI.escape(label)} + +
`; + } + function _bindEvents(el) { el.querySelectorAll('[data-bd-nav]').forEach(btn => { btn.addEventListener('click', () => App.navigate(btn.dataset.bdNav)); }); + + // Admin ohne Profil: Züchterprofil anlegen + el.querySelector('#bd-admin-create')?.addEventListener('click', async e => { + const btn = e.currentTarget; + btn.disabled = true; + btn.textContent = 'Wird angelegt…'; + try { + await API.breeder.adminCreateProfile(); + UI.toast.success('Admin-Züchterprofil angelegt.'); + await _load(); + } catch (err) { + UI.toast.error(err.message || 'Fehler beim Anlegen.'); + btn.disabled = false; + btn.innerHTML = `${UI.icon('plus')} Profil anlegen`; + } + }); + + // KI-Toggles — optimistisches Update mit Revert bei Fehler + el.querySelectorAll('.bd-ki-toggle').forEach(btn => { + btn.addEventListener('click', async () => { + const key = btn.dataset.key; + const active = btn.dataset.active === '1'; + const newVal = active ? 0 : 1; + const thumb = btn.querySelector('.by-toggle-thumb'); + + btn.dataset.active = newVal ? '1' : '0'; + btn.style.background = newVal ? 'var(--c-primary)' : 'var(--c-border)'; + if (thumb) thumb.style.left = newVal ? '22px' : '2px'; + + try { + await API.patch('/profile', { [key]: newVal }); + if (_appState?.user) _appState.user[key] = newVal; + UI.toast.success(newVal ? 'KI-Feature aktiviert.' : 'KI-Feature deaktiviert.'); + } catch (err) { + btn.dataset.active = active ? '1' : '0'; + btn.style.background = active ? 'var(--c-primary)' : 'var(--c-border)'; + if (thumb) thumb.style.left = active ? '22px' : '2px'; + UI.toast.error(err?.message || 'Einstellung konnte nicht gespeichert werden.'); + } + }); + }); } return { init, refresh, onDogChange }; diff --git a/backend/static/js/pages/settings.js b/backend/static/js/pages/settings.js index f4bc01d..6a36d26 100644 --- a/backend/static/js/pages/settings.js +++ b/backend/static/js/pages/settings.js @@ -1664,29 +1664,6 @@ window.Page_settings = (() => { } - // ---------------------------------------------------------- - // KI-Toggle-Zeile (Hilfsfunktion für Züchter-Card) - // ---------------------------------------------------------- - function _kiToggleRow(key, label, user) { - const active = user[key] !== 0; - return ` -
- ${UI.escape(label)} - -
`; - } // ---------------------------------------------------------- // ZÜCHTER-CARD — asynchron laden und in Slot rendern @@ -1714,41 +1691,10 @@ window.Page_settings = (() => { let actionBlock = ''; if (rolle === 'breeder' || rolle === 'admin') { - statusBadge = ` - ${UI.icon('check-circle')} ${rolle === 'admin' ? 'Admin — alle Züchter-Features verfügbar' : 'Verifizierter Züchter'} - `; - actionBlock = ` -
- ${profile?.zwingername ? `
Zwinger: ${UI.escape(profile.zwingername)}
` : ''} - ${profile?.rasse_text ? `
Rasse: ${UI.escape(profile.rasse_text)}
` : ''} -
- ${rolle === 'breeder' && profile ? ` - ` : ''} - ${rolle === 'admin' && !profile ? ` - ` : ''} - ${rolle === 'admin' && profile ? ` - ` : ''} - ${profile ? ` -
-
- KI-Züchter-Assistenz -
- ${_kiToggleRow('ki_zucht_wurfankuendigung', 'Wurfankündigungen schreiben', _appState.user || {})} - ${_kiToggleRow('ki_zucht_genetik', 'Genetik-Erklärung für Käufer', _appState.user || {})} - ${_kiToggleRow('ki_zucht_paarung', 'Paarungsanalyse', _appState.user || {})} - ${_kiToggleRow('ki_zucht_beschreibung', 'Hunde-Beschreibungen', _appState.user || {})} - ${_kiToggleRow('ki_zucht_jahresbericht', 'Jahresauswertung', _appState.user || {})} -
- ${UI.icon('info')} Der Tierschutz-Check läuft immer automatisch und ist nicht abschaltbar. -
-
` : ''}`; + // Verifizierte Züchter/Admins: alles Inhaltliche (Profil, KI-Assistenz, + // Würfe, Zuchtkartei) lebt im Züchter-Bereich — hier nur der Verweis. + slot.innerHTML = ''; + return; } else if (breeder_status === 'pending') { statusBadge = ` ${UI.icon('hourglass')} Antrag wird geprüft @@ -1784,221 +1730,7 @@ window.Page_settings = (() => { // Button-Handler binden slot.querySelector('#breeder-reapply-btn')?.addEventListener('click', () => _showUpgradeModal('breeder')); - slot.querySelector('#breeder-edit-profile-btn')?.addEventListener('click', () => - _openBreederEditModal(profile) - ); - slot.querySelector('#breeder-admin-create-btn')?.addEventListener('click', async (e) => { - const btn = e.currentTarget; - btn.disabled = true; - btn.textContent = 'Wird angelegt…'; - try { - await API.breeder.adminCreateProfile(); - UI.toast.success('Admin-Züchterprofil angelegt. Bitte Seite neu laden.'); - _loadBreederCard(); - } catch (err) { - UI.toast.error(err.message || 'Fehler beim Anlegen.'); - btn.disabled = false; - btn.innerHTML = `${UI.icon('plus')} Admin-Züchterprofil anlegen`; - } - }); - - // KI-Toggle-Handler - slot.querySelectorAll('.ki-toggle-btn').forEach(btn => { - btn.addEventListener('click', async () => { - const key = btn.dataset.key; - const active = btn.dataset.active === '1'; - const newVal = active ? 0 : 1; - - // Optimistisches UI-Update - btn.dataset.active = newVal ? '1' : '0'; - btn.style.background = newVal ? 'var(--c-primary)' : 'var(--c-border)'; - const thumb = btn.querySelector('.by-toggle-thumb'); - if (thumb) thumb.style.left = newVal ? '22px' : '2px'; - - try { - const updated = await API.patch('/profile', { [key]: newVal }); - if (_appState?.user) _appState.user[key] = newVal; - UI.toast.success(newVal ? 'KI-Feature aktiviert.' : 'KI-Feature deaktiviert.'); - } catch (err) { - // Revert - btn.dataset.active = active ? '1' : '0'; - btn.style.background = active ? 'var(--c-primary)' : 'var(--c-border)'; - if (thumb) thumb.style.left = active ? '22px' : '2px'; - UI.toast.error(err?.message || 'Einstellung konnte nicht gespeichert werden.'); - } - }); - }); - } - - // ---------------------------------------------------------- - // ZÜCHTER-PROFIL BEARBEITEN MODAL - // ---------------------------------------------------------- - function _openBreederEditModal(profile) { - const inputStyle = `width:100%;box-sizing:border-box;padding:var(--space-2) var(--space-3); - border:1.5px solid var(--c-border);border-radius:var(--radius-md); - font-size:var(--text-sm);font-family:inherit; - background:var(--c-surface);color:var(--c-text)`; - - UI.modal.open({ - title: `${UI.icon('pencil-simple')} Züchter-Profil bearbeiten`, - body: ` -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
`, - footer: ` -
- - -
`, - }); - - document.getElementById('breeder-edit-form')?.addEventListener('submit', async e => { - e.preventDefault(); - const btn = document.getElementById('breeder-edit-submit'); - await UI.asyncButton(btn, async () => { - const form = e.target; - const data = { - zwingername: form.zwingername.value.trim() || undefined, - rasse_text: form.rasse_text.value.trim() || undefined, - verein: form.verein.value.trim() || undefined, - stadt: form.stadt.value.trim() || undefined, - vdh_mitglied: form.vdh_mitglied.checked ? 1 : 0, - website: form.website.value.trim() || undefined, - beschreibung: form.beschreibung.value.trim() || undefined, - }; - await API.breeder.updateProfile(data); - UI.modal.close?.(); - UI.toast.success('Profil aktualisiert.'); - _loadBreederCard(); - }); - }); - } - - // ---------------------------------------------------------- - // ZÜCHTER-ANTRAG MODAL - // ---------------------------------------------------------- - function _openBreederApplyModal() { - const inputStyle = `width:100%;box-sizing:border-box;padding:var(--space-2) var(--space-3); - border:1.5px solid var(--c-border);border-radius:var(--radius-md); - font-size:var(--text-sm);font-family:inherit; - background:var(--c-surface);color:var(--c-text)`; - - UI.modal.open({ - title: `${UI.icon('certificate')} Züchter-Antrag stellen`, - body: ` -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- Zuchtbuch-Eintrag, Vereinsmitgliedschaft o.ä. (PDF, JPG, PNG, WebP) -
-
-
- `, - footer: ` -
- - -
- `, - }); document.getElementById('breeder-apply-form')?.addEventListener('submit', async e => { e.preventDefault(); diff --git a/backend/static/landing.html b/backend/static/landing.html index fc24dda..891c8f2 100644 --- a/backend/static/landing.html +++ b/backend/static/landing.html @@ -4,7 +4,7 @@ - + Ban Yaro — Die Hunde-App für Deutschland, Österreich & Schweiz diff --git a/backend/static/sw.js b/backend/static/sw.js index e299457..fd4c73b 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -4,7 +4,7 @@ ============================================================ */ // ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab -const VER = '1268'; +const VER = '1269'; const CACHE_VERSION = `by-v${VER}`; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten