Auto-enable POI categories on routing profile change

useProfileDefaults hook observes profile changes in Yjs and merges
relevant POI categories into the enabled set. Skips initial load to
respect existing state. Cycling profiles → bike infra, hiking →
shelter + viewpoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ullrich Schäfer 2026-04-11 02:19:30 +02:00
parent be36a5f650
commit 22c5ebd838
No known key found for this signature in database
GPG key ID: A32FF691A0F752D9
4 changed files with 51 additions and 4 deletions

View file

@ -10,6 +10,7 @@ import { parseGpxAsync, extractWaypoints } from "@trails-cool/gpx";
import { isOvernight } from "~/lib/overnight";
import { setOvernight } from "~/lib/overnight";
import { usePois } from "~/lib/use-pois";
import { useProfileDefaults } from "~/lib/use-profile-defaults";
import { snapToPoi } from "~/lib/poi-snap";
import { Z_CURSOR, Z_WAYPOINT, Z_WAYPOINT_HIGHLIGHTED, Z_HIGHLIGHT } from "~/lib/z-index";
import { NoGoAreaLayer } from "./NoGoAreaLayer";
@ -278,6 +279,7 @@ export function PlannerMap({ yjs, onRouteRequest, highlightPosition, highlighted
const { t } = useTranslation("planner");
const [waypoints, setWaypoints] = useState<WaypointData[]>([]);
const poiState = usePois();
useProfileDefaults(yjs, poiState);
const [draggingOver, setDraggingOver] = useState(false);
const dragCounterRef = useRef(0);
const [routeCoordinates, setRouteCoordinates] = useState<[number, number, number][] | null>(null);

View file

@ -15,7 +15,7 @@ export interface PoiState {
pois: Poi[];
status: PoiStatus;
enabledCategories: string[];
setEnabledCategories: (ids: string[]) => void;
setEnabledCategories: React.Dispatch<React.SetStateAction<string[]>>;
toggleCategory: (id: string) => void;
refresh: (bbox: BBox, zoom: number) => void;
}

View file

@ -0,0 +1,45 @@
import { useEffect, useRef } from "react";
import type { YjsState } from "./use-yjs.ts";
import type { PoiState } from "./use-pois.ts";
import { getCategoriesForProfile } from "./poi-categories.ts";
/**
* Auto-enable relevant POI categories when the routing profile changes.
* Only triggers on explicit profile changes (not initial load).
*/
export function useProfileDefaults(yjs: YjsState | null, poiState: PoiState): void {
const initializedRef = useRef(false);
const prevProfileRef = useRef<string | null>(null);
useEffect(() => {
if (!yjs) return;
const handleChange = () => {
const profile = yjs.routeData.get("profile") as string | undefined;
if (!profile) return;
// Skip initial load — respect existing state
if (!initializedRef.current) {
initializedRef.current = true;
prevProfileRef.current = profile;
return;
}
// Only act on actual profile changes
if (profile === prevProfileRef.current) return;
prevProfileRef.current = profile;
// Auto-enable POI categories for this profile
const defaultCategories = getCategoriesForProfile(profile);
if (defaultCategories.length > 0) {
poiState.setEnabledCategories((prev: string[]) => {
const merged = new Set([...prev, ...defaultCategories]);
return [...merged];
});
}
};
yjs.routeData.observe(handleChange);
return () => yjs.routeData.unobserve(handleChange);
}, [yjs, poiState.setEnabledCategories]);
}

View file

@ -47,9 +47,9 @@
## 8. Profile-Aware Defaults
- [ ] 8.1 Define profile-to-overlay mapping (cycling → waymarked-cycling + bike POIs, hiking → waymarked-hiking + shelter + viewpoints, MTB → waymarked-mtb + bike POIs)
- [ ] 8.2 Auto-enable mapped overlays on routing profile change (update Yjs arrays)
- [ ] 8.3 Only auto-enable on explicit profile change, not on initial page load (respect existing Yjs state)
- [x] 8.1 Define profile-to-overlay mapping (cycling → waymarked-cycling + bike POIs, hiking → waymarked-hiking + shelter + viewpoints, MTB → waymarked-mtb + bike POIs)
- [x] 8.2 Auto-enable mapped overlays on routing profile change (update Yjs arrays)
- [x] 8.3 Only auto-enable on explicit profile change, not on initial page load (respect existing Yjs state)
## 9. i18n