Refactor API routes and hooks to use library clients
- Wire `api/geocode` and `api/bike-route` to use `GeocodingClient` and `BikeRoutingClient` instead of raw fetch calls - Move `parseHafasJourneys` from `useJourneys` to `hafas-client` - Remove dead code `src/lib/live-status-utils.ts` - Update test setup to import `@testing-library/jest-dom/vitest`
This commit is contained in:
@@ -1,67 +1,14 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import type { Journey } from "@/types";
|
||||
import { parseHafasTime, hafasDateTime } from "@/lib/hafas-time";
|
||||
import { parseHafasJourneys } from "@/lib/hafas-client";
|
||||
import { hafasDateTime } from "@/lib/hafas-time";
|
||||
|
||||
interface HafasJourney {
|
||||
ctxRecon?: string;
|
||||
secL?: Array<{
|
||||
dep?: { dTimeS?: string; dTimeR?: string; dPlatfS?: string };
|
||||
arr?: { aTimeS?: string; aTimeR?: string };
|
||||
jny?: {
|
||||
prodX?: number;
|
||||
stopL?: Array<{ name: string }>;
|
||||
dlySum?: number;
|
||||
isCncl?: boolean;
|
||||
};
|
||||
chgDurR?: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
function parseHafasJourneys(json: unknown, hafasDate: string, queryDate: Date): Journey[] {
|
||||
// HAFAS response shape is too complex for a clean TypeScript type; use any for parsing.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- HAFAS response shape is undocumented and deeply nested
|
||||
const data = json as any;
|
||||
const outConL: HafasJourney[] = data?.svcResL?.[0]?.res?.outConL ?? [];
|
||||
|
||||
return outConL.map((con, i): Journey => {
|
||||
const first = con.secL?.[0];
|
||||
const last = con.secL?.[con.secL.length - 1];
|
||||
const dep = first?.dep;
|
||||
const arr = last?.arr;
|
||||
|
||||
const sD = dep?.dTimeS ? parseHafasTime(hafasDate, dep.dTimeS) : queryDate;
|
||||
const rD = dep?.dTimeR ? parseHafasTime(hafasDate, dep.dTimeR) : sD;
|
||||
const sA = arr?.aTimeS ? parseHafasTime(hafasDate, arr.aTimeS) : sD;
|
||||
const rA = arr?.aTimeR ? parseHafasTime(hafasDate, arr.aTimeR) : sA;
|
||||
|
||||
const delayMs = rD.getTime() - sD.getTime();
|
||||
const delay = Math.max(0, Math.round(delayMs / 60000));
|
||||
|
||||
const trains = (con.secL ?? [])
|
||||
.filter((s) => s.jny)
|
||||
.map((s) => s.jny?.stopL?.[0]?.name ?? "")
|
||||
.filter(Boolean);
|
||||
|
||||
const cancelled = (con.secL ?? []).some((s) => s.jny?.isCncl === true);
|
||||
const changes = Math.max(0, (con.secL ?? []).filter((s) => s.jny).length - 1);
|
||||
const platform = first?.dep?.dPlatfS ?? "";
|
||||
|
||||
return {
|
||||
id: con.ctxRecon ?? `journey-${i}`,
|
||||
sD,
|
||||
rD,
|
||||
sA,
|
||||
rA,
|
||||
delay,
|
||||
platform,
|
||||
changes,
|
||||
trains,
|
||||
cancelled,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function useJourneys(fromStationExtId: string | null, toStationExtId: string | null, date: Date, refreshKey = 0) {
|
||||
export function useJourneys(
|
||||
fromStationExtId: string | null,
|
||||
toStationExtId: string | null,
|
||||
date: Date,
|
||||
refreshKey = 0,
|
||||
) {
|
||||
const [journeys, setJourneys] = useState<Journey[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
Reference in New Issue
Block a user