Files
eventmap/js/models/schema.js
T
dapelza ee55fb1cf9 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)
2026-07-24 11:24:47 +02:00

51 lines
1.5 KiB
JavaScript

// Beschreibt die Feldstruktur eines Ausflugsziels (~27 Felder, siehe
// anforderung.md) und liefert Default-Werte. Dient als einzige Quelle der
// Wahrheit für die Form eines Place-Objekts; Validierungslogik für
// Formulare folgt in einer späteren Phase.
(function () {
/**
* Liefert ein leeres/defaultes Place-Objekt ohne id/createdAt/updatedAt
* (diese werden von place.js ergänzt).
*/
function createDefaultPlaceFields() {
return {
name: '',
category: 'sonstige',
shortDescription: '',
description: '',
latitude: null,
longitude: null,
address: '',
city: '',
region: '',
ageRecommendation: { min: null, max: null },
cost: { type: 'unknown', description: '' },
openingHours: '',
durationMinutes: null,
facilities: {
strollerAccessible: false,
wheelchairAccessible: false,
toilets: false,
parking: false,
restaurant: false,
},
environment: 'outdoor',
website: '',
image: '',
rating: null,
tags: [],
source: '',
sourceVerified: false,
};
}
// Gültige Werte für die Enums des Datenmodells.
const COST_TYPES = ['free', 'paid', 'mixed', 'unknown'];
const ENVIRONMENT_TYPES = ['indoor', 'outdoor', 'mixed'];
EventMap.models.createDefaultPlaceFields = createDefaultPlaceFields;
EventMap.models.COST_TYPES = COST_TYPES;
EventMap.models.ENVIRONMENT_TYPES = ENVIRONMENT_TYPES;
})();