From 58302dc9e4fe5fd375dfe1efe26fad94dd40a2ae Mon Sep 17 00:00:00 2001 From: Maurice Date: Tue, 20 Oct 2026 18:05:40 +0200 Subject: [PATCH] fix(tours): keep the planner page hook's view model its only object return The map focus helpers split out of useTripPlannerPage returned object literals ahead of the hook's own return, which the B4A wiring test reads as the view model. They move to tourMapFocus.ts beside the hook. --- client/src/pages/tripPlanner/tourMapFocus.ts | 41 +++++++++++++++++++ .../pages/tripPlanner/useTripPlannerPage.ts | 37 +---------------- 2 files changed, 42 insertions(+), 36 deletions(-) create mode 100644 client/src/pages/tripPlanner/tourMapFocus.ts diff --git a/client/src/pages/tripPlanner/tourMapFocus.ts b/client/src/pages/tripPlanner/tourMapFocus.ts new file mode 100644 index 000000000..536f5381a --- /dev/null +++ b/client/src/pages/tripPlanner/tourMapFocus.ts @@ -0,0 +1,41 @@ +import type { useMapLocationSearch } from './useMapLocationSearch' +import type { useTourWorkspace } from './useTourWorkspace' + +// The planner page hook's pure helpers: what the Tours map draws and frames. +// They live apart so the page hook's one object-literal return stays its view model. + +type Workspace = ReturnType +type TourPlanner = Workspace['tourPlanner'] + +/** PAD-05B: the paddle line in view, a recorded paddle track's or the paddle tour's being planned; none for any other. */ +export function paddleLineOf(tourPlanner: TourPlanner) { + if (tourPlanner.mode.type === 'view-gpx') { + return tourPlanner.mode.tour.tour_type === 'kayak' ? tourPlanner.readOnlyGpxAnalysis?.routeCoordinates ?? null : null + } + return tourPlanner.isPaddle ? tourPlanner.route : null +} + +/** + * RTE-02, RTE-03: the ways offered over the route being edited (a section's + * ways being compared, else the round hikes), the one in focus, and the frame + * round hikes ask the map for while they are looked for and shown. + */ +export function offeredWaysOf(tourPlanner: TourPlanner, offering: boolean) { + const { comparison, focus: variantFocus } = tourPlanner.legVariants + const { view: rounds, focus: roundFocus, frame: roundFrame } = tourPlanner.roundHikes + return { + ways: offering ? comparison?.variants ?? rounds?.candidates ?? null : null, + focus: comparison ? variantFocus : roundFocus, + frame: offering ? roundFrame : null, + } +} + +/** What frames the map: a picked wanderer trail itself, else round hikes being framed, else the planner. */ +export function mapFocusKeyOf( + wandererBrowser: Workspace['wandererBrowser'], + frame: ReturnType['frame'], + plannerKey: ReturnType['mapFocusKey'], +) { + if (wandererBrowser.open && wandererBrowser.selected) return `wanderer:${wandererBrowser.selected.id}` + return frame?.key ?? plannerKey +} diff --git a/client/src/pages/tripPlanner/useTripPlannerPage.ts b/client/src/pages/tripPlanner/useTripPlannerPage.ts index 7001219d9..5e9312e93 100644 --- a/client/src/pages/tripPlanner/useTripPlannerPage.ts +++ b/client/src/pages/tripPlanner/useTripPlannerPage.ts @@ -14,42 +14,7 @@ import { useMapLocationSearch } from './useMapLocationSearch' import { usePlannerFocusPoints } from './usePlannerFocusPoints' import { useTripPlanner } from './useTripPlanner' import { useTourWorkspace } from './useTourWorkspace' - -type Workspace = ReturnType -type TourPlanner = Workspace['tourPlanner'] - -/** PAD-05B: the paddle line in view, a recorded paddle track's or the paddle tour's being planned; none for any other. */ -function paddleLineOf(tourPlanner: TourPlanner) { - if (tourPlanner.mode.type === 'view-gpx') { - return tourPlanner.mode.tour.tour_type === 'kayak' ? tourPlanner.readOnlyGpxAnalysis?.routeCoordinates ?? null : null - } - return tourPlanner.isPaddle ? tourPlanner.route : null -} - -/** - * RTE-02, RTE-03: the ways offered over the route being edited (a section's - * ways being compared, else the round hikes), the one in focus, and the frame - * round hikes ask the map for while they are looked for and shown. - */ -function offeredWaysOf(tourPlanner: TourPlanner, offering: boolean) { - const { comparison, focus: variantFocus } = tourPlanner.legVariants - const { view: rounds, focus: roundFocus, frame: roundFrame } = tourPlanner.roundHikes - return { - ways: offering ? comparison?.variants ?? rounds?.candidates ?? null : null, - focus: comparison ? variantFocus : roundFocus, - frame: offering ? roundFrame : null, - } -} - -/** What frames the map: a picked wanderer trail itself, else round hikes being framed, else the planner. */ -function mapFocusKeyOf( - wandererBrowser: Workspace['wandererBrowser'], - frame: ReturnType['frame'], - plannerKey: ReturnType['mapFocusKey'], -) { - if (wandererBrowser.open && wandererBrowser.selected) return `wanderer:${wandererBrowser.selected.id}` - return frame?.key ?? plannerKey -} +import { mapFocusKeyOf, offeredWaysOf, paddleLineOf } from './tourMapFocus' export function useTripPlannerPage() { const planner = useTripPlanner()