Routenplanung auf HAFAS (/journeys) umstellen, Zwischenhalte, Filter, Paginierung

Löst die WebApp aus der eigenen OTP2-Instanz heraus und nutzt dieselbe
HAFAS-Anbindung (VBB + Deutsche Bahn) wie die iOS-App, damit beide Clients
gegen dasselbe Backend-Feature-Set laufen:

- js/api.js: getJourneys() ruft jetzt /journeys statt /otp/journeys auf,
  inkl. via0-2 (Lat/Lon/Name/WaitMinutes), modes, bike, earlierRef/laterRef.
  Gibt die volle Antwort zurück statt nur { journeys }.
- js/app.js: bis zu 3 Zwischenhalte mit eigener Ortssuche und Aufenthaltszeit,
  Verkehrsmittel-Filter (ModeFilter-Komponente wiederverwendet), Fahrrad-
  Toggle, Früher/Später-Buttons zum Nachladen. Share-Link-Format um
  Vias/Modes/Bike erweitert, alter Umstiegszeit-Puffer entfernt (von HAFAS
  nicht unterstützt).
- index.html/styles.css: neue Formularelemente für Zwischenhalte, Filter
  und Paginierung.
- js/i18n.js: neue Übersetzungsschlüssel in DE/EN, alten sourceNote-String
  korrigiert (& wurde per textContent gesetzt und wäre literal
  angezeigt worden statt als &).
- README.md: Feature-Beschreibung aktualisiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01De7H8hR1Q9DdgyuS2ukN6y
This commit is contained in:
Claude committed 2026-09-28 11:49:14 +02:00
1 parent 9c3ec24bfe
commit 32c594bc4d
6 files changed
+358 -73

No files matched your search

+22 -10
View File
@@ -89,16 +89,22 @@ const I18N = (() => {
'journey.departureAt': 'Abfahrt um',
'journey.arrivalAt': 'Ankunft um',
'journey.wheelchair': 'Nur rollstuhlgerechte Verbindungen',
'journey.transferSlack': 'Umstiegszeit-Puffer',
'journey.transferSlackDefault': 'Standard',
'journey.transferSlack0': '0 min (knapp)',
'journey.transferSlack15': '15 min (sicher)',
'journey.bike': 'Fahrrad mitnehmen',
'journey.modes': 'Verkehrsmittel',
'journey.addVia': 'Zwischenhalt hinzufügen',
'journey.viaPlaceholder': 'Zwischenhalt {n}',
'journey.removeVia': 'Zwischenhalt entfernen',
'journey.viaWaitLabel': 'Aufenthalt dort',
'journey.viaWaitDirect': 'Direkt weiter',
'journey.earlier': 'Früher',
'journey.later': 'Später',
'journey.submit': 'Verbindungen suchen',
'journey.sourceNote': '🛰 Routenplanung über unsere selbst gehostete, offene Instanz (VBB-Region)',
'journey.sourceNote': '🛰 Routenplanung mit Echtzeitdaten von VBB & Deutscher Bahn',
'journey.share': 'Route teilen',
'journey.selectFromResults': 'Bitte Start und Ziel aus der Liste auswählen.',
'journey.searching': 'Suche Verbindungen…',
'journey.noResults': 'Keine Verbindungen gefunden.',
'journey.maxViasReached': 'Maximal 3 Zwischenhalte möglich.',
'disruptions.title': 'Störungen',
'disruptions.text': 'Ortsbezogene und netzweite Hinweise.',
'disruptions.nearbyTitle': 'In deiner Nähe',
@@ -204,16 +210,22 @@ const I18N = (() => {
'journey.departureAt': 'Depart at',
'journey.arrivalAt': 'Arrive by',
'journey.wheelchair': 'Wheelchair-accessible connections only',
'journey.transferSlack': 'Transfer buffer',
'journey.transferSlackDefault': 'Default',
'journey.transferSlack0': '0 min (tight)',
'journey.transferSlack15': '15 min (safe)',
'journey.bike': 'Take my bike along',
'journey.modes': 'Transit modes',
'journey.addVia': 'Add stopover',
'journey.viaPlaceholder': 'Stopover {n}',
'journey.removeVia': 'Remove stopover',
'journey.viaWaitLabel': 'Wait time there',
'journey.viaWaitDirect': 'Continue immediately',
'journey.earlier': 'Earlier',
'journey.later': 'Later',
'journey.submit': 'Search connections',
'journey.sourceNote': '🛰 Journey planning via our self-hosted, open instance (VBB region)',
'journey.sourceNote': '🛰 Journey planning with real-time VBB & Deutsche Bahn data',
'journey.share': 'Share route',
'journey.selectFromResults': 'Please choose start and destination from the list.',
'journey.searching': 'Searching for connections…',
'journey.noResults': 'No connections found.',
'journey.maxViasReached': 'Maximum of 3 stopovers.',
'disruptions.title': 'Disruptions',
'disruptions.text': 'Location-based and network-wide notices.',
'disruptions.nearbyTitle': 'Near you',