feat(bookings): show transport routes on map (#384, #587)

Adds from/to endpoints to flight/train/cruise/car reservations with
live map rendering. Flights use geodesic arcs and a curved duration +
distance badge; train/car/cruise render as straight or geodesic lines
with endpoint markers. Airports come from an embedded OurAirports
database (~3200 airports, offline-capable); train/cruise/car locations
via Nominatim. Per-trip connection toggle sits in the day plan
sidebar, persisted in localStorage. Clicking a map endpoint opens the
existing transport detail popup. New display setting toggles endpoint
labels on the map. Migration 105 adds the reservation_endpoints table
plus needs_review flag; existing flights are backfilled from their
IATA metadata on server startup.
This commit is contained in:
Maurice
2026-04-17 14:04:40 +02:00
parent 21511c2f68
commit 8defc90e95
26 changed files with 1437 additions and 81 deletions
+5
View File
@@ -365,6 +365,11 @@ export const mapsApi = {
resolveUrl: (url: string) => apiClient.post('/maps/resolve-url', { url }).then(r => r.data),
}
export const airportsApi = {
search: (q: string, signal?: AbortSignal) => apiClient.get('/airports/search', { params: { q }, signal }).then(r => r.data),
byIata: (iata: string) => apiClient.get(`/airports/${encodeURIComponent(iata)}`).then(r => r.data),
}
export const budgetApi = {
list: (tripId: number | string) => apiClient.get(`/trips/${tripId}/budget`).then(r => r.data),
create: (tripId: number | string, data: Record<string, unknown>) => apiClient.post(`/trips/${tripId}/budget`, data).then(r => r.data),