Phase 0+1: Scaffold, Datenmodell, Karte und Liste
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)
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
// 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;
|
||||
})();
|
||||
Reference in New Issue
Block a user