diff --git a/backend/static/css/components.css b/backend/static/css/components.css index 750fc4a..00aa066 100644 --- a/backend/static/css/components.css +++ b/backend/static/css/components.css @@ -1219,3 +1219,84 @@ textarea.form-control { color: var(--c-primary-dark); font-weight: var(--weight-semibold); } + +/* ============================================================ + TAGEBUCH — HUNDE-PICKER (Einstiegsseite bei mehreren Hunden) + ============================================================ */ + +.diary-picker-wrap { + display: flex; + flex-direction: column; + align-items: center; + padding: var(--space-8) var(--space-4) var(--space-4); + gap: var(--space-5); +} + +.diary-picker-hint { + font-size: var(--text-lg); + font-weight: var(--weight-semibold); + color: var(--c-text-secondary); + margin: 0; +} + +.diary-picker-grid { + display: flex; + flex-wrap: wrap; + gap: var(--space-4); + justify-content: center; +} + +.diary-picker-card { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-2); + padding: var(--space-4); + width: 140px; + background: var(--c-surface); + border: 2px solid var(--c-border); + border-radius: var(--radius-lg); + cursor: pointer; + transition: transform var(--transition-fast), box-shadow var(--transition-fast), + border-color var(--transition-fast); + touch-action: manipulation; +} +.diary-picker-card:active { + transform: scale(0.96); +} +.diary-picker-card--active { + border-color: var(--c-primary); + box-shadow: 0 0 0 3px var(--c-primary-subtle); +} + +.diary-picker-av { + width: 88px; + height: 88px; + border-radius: 50%; + overflow: hidden; + background: var(--c-surface-2); + display: flex; + align-items: center; + justify-content: center; + border: 3px solid var(--c-border); +} +.diary-picker-card--active .diary-picker-av { + border-color: var(--c-primary); +} +.diary-picker-av img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.diary-picker-name { + font-weight: var(--weight-semibold); + font-size: var(--text-base); + color: var(--c-text); + text-align: center; +} +.diary-picker-rasse { + font-size: var(--text-xs); + color: var(--c-text-secondary); + text-align: center; +} diff --git a/backend/static/js/app.js b/backend/static/js/app.js index b72fc72..116a916 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -394,7 +394,7 @@ const App = (() => { // ÖFFENTLICHE API // (andere Module können App.state, App.navigate etc. nutzen) // ---------------------------------------------------------- - return { init, navigate, state, renderDogSwitcher: _renderDogSwitcher }; + return { init, navigate, state, setActiveDog, renderDogSwitcher: _renderDogSwitcher }; })(); diff --git a/backend/static/js/pages/diary.js b/backend/static/js/pages/diary.js index 38933e8..356d87c 100644 --- a/backend/static/js/pages/diary.js +++ b/backend/static/js/pages/diary.js @@ -34,28 +34,29 @@ window.Page_diary = (() => { } // ---------------------------------------------------------- - // REFRESH — erneuter Navigations-Aufruf + // REFRESH — erneuter Navigations-Aufruf (Tap auf Tab) // ---------------------------------------------------------- async function refresh() { if (!_appState.activeDog) return; - // Wenn vorher "kein Hund"-Zustand: #diary-list existiert nicht → voll neu rendern - if (!_container.querySelector('#diary-list')) { - await _render(); + // Mehrere Hunde → Picker zeigen (User kann Hund wählen) + if (_appState.dogs.length > 1) { + _renderDogPicker(); return; } + // Einzelner Hund → Diary direkt neu laden _offset = 0; _entries = []; - await _load(); - _renderList(); + await _renderDiary(); } // ---------------------------------------------------------- - // ON DOG CHANGE + // ON DOG CHANGE — vom Header-Switcher ausgelöst // ---------------------------------------------------------- async function onDogChange(dog) { _offset = 0; _entries = []; - await _render(); + // Direkt Diary laden — Hund wurde bereits extern gewählt + await _renderDiary(); } // ---------------------------------------------------------- @@ -66,7 +67,7 @@ window.Page_diary = (() => { } // ---------------------------------------------------------- - // RENDER — Hauptstruktur + // RENDER — Einstieg: Picker bei mehreren Hunden, sonst direkt // ---------------------------------------------------------- async function _render() { if (!_appState.activeDog) { @@ -81,6 +82,53 @@ window.Page_diary = (() => { return; } + if (_appState.dogs.length > 1) { + _renderDogPicker(); + } else { + await _renderDiary(); + } + } + + // ---------------------------------------------------------- + // HUNDE-PICKER — Einstiegsseite bei mehreren Hunden + // ---------------------------------------------------------- + function _renderDogPicker() { + const activeDogId = _appState.activeDog?.id; + + const cards = _appState.dogs.map(dog => { + const isActive = dog.id === activeDogId; + const av = dog.foto_url + ? `${_escape(dog.name)}` + : `🐕`; + return ` +
+
${av}
+
${_escape(dog.name)}
+ ${dog.rasse ? `
${_escape(dog.rasse)}
` : ''} +
`; + }).join(''); + + _container.innerHTML = ` +
+

Wessen Tagebuch?

+
${cards}
+
`; + + _container.querySelectorAll('.diary-picker-card').forEach(el => { + el.addEventListener('click', async () => { + const id = parseInt(el.dataset.dogId); + App.setActiveDog(id); + // onDogChange() wird durch setActiveDog → _notifyDogChange() aufgerufen + // → lädt Diary direkt + }); + }); + } + + // ---------------------------------------------------------- + // DIARY-ANSICHT — Timeline mit Einträgen + // ---------------------------------------------------------- + async function _renderDiary() { _container.innerHTML = `