Reines HTML5/CSS3/JavaScript ohne Build-Tooling, lauffaehig direkt per Doppelklick auf index.html (file://, kein Server noetig): - Datenmodell fuer Ausflugsziele mit allen Feldern aus der Anforderung, 15 feste Kategorien inkl. Farbe/Icon - Zentraler Pub/Sub-Store mit LocalStorage-Persistenz und Migrations-Grundgeruest - Interaktive Karte (Leaflet + Leaflet.markercluster, lokal vendored) mit kategoriefarbenen Markern, Clustering, Popups, Geolocation-Button - Kartengrundlage ueber CARTO-Basemaps statt tile.openstreetmap.org, da dessen Referer-Pflicht file://-Aufrufe blockiert - Seed-Daten als eingebettetes Script (data/seed.js) statt JSON-Datei, da fetch() auf lokale Dateien unter file:// nicht zuverlaessig funktioniert - Ergebnisliste mit 10 Beispiel-Ausflugszielen, sicher gerendert ueber textContent/DOM-APIs statt innerHTML (Vorbereitung fuer spaeteren KI-JSON-Import mit Fremddaten) - Responsives Layout (Desktop nebeneinander, Mobile gestapelt)
64 lines
1.8 KiB
JavaScript
64 lines
1.8 KiB
JavaScript
// Persistenzschicht: liest/schreibt die beiden LocalStorage-Keys
|
|
// eventmap.data.v1 und eventmap.settings.v1.
|
|
|
|
(function () {
|
|
const { STORAGE_KEYS, CURRENT_SCHEMA_VERSION } = EventMap.config;
|
|
const { migrate } = EventMap.store;
|
|
|
|
function createDefaultSettings() {
|
|
return {
|
|
lastFilters: null,
|
|
lastMapView: null,
|
|
userConsentGeo: null,
|
|
defaultCenter: null,
|
|
};
|
|
}
|
|
|
|
/** Liest die persistierten Places. Gibt null zurück, falls noch nichts gespeichert ist. */
|
|
function loadData() {
|
|
const raw = window.localStorage.getItem(STORAGE_KEYS.DATA);
|
|
if (!raw) {
|
|
return null;
|
|
}
|
|
try {
|
|
const parsed = JSON.parse(raw);
|
|
return migrate(parsed);
|
|
} catch (err) {
|
|
console.warn('EventMap: Gespeicherte Daten sind beschädigt und werden verworfen.', err);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function saveData(places) {
|
|
const payload = {
|
|
schemaVersion: CURRENT_SCHEMA_VERSION,
|
|
places,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
window.localStorage.setItem(STORAGE_KEYS.DATA, JSON.stringify(payload));
|
|
}
|
|
|
|
function loadSettings() {
|
|
const raw = window.localStorage.getItem(STORAGE_KEYS.SETTINGS);
|
|
if (!raw) {
|
|
return createDefaultSettings();
|
|
}
|
|
try {
|
|
return { ...createDefaultSettings(), ...JSON.parse(raw) };
|
|
} catch (err) {
|
|
console.warn('EventMap: Gespeicherte Einstellungen sind beschädigt, Defaults werden verwendet.', err);
|
|
return createDefaultSettings();
|
|
}
|
|
}
|
|
|
|
function saveSettings(settings) {
|
|
window.localStorage.setItem(STORAGE_KEYS.SETTINGS, JSON.stringify(settings));
|
|
}
|
|
|
|
EventMap.store.createDefaultSettings = createDefaultSettings;
|
|
EventMap.store.loadData = loadData;
|
|
EventMap.store.saveData = saveData;
|
|
EventMap.store.loadSettings = loadSettings;
|
|
EventMap.store.saveSettings = saveSettings;
|
|
})();
|