/* ============================================================ BAN YARO — Reise mit Hund Tabs: Checkliste | EU-Länder | Notfälle ============================================================ */ window.Page_reise = (() => { let _container = null; let _appState = null; let _activeTab = 'checkliste'; const TABS = [ { key: 'checkliste', label: 'Checkliste', icon: '' }, { key: 'laender', label: 'EU-Länder', icon: '' }, ]; const CHECKLIST = [ { key: 'dokumente', label: 'Dokumente', icon: 'file-text', items: [ 'EU-Heimtierausweis (Pflicht innerhalb EU)', 'Impfpass (Tollwut mind. 21 Tage alt)', 'Krankenkassen-Notfallkarte Tierarzt', 'Foto des Hundes (für Vermisst-Fall)', 'Chip-Nummer notiert', ], }, { key: 'gesundheit', label: 'Gesundheit', icon: 'heartbeat', items: [ 'Zecken-/Flohschutz aufgefrischt', 'Reisekrankheit-Mittel (falls nötig)', 'Medikamente ausreichend eingepackt', 'Tierarzt-Kontakt am Zielort recherchiert', 'Verbandszeug für Hunde', ], }, { key: 'ausruestung', label: 'Ausrüstung', icon: 'backpack', items: [ 'Leine + Ersatzleine', 'Halsband mit Adressanhänger', 'Transportbox/Reisekorb', 'Lieblingsdecke/Schlafplatz', 'Spielzeug (2–3 Stück)', ], }, { key: 'futter', label: 'Futter & Wasser', icon: 'bowl-food', items: [ 'Genug Futter (+ Reserve)', 'Wassernapf + Flasche', 'Futternapf', 'Bekannte Leckerlis', ], }, { key: 'auto', label: 'Im Auto', icon: 'car', items: [ 'Sicherheitsgurt-Adapter oder Box gesichert', 'Sonnenschutz-Netz für Fenster', 'Pausen alle 2h eingeplant', ], }, ]; const LAENDER = [ { flag: '🇩🇪', name: 'Deutschland', regel: 'Keine Einschränkungen bei EU-Pass + Chip' }, { flag: '🇦🇹', name: 'Österreich', regel: 'Gleiche Regeln wie DE, Leinenpflicht in Bergbahnen' }, { flag: '🇨🇭', name: 'Schweiz', regel: 'Nicht-EU → eigene Einfuhrregeln, Tollwut-Titer-Test', warn: true }, { flag: '🇮🇹', name: 'Italien', regel: 'Leinenpflicht öffentlich, Maulkorb in öffentlichen Verkehrsmitteln' }, { flag: '🇫🇷', name: 'Frankreich', regel: 'Manche Strände im Sommer hundeverboten' }, { flag: '🇬🇷', name: 'Griechenland', regel: 'Hunde erlaubt, kaum Einschränkungen' }, { flag: '🇭🇷', name: 'Kroatien', regel: 'Viele Strände hundefreundlich, EU-Pass genügt' }, { flag: '🇬🇧', name: 'Großbritannien', regel: 'Strenge Einreise! PETS-Zertifikat + Tollwut-Impfung + Bandwurm-Behandlung nötig', warn: true }, ]; const SOFORTMASSNAHMEN = [ { icon: 'thermometer-hot', text: 'Hitzschlag: Sofort Schatten, kühlen mit lauwarmem Wasser, Tierarzt rufen' }, { icon: 'skull', text: 'Vergiftung: Ruhig halten, NICHT erbrechen lassen, sofort Tiergift-Notfall anrufen' }, { icon: 'drop', text: 'Starke Blutung: Druckverband anlegen, Druck halten, Tierarzt aufsuchen' }, { icon: 'bone', text: 'Knochenbruch: Ruhigstellen, nicht bewegen, Tierarzt aufsuchen' }, { icon: 'heartbeat', text: 'Bewusstlosigkeit: Atemwege freihalten, stabile Seitenlage, 112 rufen' }, ]; const LS_KEY = 'banyaro_reise_checkliste'; const LS_CUSTOM_KEY = 'banyaro_reise_custom'; // {catKey: ["custom item",...]} const LS_HIDDEN_KEY = 'banyaro_reise_hidden'; // {itemKey: true} — gelöschte Standard-Items let _editMode = false; function _loadCustom() { try { return JSON.parse(localStorage.getItem(LS_CUSTOM_KEY) || '{}'); } catch { return {}; } } function _saveCustom(d) { try { localStorage.setItem(LS_CUSTOM_KEY, JSON.stringify(d)); } catch {} } function _loadHidden() { try { return JSON.parse(localStorage.getItem(LS_HIDDEN_KEY) || '{}'); } catch { return {}; } } function _saveHidden(d) { try { localStorage.setItem(LS_HIDDEN_KEY, JSON.stringify(d)); } catch {} } // ------------------------------------------------------------------ // Helpers // ------------------------------------------------------------------ function _loadChecked() { try { return JSON.parse(localStorage.getItem(LS_KEY) || '{}'); } catch { return {}; } } function _saveChecked(state) { try { localStorage.setItem(LS_KEY, JSON.stringify(state)); } catch {} } function _itemKey(catKey, idx) { return `${catKey}__${idx}`; } // ------------------------------------------------------------------ // LIFECYCLE // ------------------------------------------------------------------ function init(container, appState, params = {}) { _container = container; _appState = appState; if (params?.tab && TABS.some(t => t.key === params.tab)) { _activeTab = params.tab; } _render(); } function refresh() { _renderTabContent(); } function onDogChange() {} // ------------------------------------------------------------------ // RENDER // ------------------------------------------------------------------ function _render() { _container.innerHTML = `
`; _renderTabBar(); _renderTabContent(); } function _renderTabBar() { const el = _container.querySelector('#reise-tabs'); if (!el) return; el.innerHTML = TABS.map(t => ` `).join(''); el.querySelectorAll('.by-tab').forEach(btn => { btn.addEventListener('click', () => { _activeTab = btn.dataset.tab; el.querySelectorAll('.by-tab').forEach(b => b.classList.remove('active')); btn.classList.add('active'); _renderTabContent(); }); }); } function _renderTabContent() { const el = _container.querySelector('#reise-content'); if (!el) return; if (_activeTab === 'checkliste') _renderCheckliste(el); else if (_activeTab === 'laender') _renderLaender(el); else if (_activeTab === 'notfall') _renderNotfall(el); } // ------------------------------------------------------------------ // TAB 1: CHECKLISTE // ------------------------------------------------------------------ function _renderCheckliste(el) { const checked = _loadChecked(); const custom = _loadCustom(); const hidden = _loadHidden(); // Alle sichtbaren Items zählen let totalItems = 0, doneItems = 0; CHECKLIST.forEach(cat => { cat.items.forEach((_, idx) => { if (!hidden[_itemKey(cat.key, idx)]) { totalItems++; if (checked[_itemKey(cat.key, idx)]) doneItems++; } }); (custom[cat.key] || []).forEach((_, i) => { totalItems++; if (checked[`${cat.key}__custom__${i}`]) doneItems++; }); }); const pct = totalItems > 0 ? Math.round((doneItems / totalItems) * 100) : 0; const cats = CHECKLIST.map(cat => { const customItems = custom[cat.key] || []; const stdRows = cat.items.map((item, idx) => { if (hidden[_itemKey(cat.key, idx)]) return ''; const key = _itemKey(cat.key, idx); const done = !!checked[key]; if (_editMode) { return `