asdasd
This commit is contained in:
@@ -49,75 +49,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
// Demo-Events
|
||||
const events = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Spielplatzrunde im Park',
|
||||
teaser: 'Lockeres Treffen mit Kaffee, Sandspielzeug und Picknick.',
|
||||
description: 'Wir treffen uns am großen Spielplatz im Kiez. Bringt Snacks mit, wir teilen. Für alle Altersstufen offen.',
|
||||
city: 'Berlin',
|
||||
zip: '10437',
|
||||
region: 'Prenzlauer Berg',
|
||||
topic: 'outdoor',
|
||||
startsAt: '2025-08-10T10:00:00',
|
||||
allowKids: true,
|
||||
ageGroup: 'kids',
|
||||
visibility: 'public',
|
||||
contact: 'papa-berlin@example.com',
|
||||
locationLabel: 'Mauerpark',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Väter-Kaffee & Austausch',
|
||||
teaser: 'Elternzeit, Job, Schlaf – wir reden über alles.',
|
||||
description: 'Reservierter Tisch im Café. Fokus auf Austausch unter Vätern, Kinder optional.',
|
||||
city: 'Hamburg',
|
||||
zip: '22767',
|
||||
region: 'Altona',
|
||||
topic: 'kaffee',
|
||||
startsAt: '2025-08-12T19:00:00',
|
||||
allowKids: false,
|
||||
ageGroup: '',
|
||||
visibility: 'members',
|
||||
contact: 'altona-dads@example.com',
|
||||
locationLabel: 'Café Elbseite',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Sport & Spiel im Park',
|
||||
teaser: 'Ballspiele und leichtes Workout, Kinder toben mit.',
|
||||
description: 'Wir bringen Bälle und Slackline. Warm-up, danach freies Spiel. Bitte Wasser mitbringen.',
|
||||
city: 'München',
|
||||
zip: '80804',
|
||||
region: 'Schwabing',
|
||||
topic: 'sport',
|
||||
startsAt: '2025-08-15T11:00:00',
|
||||
allowKids: true,
|
||||
ageGroup: 'school',
|
||||
visibility: 'public',
|
||||
contact: 'schwabing-sport@example.com',
|
||||
locationLabel: 'Luitpoldpark',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'Workshop: Erste Hilfe für Kids',
|
||||
teaser: 'Erste Hilfe Basics speziell für Kinder-Unfälle.',
|
||||
description: 'Zertifizierter Trainer, kleiner Materialbeitrag. Kinder können mitgebracht werden.',
|
||||
city: 'Köln',
|
||||
zip: '50667',
|
||||
region: 'Innenstadt',
|
||||
topic: 'workshop',
|
||||
startsAt: '2025-08-20T18:30:00',
|
||||
allowKids: true,
|
||||
ageGroup: 'kids',
|
||||
visibility: 'members',
|
||||
contact: 'koeln-workshop@example.com',
|
||||
locationLabel: 'Familienzentrum Mitte',
|
||||
},
|
||||
];
|
||||
// Events from backend (injected on page); fallback to empty
|
||||
const events = Array.isArray(window.__events) ? window.__events : [];
|
||||
|
||||
const state = { topic: 'all', age: '', region: '', query: '' };
|
||||
const state = { topic: 'all', age: '', region: '', query: '', geo: null };
|
||||
const el = {
|
||||
list: document.getElementById('eventList'),
|
||||
chips: document.querySelectorAll('[data-filter]'),
|
||||
@@ -133,6 +68,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
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) => `<span class="badge">${label}</span>`;
|
||||
|
||||
const renderCard = (item) => {
|
||||
@@ -170,16 +115,39 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
};
|
||||
|
||||
const matchesFilter = (ev) => {
|
||||
const topicOk = state.topic === 'all' || state.topic === ev.topic;
|
||||
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 regionOk = !state.region || ev.region.toLowerCase().includes(state.region) || ev.city.toLowerCase().includes(state.region) || ev.zip.startsWith(state.region);
|
||||
const queryOk = !state.query || (ev.title + ev.teaser + ev.description + ev.city + ev.region).toLowerCase().includes(state.query);
|
||||
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;
|
||||
const filtered = events.filter(matchesFilter);
|
||||
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('') || '<p class="muted">Keine Events gefunden.</p>';
|
||||
};
|
||||
|
||||
@@ -212,8 +180,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
return;
|
||||
}
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
() => {
|
||||
state.region = 'nähe';
|
||||
(pos) => {
|
||||
state.geo = { lat: pos.coords.latitude, lng: pos.coords.longitude };
|
||||
renderEvents();
|
||||
},
|
||||
() => alert('Standort konnte nicht ermittelt werden.')
|
||||
|
||||
Reference in New Issue
Block a user