import type { Trip, TripSummary, Place, Meal, Day, Weather, SafetyData, TripMeta, ActualEntry, ActualDay, WrapupData, MapSummary, MapPlace, StandaloneMap } from "./types"; const BASE = "/travel/api"; async function fetchJson(path: string): Promise { const res = await fetch(`${BASE}/${path}`); if (!res.ok) throw new Error(`Failed to fetch ${path}: ${res.status}`); return res.json(); } export async function loadTrips(): Promise { return fetchJson("trips"); } export async function loadTrip(tripId: string): Promise { const [meta, weather, pack, placeFiles, safety, dayFiles, meals, actuals, wrapup] = await Promise.all([ fetchJson(`trip/${tripId}/meta.json`), fetchJson(`trip/${tripId}/weather.json`), fetchJson(`trip/${tripId}/pack.json`), fetchJson>(`trip/${tripId}/places`), fetchJson(`trip/${tripId}/places/safety.json`), fetchJson(`trip/${tripId}/days`), fetchJson(`trip/${tripId}/meals`).catch(() => [] as Meal[]), fetchJson(`trip/${tripId}/actuals`).catch(() => [] as ActualDay[]), fetchJson(`trip/${tripId}/wrapup.json`).catch(() => ({ todos: [], expenses: [], highlights: [], lessons: [], summary: "" } as WrapupData)), ]); const places: Place[] = []; for (const [, arr] of Object.entries(placeFiles)) { if (Array.isArray(arr)) places.push(...arr); } let packState: Record = {}; try { packState = await fetchJson>(`trip/${tripId}/pack-state.json`); } catch { /* no saved state yet */ } return { id: tripId, meta, weather, pack, packState, places, meals, safety, days: dayFiles, actuals, wrapup }; } export function placesBy(places: Place[], category: string): Place[] { return places.filter(p => p.category === category); } export async function loadMaps(): Promise { return fetchJson("maps"); } export async function loadMap(mapId: string): Promise { const [meta, places] = await Promise.all([ fetchJson>(`map/${mapId}/meta.json`), fetchJson(`map/${mapId}/places.json`).catch(() => [] as MapPlace[]), ]); return { id: mapId, ...meta, places }; }