document.addEventListener('DOMContentLoaded', () => { const body = document.body; const isLoggedIn = body.dataset.auth === '1'; const childGender = body.dataset.childGender || ''; const header = document.querySelector('.site-header'); const headerSentinel = document.getElementById('headerSentinel'); // Logo-Logik const pickLogo = (gender) => { if (gender === 'female') return 'logo_female.png'; if (gender === 'male') return 'logo_male.png'; return Math.random() < 0.5 ? 'logo_female.png' : 'logo_male.png'; }; const chosenLogo = pickLogo(childGender); document.querySelectorAll('[data-logo-img]').forEach(img => { img.src = `/assets/bilder/${chosenLogo}`; }); // Header shrink via IntersectionObserver (no flicker around threshold) if (header && headerSentinel && 'IntersectionObserver' in window) { const observer = new IntersectionObserver(([entry]) => { header.classList.toggle('is-scrolled', !entry.isIntersecting); }, { rootMargin: '-1px 0px 0px 0px', threshold: 0, }); observer.observe(headerSentinel); } else if (header) { // Fallback with simple threshold const limit = 120; const onScroll = () => header.classList.toggle('is-scrolled', window.scrollY > limit); onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); } // Mobile Menü const mobileMenu = document.getElementById('mobileMenu'); document.querySelectorAll('.menu-toggle').forEach(btn => { btn.addEventListener('click', () => { mobileMenu?.classList.toggle('open'); }); }); // Scroll zu Events const scrollBtn = document.getElementById('scrollToEvents'); if (scrollBtn) { scrollBtn.addEventListener('click', () => { document.getElementById('events')?.scrollIntoView({ behavior: 'smooth' }); }); } // Events from backend (injected on page); fallback to empty const events = Array.isArray(window.__events) ? window.__events : []; const state = { topic: 'all', age: '', region: '', query: '', geo: null }; const el = { list: document.getElementById('eventList'), chips: document.querySelectorAll('[data-filter]'), locInput: document.getElementById('locInput'), topicSelect: document.getElementById('topicSelect'), ageSelect: document.getElementById('ageSelect'), btnSearch: document.getElementById('btnSearch'), btnGeo: document.getElementById('btnGeo'), }; const fmtDate = (iso) => { const d = new Date(iso); return d.toLocaleDateString('de-DE', { weekday: 'short', day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit' }); }; const haversine = (lat1, lon1, lat2, lon2) => { const toRad = (d) => d * Math.PI / 180; const R = 6371e3; const dLat = toRad(lat2 - lat1); const dLon = toRad(lon2 - lon1); const a = Math.sin(dLat/2) ** 2 + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon/2) ** 2; const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return R * c; }; const tag = (label) => `${label}`; const renderCard = (item) => { const guest = !isLoggedIn; const access = item.visibility === 'members' && guest ? '
Nur für Mitglieder
' : ''; const desc = guest ? `

Melde dich an, um die volle Beschreibung zu sehen.

` : `

${item.description}

`; const contact = !guest ? `
Kontakt: ${item.contact}
` : ''; const kids = item.allowKids ? 'Mit Kindern' : 'Ohne Kinder'; const tags = [ tag(item.topic === 'kaffee' ? 'Kaffee & Austausch' : item.topic.charAt(0).toUpperCase() + item.topic.slice(1)), tag(kids), item.ageGroup ? tag(`Alter: ${item.ageGroup}`) : '', ].filter(Boolean).join(''); return `
${access}
${fmtDate(item.startsAt)} 📍 ${item.region || item.city} ${item.visibility === 'public' ? 'Öffentlich' : 'Mitglieder'}

${item.title}

${guest ? item.teaser : item.description.slice(0, 140) + '...'}

${guest ? '' : desc}
${tags}
${contact}
${!guest ? '' : ''}
`; }; const matchesFilter = (ev) => { const topicOk = state.topic === 'all' || state.topic === ev.topic || state.topic === ''; const ageOk = !state.age || ev.ageGroup === state.age || (state.age === 'baby' && ev.ageGroup === 'kids'); // simple fallback const regionField = (ev.region || '').toLowerCase(); const cityField = (ev.city || '').toLowerCase(); const zipField = (ev.zip || ''); const queryHaystack = (ev.title + ev.teaser + ev.description + (ev.city || '') + (ev.region || '')).toLowerCase(); const regionOk = !state.region || regionField.includes(state.region) || cityField.includes(state.region) || zipField.startsWith(state.region); const queryOk = !state.query || queryHaystack.includes(state.query); return topicOk && ageOk && regionOk && queryOk; }; const renderEvents = () => { if (!el.list) return; let filtered = events.filter(matchesFilter); filtered.sort((a,b) => new Date(a.startsAt) - new Date(b.startsAt)); if (state.geo) { const withCoords = filtered.filter(ev => ev.lat !== null && ev.lng !== null); withCoords.forEach(ev => { ev._distance = haversine(state.geo.lat, state.geo.lng, ev.lat, ev.lng); }); withCoords.sort((a,b) => (a._distance || Infinity) - (b._distance || Infinity)); const near = withCoords.filter(ev => ev._distance <= 5000).slice(0,5); const fallback = withCoords.slice(0,5); filtered = (near.length ? near : fallback).map(ev => { const copy = { ...ev }; if (ev._distance) { copy.teaser = `${ev.teaser} · ca. ${(ev._distance/1000).toFixed(1)} km entfernt`; } return copy; }); } else { filtered = filtered.slice(0,5); } el.list.innerHTML = filtered.map(renderCard).join('') || '

Keine Events gefunden.

'; }; if (el.chips.length > 0) { el.chips[0].classList.add('active'); } el.chips.forEach(chip => { chip.addEventListener('click', () => { el.chips.forEach(c => c.classList.remove('active')); chip.classList.add('active'); state.topic = chip.dataset.filter; renderEvents(); }); }); if (el.btnSearch) { el.btnSearch.addEventListener('click', () => { state.region = (el.locInput?.value || '').trim().toLowerCase(); state.topic = el.topicSelect?.value || 'all'; state.age = el.ageSelect?.value || ''; renderEvents(); }); } if (el.btnGeo) { el.btnGeo.addEventListener('click', () => { if (!navigator.geolocation) { alert('Geolocation wird nicht unterstützt.'); return; } navigator.geolocation.getCurrentPosition( (pos) => { state.geo = { lat: pos.coords.latitude, lng: pos.coords.longitude }; renderEvents(); }, () => alert('Standort konnte nicht ermittelt werden.') ); }); } renderEvents(); });