From d5f09cd16b2c1d35c45161528a4f36dd6201b092 Mon Sep 17 00:00:00 2001 From: rene Date: Fri, 17 Apr 2026 15:29:57 +0200 Subject: [PATCH] Fix: UI.escape definieren + Transponder-Karte immer im Profil anzeigen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UI.escape() fehlte im Public-API von ui.js (crash nach Profil speichern) - Chip-Nr.-Karte im Hunde-Profil immer sichtbar, auch ohne Wert - "Eintragen"-Button öffnet Inline-Edit-Modal direkt im Profil - SW-Cache by-v143 --- backend/static/js/pages/dog-profile.js | 56 ++++++++++++++++++++++---- backend/static/js/ui.js | 10 +++++ backend/static/sw.js | 2 +- 3 files changed, 60 insertions(+), 8 deletions(-) diff --git a/backend/static/js/pages/dog-profile.js b/backend/static/js/pages/dog-profile.js index fdf69ca..6d72005 100644 --- a/backend/static/js/pages/dog-profile.js +++ b/backend/static/js/pages/dog-profile.js @@ -133,14 +133,19 @@ window.Page_dog_profile = (() => {
${dog.gewicht_kg} kg
` : ''} - ${dog.chip_nr ? ` -
-
Chip-Nr.
-
${_esc(dog.chip_nr)}
+
+
+ Transponder
- ` : ''} + ${dog.chip_nr + ? `
${_esc(dog.chip_nr)}
` + : `
nicht eingetragen + +
` + } +
${dog.bio ? ` @@ -230,9 +235,46 @@ window.Page_dog_profile = (() => { } }); + // Transponder "Eintragen"-Button + document.getElementById('dp-chip-edit-btn')?.addEventListener('click', () => { + _showChipEdit(dog); + }); + // Edit- und Add-Klicks laufen über Event-Delegation in init() — keine direkten Listener nötig. } + function _showChipEdit(dog) { + UI.modal.open({ + title: 'Transpondernummer', + body: ` +
+ + +
`, + footer: ` + + `, + }); + document.getElementById('chip-edit-save-btn').addEventListener('click', async () => { + const nr = document.getElementById('chip-edit-input').value.trim() || null; + const btn = document.getElementById('chip-edit-save-btn'); + UI.setLoading(btn, true); + try { + await API.dogs.update(dog.id, { chip_nr: nr }); + dog.chip_nr = nr; + _appState.activeDog = { ..._appState.activeDog, chip_nr: nr }; + _appState.dogs = _appState.dogs.map(d => d.id === dog.id ? _appState.activeDog : d); + UI.modal.close(); + UI.toast.success('Transpondernummer gespeichert.'); + _renderProfile(_appState.activeDog); + } catch (e) { + UI.setLoading(btn, false); + UI.toast.error('Fehler beim Speichern.'); + } + }); + } + // ---------------------------------------------------------- // NEU ANLEGEN (direkt auf der Seite, kein Modal) // ---------------------------------------------------------- diff --git a/backend/static/js/ui.js b/backend/static/js/ui.js index 1b6cf14..22f66d0 100644 --- a/backend/static/js/ui.js +++ b/backend/static/js/ui.js @@ -259,6 +259,15 @@ const UI = (() => { `; } + function escape(str) { + if (!str) return ''; + return String(str) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); + } + // Öffentliche API return { toast, modal, @@ -267,6 +276,7 @@ const UI = (() => { emptyState, time, setupPhotoPreview, scrollTop, skeleton, icon: _svgIcon, + escape, }; })(); diff --git a/backend/static/sw.js b/backend/static/sw.js index 223defb..aec02ba 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-v142'; +const CACHE_VERSION = 'by-v143'; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten