aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/app/hooks')
-rw-r--r--src/frontend/app/hooks/usePlanQuery.ts29
-rw-r--r--src/frontend/app/hooks/usePlanner.ts93
2 files changed, 80 insertions, 42 deletions
diff --git a/src/frontend/app/hooks/usePlanQuery.ts b/src/frontend/app/hooks/usePlanQuery.ts
new file mode 100644
index 0000000..103f5f4
--- /dev/null
+++ b/src/frontend/app/hooks/usePlanQuery.ts
@@ -0,0 +1,29 @@
+import { useQuery } from "@tanstack/react-query";
+import { fetchPlan } from "../api/planner";
+
+export const usePlanQuery = (
+ fromLat: number | undefined,
+ fromLon: number | undefined,
+ toLat: number | undefined,
+ toLon: number | undefined,
+ time?: Date,
+ arriveBy: boolean = false,
+ enabled: boolean = true
+) => {
+ return useQuery({
+ queryKey: [
+ "plan",
+ fromLat,
+ fromLon,
+ toLat,
+ toLon,
+ time?.toISOString(),
+ arriveBy,
+ ],
+ queryFn: () =>
+ fetchPlan(fromLat!, fromLon!, toLat!, toLon!, time, arriveBy),
+ enabled: !!(fromLat && fromLon && toLat && toLon) && enabled,
+ staleTime: 60000, // 1 minute
+ retry: false,
+ });
+};
diff --git a/src/frontend/app/hooks/usePlanner.ts b/src/frontend/app/hooks/usePlanner.ts
index 6123f8a..a28167a 100644
--- a/src/frontend/app/hooks/usePlanner.ts
+++ b/src/frontend/app/hooks/usePlanner.ts
@@ -1,9 +1,6 @@
import { useCallback, useEffect, useState } from "react";
-import {
- type PlannerSearchResult,
- type RoutePlan,
- planRoute,
-} from "../data/PlannerApi";
+import { type PlannerSearchResult, type RoutePlan } from "../data/PlannerApi";
+import { usePlanQuery } from "./usePlanQuery";
const STORAGE_KEY = "planner_last_route";
const EXPIRY_MS = 2 * 60 * 60 * 1000; // 2 hours
@@ -32,6 +29,48 @@ export function usePlanner() {
number | null
>(null);
+ const {
+ data: queryPlan,
+ isLoading: queryLoading,
+ error: queryError,
+ isFetching,
+ } = usePlanQuery(
+ origin?.lat,
+ origin?.lon,
+ destination?.lat,
+ destination?.lon,
+ searchTime ?? undefined,
+ arriveBy,
+ !!(origin && destination)
+ );
+
+ // Sync query result to local state and storage
+ useEffect(() => {
+ if (queryPlan) {
+ setPlan(queryPlan as any); // Cast because of slight type differences if any, but they should match now
+
+ if (origin && destination) {
+ const toStore: StoredRoute = {
+ timestamp: Date.now(),
+ origin,
+ destination,
+ plan: queryPlan as any,
+ searchTime: searchTime ?? new Date(),
+ arriveBy,
+ selectedItineraryIndex: selectedItineraryIndex ?? undefined,
+ };
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore));
+ }
+ }
+ }, [
+ queryPlan,
+ origin,
+ destination,
+ searchTime,
+ arriveBy,
+ selectedItineraryIndex,
+ ]);
+
// Load from storage on mount
useEffect(() => {
const stored = localStorage.getItem(STORAGE_KEY);
@@ -60,41 +99,11 @@ export function usePlanner() {
time?: Date,
arriveByParam: boolean = false
) => {
- setLoading(true);
- setError(null);
- try {
- const result = await planRoute(
- from.lat,
- from.lon,
- to.lat,
- to.lon,
- time,
- arriveByParam
- );
- setPlan(result);
- setOrigin(from);
- setDestination(to);
- setSearchTime(time ?? new Date());
- setArriveBy(arriveByParam);
- setSelectedItineraryIndex(null); // Reset when doing new search
-
- // Save to storage
- const toStore: StoredRoute = {
- timestamp: Date.now(),
- origin: from,
- destination: to,
- plan: result,
- searchTime: time ?? new Date(),
- arriveBy: arriveByParam,
- selectedItineraryIndex: undefined,
- };
- localStorage.setItem(STORAGE_KEY, JSON.stringify(toStore));
- } catch (err) {
- setError("Failed to calculate route. Please try again.");
- setPlan(null);
- } finally {
- setLoading(false);
- }
+ setOrigin(from);
+ setDestination(to);
+ setSearchTime(time ?? new Date());
+ setArriveBy(arriveByParam);
+ setSelectedItineraryIndex(null);
};
const clearRoute = () => {
@@ -145,8 +154,8 @@ export function usePlanner() {
destination,
setDestination,
plan,
- loading,
- error,
+ loading: queryLoading || (isFetching && !plan),
+ error: queryError ? "Failed to calculate route. Please try again." : null,
searchTime,
arriveBy,
selectedItineraryIndex,