Seed-Daten per Fetch von externem Server laden, UI-Sprachumschalter (DE/EN) und KI-Übersetzungs-Prompt-Generator ergänzen

- Beispieldaten werden nicht mehr eingebettet (data/seed.js entfernt),
  sondern beim ersten Start per fetch(EventMap.config.SEED_DATA_URL) von
  einem externen, selbst gehosteten Server geladen (siehe ADR 0001,
  Revision 2026-07-28).
- Neuer UI-Sprachumschalter (Deutsch/Englisch) für die Bedienoberfläche:
  js/i18n/strings.js + js/i18n/i18n.js, Sprachwahl im Menü, Persistenz über
  settings.language, Retranslation ohne Reload.
- Neuer Menüpunkt "Ausflugsziel übersetzen (KI)": erzeugt einen Prompt, der
  eine externe KI bittet, Name/Beschreibungen eines bestehenden Ortes ins
  Englische, Spanische oder Französische zu übersetzen (js/ai/translatePromptBuilder.js,
  js/ui/translatePromptGenerator.js).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-28 15:16:31 +02:00
co-authored by Claude Sonnet 5
parent 4eb595aa81
commit 2aaff8f680
17 changed files with 1027 additions and 2007 deletions
+26 -13
View File
@@ -1,7 +1,8 @@
// Zentraler Pub/Sub-Store der Anwendung. Hält den Laufzeitzustand
// (places, filters, userLocation, selectedPlaceId) und benachrichtigt
// Subscriber bei Änderungen. Lädt beim Start aus LocalStorage bzw. beim
// allerersten Start aus data/seed.js und persistiert Änderungen zurück.
// allerersten Start von EventMap.config.SEED_DATA_URL und persistiert
// Änderungen zurück.
(function () {
const { loadData, saveData, loadSettings, saveSettings } = EventMap.store;
@@ -48,29 +49,41 @@
saveSettings(settings);
}
function loadSeedPlaces() {
const raw = (EventMap.data && EventMap.data.SEED_PLACES) || [];
/** Lädt die Beispieldaten von EventMap.config.SEED_DATA_URL nach. Wirft bei Netzwerk-/HTTP-/Parse-Fehlern. */
async function loadSeedPlaces() {
const response = await fetch(EventMap.config.SEED_DATA_URL);
if (!response.ok) {
throw new Error(`Seed-Daten-Download fehlgeschlagen (HTTP ${response.status}).`);
}
const raw = await response.json();
return raw.map((item) => normalizePlace(item));
}
/**
* Initialisiert den Store: lädt persistierte Places aus LocalStorage oder,
* falls noch keine vorhanden sind, die eingebetteten Beispieldaten
* (data/seed.js). Gibt den finalen State zurück.
* falls noch keine vorhanden sind, die Beispieldaten von
* EventMap.config.SEED_DATA_URL. Gibt { seedLoadFailed } zurück, damit
* main.js bei einem fehlgeschlagenen Download einen Hinweis anzeigen kann
* (die App bleibt dabei mit einer leeren Places-Liste nutzbar).
*/
function initStore() {
async function initStore() {
const persisted = loadData();
let places = [];
if (persisted && Array.isArray(persisted.places) && persisted.places.length > 0) {
places = persisted.places.map((p) => normalizePlace(p));
} else {
places = loadSeedPlaces();
saveData(places);
setState({ places: persisted.places.map((p) => normalizePlace(p)) });
return { seedLoadFailed: false };
}
setState({ places });
return state;
try {
const places = await loadSeedPlaces();
saveData(places);
setState({ places });
return { seedLoadFailed: false };
} catch (err) {
console.warn('EventMap: Beispieldaten konnten nicht geladen werden.', err);
setState({ places: [] });
return { seedLoadFailed: true };
}
}
/** Persistiert state.places nach Änderungen (Erstellen/Bearbeiten/Löschen). */