import { useEffect, useRef } from "react"; import { MapContainer, TileLayer, GeoJSON, useMap } from "react-leaflet"; import L from "leaflet"; import type { GeoJsonObject } from "geojson"; import "leaflet/dist/leaflet.css"; function FitBounds({ data }: { data: GeoJsonObject }) { const map = useMap(); const fitted = useRef(false); useEffect(() => { if (fitted.current) return; const layer = L.geoJSON(data); const bounds = layer.getBounds(); if (bounds.isValid()) { map.fitBounds(bounds, { padding: [20, 20] }); fitted.current = true; } }, [data, map]); return null; } const DAY_COLORS = ["#2563eb", "#8B6D3A", "#059669", "#9333ea", "#dc2626", "#0891b2"]; interface RouteMapProps { geojson: string; interactive?: boolean; className?: string; dayBreaks?: number[]; } export function RouteMapThumbnail({ geojson, interactive, className, dayBreaks }: RouteMapProps) { const data: GeoJsonObject = JSON.parse(geojson); return ( OpenStreetMap' : undefined} /> {dayBreaks && dayBreaks.length > 0 ? ( ) : ( )} ); } function DayColoredRoute({ data, dayBreaks }: { data: GeoJsonObject; dayBreaks: number[] }) { // Extract coordinates from the GeoJSON LineString const geometry = (data as { type: string; coordinates?: number[][] }).coordinates ?? ((data as { features?: Array<{ geometry: { coordinates: number[][] } }> }).features?.[0]?.geometry?.coordinates); if (!geometry || geometry.length < 2) { return ; } // Split coordinates into segments at approximate day break points // dayBreaks are waypoint indices — we split the line evenly since we don't // have exact waypoint-to-coordinate mapping in the Journal context const totalPoints = geometry.length; const numDays = dayBreaks.length + 1; const pointsPerDay = Math.ceil(totalPoints / numDays); const segments: Array<{ coords: number[][]; color: string }> = []; for (let d = 0; d < numDays; d++) { const start = d * pointsPerDay; const end = Math.min((d + 1) * pointsPerDay + 1, totalPoints); if (start >= totalPoints) break; segments.push({ coords: geometry.slice(start, end), color: DAY_COLORS[d % DAY_COLORS.length]!, }); } return ( <> {segments.map((seg, i) => { const segData: GeoJsonObject = { type: "Feature", geometry: { type: "LineString", coordinates: seg.coords }, properties: {}, } as unknown as GeoJsonObject; return ( ); })} ); }