99 lines
2.7 KiB
TypeScript
99 lines
2.7 KiB
TypeScript
import { useState, useEffect } from "react";
|
|
import type { Station } from "@/types";
|
|
import { DEFAULT_STATION_NAME, DEFAULT_STATION_EXT_ID } from "@/lib/constants";
|
|
import { useGeolocation } from "./useGeolocation";
|
|
|
|
interface HafasLocation {
|
|
type: string;
|
|
name: string;
|
|
extId: string;
|
|
lat: number;
|
|
lon: number;
|
|
}
|
|
|
|
export function useOriginStation() {
|
|
const [station, setStation] = useState<Station | null>(null);
|
|
const [loading, setLoading] = useState<boolean>(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const { location, state } = useGeolocation();
|
|
|
|
useEffect(() => {
|
|
let isMounted = true;
|
|
|
|
const fetchNearestStation = async () => {
|
|
if (!location || state !== "granted") {
|
|
if (isMounted) {
|
|
setStation({ name: DEFAULT_STATION_NAME, extId: DEFAULT_STATION_EXT_ID });
|
|
}
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const { latitude, longitude } = location.coords;
|
|
|
|
// Use HAFAS LocMatch with coordinates to find nearest station
|
|
const body = {
|
|
svcReqL: [
|
|
{
|
|
meth: "LocMatch",
|
|
req: {
|
|
input: {
|
|
loc: {
|
|
lat: latitude,
|
|
lon: longitude,
|
|
type: "S",
|
|
},
|
|
maxLoc: 5,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
};
|
|
|
|
const response = await fetch("/api/hafas", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(body),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HAFAS request failed with status ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
const match = data?.svcResL?.[0]?.res?.match?.locL ?? [];
|
|
const stations: Station[] = (match as HafasLocation[])
|
|
.filter((l) => l.type === "S")
|
|
.map((l) => ({ name: l.name, extId: l.extId, lat: l.lat, lng: l.lon }));
|
|
|
|
if (!isMounted) return;
|
|
|
|
if (stations.length > 0) {
|
|
setStation(stations[0]);
|
|
} else {
|
|
setStation({ name: DEFAULT_STATION_NAME, extId: DEFAULT_STATION_EXT_ID });
|
|
}
|
|
setLoading(false);
|
|
} catch (err: unknown) {
|
|
if (isMounted) {
|
|
const message = err instanceof Error ? err.message : "Failed to find nearest station";
|
|
setError(message);
|
|
setStation({ name: DEFAULT_STATION_NAME, extId: DEFAULT_STATION_EXT_ID });
|
|
setLoading(false);
|
|
}
|
|
}
|
|
};
|
|
|
|
fetchNearestStation();
|
|
|
|
return () => {
|
|
isMounted = false;
|
|
};
|
|
}, [location, state]);
|
|
|
|
return { station, loading, error };
|
|
}
|