@mytec: iter7 ready for test

This commit is contained in:
2026-01-30 13:06:31 +02:00
parent baebd29e1a
commit 3e1061e369
12 changed files with 592 additions and 39 deletions

View File

@@ -0,0 +1,74 @@
import { useState, useEffect } from 'react';
import { useMap } from 'react-leaflet';
import L from 'leaflet';
interface ElevationState {
elevation: number | null;
position: { lat: number; lon: number } | null;
loading: boolean;
}
export function useElevation() {
const map = useMap();
const [state, setState] = useState<ElevationState>({
elevation: null,
position: null,
loading: false,
});
useEffect(() => {
let timeoutId: number;
let abortController: AbortController | null = null;
const handleMouseMove = (e: L.LeafletMouseEvent) => {
setState((prev) => ({
...prev,
position: { lat: e.latlng.lat, lon: e.latlng.lng },
}));
// Debounce API calls (300ms)
clearTimeout(timeoutId);
if (abortController) abortController.abort();
timeoutId = window.setTimeout(async () => {
setState((prev) => ({ ...prev, loading: true }));
abortController = new AbortController();
try {
const response = await fetch(
`https://api.open-elevation.com/api/v1/lookup?locations=${e.latlng.lat},${e.latlng.lng}`,
{ signal: abortController.signal }
);
const data = await response.json();
const elev = data?.results?.[0]?.elevation ?? null;
setState((prev) => ({ ...prev, elevation: elev, loading: false }));
} catch (error: unknown) {
if (error instanceof DOMException && error.name === 'AbortError') {
// Intentional abort, ignore
return;
}
console.error('Elevation fetch failed:', error);
setState((prev) => ({ ...prev, elevation: null, loading: false }));
}
}, 300);
};
const handleMouseOut = () => {
clearTimeout(timeoutId);
if (abortController) abortController.abort();
setState({ elevation: null, position: null, loading: false });
};
map.on('mousemove', handleMouseMove);
map.on('mouseout', handleMouseOut);
return () => {
map.off('mousemove', handleMouseMove);
map.off('mouseout', handleMouseOut);
clearTimeout(timeoutId);
if (abortController) abortController.abort();
};
}, [map]);
return state;
}