Merge pull request #613 from trails-cool/fix/planner-nearby-pois-session

fix(planner): nearby-POI lookup sends the real session (was 401 Unauthorized)
This commit is contained in:
Ullrich Schäfer 2026-07-16 23:41:58 +02:00 committed by GitHub
commit 104424d531
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 13 additions and 11 deletions

View file

@ -185,7 +185,7 @@ export function PlannerMap({ yjs, sessionId, onRouteRequest, highlightPosition,
const { draggingOver, handleDragEnter, handleDragLeave, handleDragOver, handleDrop } = useGpxDrop(yjs, onImportError);
const selectedWp = selectedWaypointIndex != null ? waypoints[selectedWaypointIndex] : undefined;
const nearbyPoisState = useNearbyPois(selectedWp?.lat, selectedWp?.lon);
const nearbyPoisState = useNearbyPois(selectedWp?.lat, selectedWp?.lon, sessionId);
const handleSnapToPoi = useCallback((poi: Poi) => {
if (selectedWaypointIndex == null) return;

View file

@ -114,7 +114,7 @@ function useAwarenessToasts(yjs: YjsState | null, t: TFunction, addToast: (messa
}
function SidebarTabs({ yjs, routeStats, days, onWaypointHover, onWaypointSelect }: { yjs: YjsState; routeStats: ReturnType<typeof useRouting>["routeStats"]; days: ReturnType<typeof useDays>; onWaypointHover: (index: number | null) => void; onWaypointSelect: (index: number | null) => void }) {
function SidebarTabs({ yjs, sessionId, routeStats, days, onWaypointHover, onWaypointSelect }: { yjs: YjsState; sessionId: string; routeStats: ReturnType<typeof useRouting>["routeStats"]; days: ReturnType<typeof useDays>; onWaypointHover: (index: number | null) => void; onWaypointSelect: (index: number | null) => void }) {
const { t } = useTranslation("planner");
const [tab, setTab] = useState<"waypoints" | "notes">("waypoints");
@ -137,7 +137,7 @@ function SidebarTabs({ yjs, routeStats, days, onWaypointHover, onWaypointSelect
<div className="flex-1 overflow-hidden">
{tab === "waypoints" ? (
<Suspense fallback={null}>
<WaypointSidebar yjs={yjs} routeStats={routeStats} days={days} onWaypointHover={onWaypointHover} onWaypointSelect={onWaypointSelect} />
<WaypointSidebar yjs={yjs} sessionId={sessionId} routeStats={routeStats} days={days} onWaypointHover={onWaypointHover} onWaypointSelect={onWaypointSelect} />
</Suspense>
) : (
<NotesPanel yjs={yjs} />
@ -292,7 +292,7 @@ export function SessionView({ sessionId, hasJournalCallback, returnUrl, initialW
</div>
</Suspense>
</main>
<SidebarTabs yjs={yjs} routeStats={routeStats} days={days} onWaypointHover={setHighlightedWaypoint} onWaypointSelect={setSelectedWaypointIndex} />
<SidebarTabs yjs={yjs} sessionId={sessionId} routeStats={routeStats} days={days} onWaypointHover={setHighlightedWaypoint} onWaypointSelect={setSelectedWaypointIndex} />
</div>
<YjsDebugPanel yjs={yjs} sessionId={sessionId} />
{toasts.length > 0 && (

View file

@ -19,6 +19,7 @@ const NOTE_MAX = 500;
interface WaypointSidebarProps {
yjs: YjsState;
sessionId: string;
routeStats?: {
distance?: number;
elevationGain?: number;
@ -29,7 +30,7 @@ interface WaypointSidebarProps {
onWaypointSelect?: (index: number | null) => void;
}
export function WaypointSidebar({ yjs, routeStats, days, onWaypointHover, onWaypointSelect }: WaypointSidebarProps) {
export function WaypointSidebar({ yjs, sessionId, routeStats, days, onWaypointHover, onWaypointSelect }: WaypointSidebarProps) {
const { t } = useTranslation("planner");
const [waypoints, setWaypoints] = useState<WaypointData[]>([]);
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
@ -133,7 +134,7 @@ export function WaypointSidebar({ yjs, routeStats, days, onWaypointHover, onWayp
);
const selectedWp = selectedIndex !== null ? waypoints[selectedIndex] : undefined;
const nearbyPoisState = useNearbyPois(selectedWp?.lat, selectedWp?.lon);
const nearbyPoisState = useNearbyPois(selectedWp?.lat, selectedWp?.lon, sessionId);
const [showAllNearby, setShowAllNearby] = useState(false);
const hasMultipleDays = days.length > 1;

View file

@ -144,7 +144,7 @@ describe("fetchNearbyPois", () => {
afterEach(() => vi.unstubAllGlobals());
it("builds a bbox around the point and calls /api/pois", async () => {
await fetchNearbyPois(50.0, 10.0, 500, drinkingWater);
await fetchNearbyPois(50.0, 10.0, 500, drinkingWater, "sess");
expect(fetch).toHaveBeenCalledOnce();
const [url] = (fetch as ReturnType<typeof vi.fn>).mock.calls[0] as [string];
expect(url).toMatch(/\/api\/pois\?bbox=\d+\.\d+,\d+\.\d+,\d+\.\d+,\d+\.\d+/);
@ -153,7 +153,7 @@ describe("fetchNearbyPois", () => {
it("forwards the AbortSignal to fetch", async () => {
const controller = new AbortController();
await fetchNearbyPois(50.0, 10.0, 500, drinkingWater, controller.signal);
await fetchNearbyPois(50.0, 10.0, 500, drinkingWater, "sess", controller.signal);
const [, opts] = (fetch as ReturnType<typeof vi.fn>).mock.calls[0] as [string, RequestInit];
expect(opts.signal).toBe(controller.signal);
});

View file

@ -133,8 +133,8 @@ export async function fetchNearbyPois(
lon: number,
radiusMeters: number,
categories: PoiCategory[],
sessionId: string,
signal?: AbortSignal,
sessionId = "nearby",
): Promise<Poi[]> {
const dLat = radiusMeters * DEG_PER_METER_LAT;
const dLon = dLat / Math.cos((lat * Math.PI) / 180);

View file

@ -19,6 +19,7 @@ const rateLimitedUntilRef = { current: 0 };
export function useNearbyPois(
lat: number | undefined,
lon: number | undefined,
sessionId: string,
): NearbyPoisState {
const [state, setState] = useState<NearbyPoisState>({ pois: [], status: "idle" });
const abortRef = useRef<AbortController | null>(null);
@ -47,7 +48,7 @@ export function useNearbyPois(
setState((prev) => ({ ...prev, status: "loading" }));
try {
const pois = await fetchNearbyPois(lat, lon, NEARBY_RADIUS_METERS, poiCategories, controller.signal);
const pois = await fetchNearbyPois(lat, lon, NEARBY_RADIUS_METERS, poiCategories, sessionId, controller.signal);
if (!controller.signal.aborted) {
setState({ pois, status: "done" });
}
@ -68,7 +69,7 @@ export function useNearbyPois(
if (timerRef.current) clearTimeout(timerRef.current);
abortRef.current?.abort();
};
}, [lat, lon]);
}, [lat, lon, sessionId]);
return state;
}