More fixes
This commit is contained in:
parent
791bc6976b
commit
14a3555cf1
21 changed files with 549 additions and 99 deletions
46
frontend/src/hooks/useTravelDestinations.ts
Normal file
46
frontend/src/hooks/useTravelDestinations.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { useState, useEffect, useRef } from 'react';
|
||||
import { authHeaders, logNonAbortError } from '../lib/api';
|
||||
import type { TransportMode } from './useTravelTime';
|
||||
|
||||
export interface Destination {
|
||||
name: string;
|
||||
slug: string;
|
||||
place_type: string;
|
||||
city?: string;
|
||||
}
|
||||
|
||||
/** Fetches all travel-time destinations for a mode once, with client-side caching. */
|
||||
export function useTravelDestinations(mode: TransportMode) {
|
||||
const [destinations, setDestinations] = useState<Destination[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const cacheRef = useRef<Partial<Record<TransportMode, Destination[]>>>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (cacheRef.current[mode]) {
|
||||
setDestinations(cacheRef.current[mode]!);
|
||||
return;
|
||||
}
|
||||
|
||||
const controller = new AbortController();
|
||||
setLoading(true);
|
||||
|
||||
fetch(
|
||||
`/api/travel-destinations?mode=${mode}`,
|
||||
authHeaders({ signal: controller.signal }),
|
||||
)
|
||||
.then((res) => {
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
return res.json();
|
||||
})
|
||||
.then((data: { destinations: Destination[] }) => {
|
||||
cacheRef.current[mode] = data.destinations;
|
||||
setDestinations(data.destinations);
|
||||
})
|
||||
.catch((err) => logNonAbortError('travel destinations', err))
|
||||
.finally(() => setLoading(false));
|
||||
|
||||
return () => controller.abort();
|
||||
}, [mode]);
|
||||
|
||||
return { destinations, loading };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue