diff --git a/backend/static/js/app.js b/backend/static/js/app.js
index 8ec5eb4..e36649b 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 = '179'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
+const APP_VER = '175'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const App = (() => {
@@ -33,7 +33,6 @@ const App = (() => {
// ----------------------------------------------------------
const pages = {
welcome: { title: 'Willkommen', module: null },
- onboarding: { title: 'Einrichtung', module: null, requiresAuth: true },
diary: { title: 'Tagebuch', module: null, requiresAuth: true },
health: { title: 'Gesundheit', module: null, requiresAuth: true },
'dog-profile': { title: 'Mein Hund', module: null, requiresAuth: true },
@@ -414,9 +413,9 @@ const App = (() => {
}
await _loadDogs();
- // Eingeloggter User ohne Hund → Onboarding-Wizard (einmalig)
- if (state.dogs.length === 0 && !localStorage.getItem('by_onboarding_done')) {
- navigate('onboarding');
+ // Eingeloggter User ohne Hund (z.B. nach Reload) → direkt zur Hund-Anlage
+ if (state.dogs.length === 0) {
+ navigate('dog-profile');
}
_updateNotifBadge();
diff --git a/backend/static/js/pages/onboarding.js b/backend/static/js/pages/onboarding.js
deleted file mode 100644
index 6cfda8b..0000000
--- a/backend/static/js/pages/onboarding.js
+++ /dev/null
@@ -1,461 +0,0 @@
-/* ============================================================
- BAN YARO — Onboarding-Wizard
- 3-Schritt-Wizard für neue User ohne Hund.
- ============================================================ */
-
-window.Page_onboarding = (() => {
-
- let _container = null;
- let _appState = null;
- let _step = 1; // 1 = Willkommen, 2 = Hund anlegen, 3 = Fertig
-
- // ----------------------------------------------------------
- // INIT
- // ----------------------------------------------------------
- async function init(container, appState) {
- _container = container;
- _appState = appState;
- _step = 1;
- _render();
- }
-
- function refresh() {
- // Wenn User nach Abschluss zurücknavigiert und schon fertig ist → Tagebuch
- if (localStorage.getItem('by_onboarding_done')) {
- App.navigate('diary');
- return;
- }
- _render();
- }
-
- function onDogChange() {}
-
- // ----------------------------------------------------------
- // RENDER
- // ----------------------------------------------------------
- function _render() {
- _container.innerHTML = `
-
-
-
-
- ${[1, 2, 3].map(n => `
-
-
- ${n < _step
- ? ` `
- : n}
-
- ${n < 3 ? `
` : ''}
-
- `).join('')}
-
-
-
-
- ${_stepContent()}
-
-
-
- `;
-
- _bindEvents();
- }
-
- function _stepContent() {
- if (_step === 1) return _step1();
- if (_step === 2) return _step2();
- if (_step === 3) return _step3();
- return '';
- }
-
- // ----------------------------------------------------------
- // SCHRITT 1 — Willkommen
- // ----------------------------------------------------------
- function _step1() {
- return `
-
-
-
-
-
-
-
-
-
- Willkommen bei Ban Yaro!
-
-
-
-
- Ban Yaro ist dein digitaler Begleiter für alles rund um deinen Hund —
- Tagebuch, Gesundheit, Karte und Community in einer App.
-
-
- In nur zwei Schritten richtest du dein Profil ein und bist sofort startklar.
-
-
-
-
- ${[
- ['book-open', 'Tagebuch', 'Momente & Fotos'],
- ['syringe', 'Gesundheit', 'Impfungen & Arzt'],
- ['map-trifold', 'Karte', 'Orte & Routen'],
- ['users', 'Community', 'Freunde & Treffen'],
- ].map(([icon, title, desc]) => `
-
- `).join('')}
-
-
-
-
-
-
- Los geht's
-
-
- Überspringen
-
-
-
-
- `;
- }
-
- // ----------------------------------------------------------
- // SCHRITT 2 — Hund anlegen
- // ----------------------------------------------------------
- function _step2() {
- const today = new Date().toISOString().slice(0, 10);
- return `
-
-
-
-
-
-
-
-
-
-
- Dein erster Hund
-
-
- Nur der Name ist Pflicht — alles andere kannst du später ergänzen.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Hund anlegen
-
-
-
-
- Ohne Hund fortfahren
-
-
-
-
- `;
- }
-
- // ----------------------------------------------------------
- // SCHRITT 3 — Fertig
- // ----------------------------------------------------------
- function _step3() {
- const dogName = _appState.activeDog?.name;
- return `
-
-
-
-
-
-
-
- Dein Profil ist bereit!
-
- ${dogName ? `
-
- ${_esc(dogName)} ist jetzt in Ban Yaro.
- Du kannst jetzt Einträge im Tagebuch anlegen, die Gesundheit pflegen
- und viele weitere Funktionen nutzen.
-
- ` : `
-
- Ban Yaro ist bereit. Du kannst jetzt die Karte, das Wiki und viele
- weitere Funktionen erkunden.
-
- `}
-
- Du kannst dein Hundeprofil jederzeit unter
- Mein Hund bearbeiten und ergänzen.
-
-
-
-
-
-
- Zum Tagebuch
-
- ${dogName ? `
-
-
- Profil vervollständigen
-
- ` : ''}
-
-
-
- `;
- }
-
- // ----------------------------------------------------------
- // EVENTS
- // ----------------------------------------------------------
- function _bindEvents() {
- // Weiter-Button (Schritt 1)
- _container.querySelector('#ob-next-btn')?.addEventListener('click', () => {
- _step = 2;
- _render();
- });
-
- // Zurück-Button (Schritt 2)
- _container.querySelector('#ob-back-btn')?.addEventListener('click', () => {
- _step = 1;
- _render();
- });
-
- // Überspringen
- _container.querySelector('#ob-skip-btn')?.addEventListener('click', () => {
- _finish();
- });
-
- // Foto-Vorschau
- _container.querySelector('#ob-photo-input')?.addEventListener('change', e => {
- const file = e.target.files?.[0];
- if (!file) return;
- const url = URL.createObjectURL(file);
- const preview = _container.querySelector('#ob-photo-preview');
- const img = _container.querySelector('#ob-photo-img');
- const label = _container.querySelector('#ob-photo-label');
- if (preview) preview.style.display = '';
- if (img) img.src = url;
- if (label) label.textContent = file.name.length > 20
- ? file.name.slice(0, 17) + '...'
- : file.name;
- });
-
- // Formular abschicken (Schritt 2)
- _container.querySelector('#ob-dog-form')?.addEventListener('submit', async e => {
- e.preventDefault();
- await _saveDog(e.target);
- });
-
- // Zu Tagebuch (Schritt 3)
- _container.querySelector('#ob-diary-btn')?.addEventListener('click', () => {
- App.navigate('diary');
- });
-
- // Zu Hund-Profil (Schritt 3)
- _container.querySelector('#ob-profile-btn')?.addEventListener('click', () => {
- App.navigate('dog-profile');
- });
- }
-
- // ----------------------------------------------------------
- // HUND SPEICHERN
- // ----------------------------------------------------------
- async function _saveDog(form) {
- const saveBtn = _container.querySelector('#ob-save-btn');
- if (saveBtn) {
- saveBtn.disabled = true;
- saveBtn.innerHTML = `
-
- Wird angelegt…
- `;
- }
-
- try {
- const data = new FormData(form);
- const payload = {
- name: data.get('name')?.trim(),
- rasse: data.get('rasse')?.trim() || null,
- geburtstag: data.get('geburtstag') || null,
- };
-
- if (!payload.name) {
- UI.toast.error('Bitte gib einen Namen ein.');
- return;
- }
-
- // Hund anlegen
- const dog = await API.dogs.create(payload);
-
- // Foto hochladen (falls vorhanden)
- const fotoFile = data.get('foto');
- if (fotoFile && fotoFile.size > 0) {
- try {
- const fd = new FormData();
- fd.append('file', fotoFile);
- await API.dogs.uploadPhoto(dog.id, fd);
- } catch {
- // Foto-Upload-Fehler ist nicht kritisch
- UI.toast.warning('Hund angelegt, Foto konnte nicht hochgeladen werden.');
- }
- }
-
- // State aktualisieren
- const dogs = await API.dogs.list();
- _appState.dogs = dogs;
- const newDog = dogs.find(d => d.id === dog.id) || dogs[0];
- _appState.activeDog = newDog;
- if (newDog) {
- localStorage.setItem('by_active_dog', String(newDog.id));
- }
- App.renderDogSwitcher();
-
- UI.toast.success(`${_esc(dog.name)} wurde angelegt!`);
-
- _step = 3;
- _render();
-
- } catch (err) {
- UI.toast.error(err.message || 'Hund konnte nicht angelegt werden.');
- } finally {
- if (saveBtn) {
- saveBtn.disabled = false;
- saveBtn.innerHTML = `
-
- Hund anlegen
- `;
- }
- }
- }
-
- // ----------------------------------------------------------
- // ABSCHLUSS
- // ----------------------------------------------------------
- function _finish() {
- localStorage.setItem('by_onboarding_done', '1');
- if (_appState.dogs.length > 0) {
- App.navigate('diary');
- } else {
- App.navigate('map');
- }
- }
-
- // ----------------------------------------------------------
- // HELPER
- // ----------------------------------------------------------
- function _esc(s) {
- return UI.escape(s || '');
- }
-
- // ----------------------------------------------------------
- // PUBLIC
- // ----------------------------------------------------------
- return { init, refresh, onDogChange };
-
-})();
diff --git a/backend/static/js/pages/settings.js b/backend/static/js/pages/settings.js
index 6aeb9d9..8478bca 100644
--- a/backend/static/js/pages/settings.js
+++ b/backend/static/js/pages/settings.js
@@ -182,32 +182,6 @@ window.Page_settings = (() => {
App-Einstellungen
-
-
-
-
-
-
Dark Mode
-
- Erscheinungsbild der App
-
-
-
- System
- Hell
- Dunkel
-
-
-
@@ -446,24 +420,6 @@ window.Page_settings = (() => {
}
});
- document.getElementById('select-theme')?.addEventListener('change', e => {
- const val = e.target.value;
- localStorage.setItem('by_theme', val);
- const html = document.documentElement;
- if (val === 'dark') {
- html.setAttribute('data-theme', 'dark');
- } else if (val === 'light') {
- html.setAttribute('data-theme', 'light');
- } else {
- html.removeAttribute('data-theme');
- }
- UI.toast.info(
- val === 'dark' ? 'Dark Mode aktiviert.' :
- val === 'light' ? 'Hell-Modus aktiviert.' :
- 'Theme folgt der Systemeinstellung.'
- );
- });
-
document.getElementById('toggle-pocket-mode')?.addEventListener('change', e => {
localStorage.setItem('by_pocket_mode', String(e.target.checked));
UI.toast.info(e.target.checked