diff --git a/client/src/components/Admin/DefaultUserSettingsTab.tsx b/client/src/components/Admin/DefaultUserSettingsTab.tsx index 2f0a3865..13d57d8f 100644 --- a/client/src/components/Admin/DefaultUserSettingsTab.tsx +++ b/client/src/components/Admin/DefaultUserSettingsTab.tsx @@ -20,7 +20,6 @@ type Defaults = { temperature_unit?: string dark_mode?: string | boolean time_format?: string - route_calculation?: boolean blur_booking_codes?: boolean map_tile_url?: string } @@ -208,22 +207,6 @@ export default function DefaultUserSettingsTab(): React.ReactElement { ))} - {/* Route Calculation */} - {t('settings.routeCalculation')} }> - {([ - { value: true, label: t('settings.on') || 'On' }, - { value: false, label: t('settings.off') || 'Off' }, - ] as const).map(opt => ( - save({ route_calculation: opt.value })} - > - {opt.label} - - ))} - - {/* Blur Booking Codes */} {t('settings.blurBookingCodes')} }> {([ diff --git a/client/src/components/Planner/DayPlanSidebar.tsx b/client/src/components/Planner/DayPlanSidebar.tsx index a8cd7aba..24983ab6 100644 --- a/client/src/components/Planner/DayPlanSidebar.tsx +++ b/client/src/components/Planner/DayPlanSidebar.tsx @@ -260,7 +260,6 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar({ const { t, language, locale } = useTranslation() const ctxMenu = useContextMenu() const timeFormat = useSettingsStore(s => s.settings.time_format) || '24h' - const routeCalcEnabled = useSettingsStore(s => s.settings.route_calculation) !== false const tripActions = useRef(useTripStore.getState()).current const can = useCanDo() const canEditDays = can('day_edit', trip) @@ -507,7 +506,7 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar({ // the start place's assignment id. Shares RouteCalculator's cache with the map. useEffect(() => { if (legsAbortRef.current) legsAbortRef.current.abort() - if (!selectedDayId || !routeCalcEnabled || !routeShown) { setRouteLegs({}); return } + if (!selectedDayId || !routeShown) { setRouteLegs({}); return } const merged = mergedItemsMap[selectedDayId] || [] const runs: { id: number; lat: number; lng: number }[][] = [] let cur: { id: number; lat: number; lng: number }[] = [] @@ -536,7 +535,7 @@ const DayPlanSidebar = React.memo(function DayPlanSidebar({ } if (!controller.signal.aborted) setRouteLegs(map) })() - }, [selectedDayId, routeCalcEnabled, routeShown, routeProfile, mergedItemsMap]) + }, [selectedDayId, routeShown, routeProfile, mergedItemsMap]) const openAddNote = (dayId, e) => { e?.stopPropagation() diff --git a/client/src/components/Planner/ReservationsPanel.test.tsx b/client/src/components/Planner/ReservationsPanel.test.tsx index 0f9e01a6..9666b2bf 100644 --- a/client/src/components/Planner/ReservationsPanel.test.tsx +++ b/client/src/components/Planner/ReservationsPanel.test.tsx @@ -27,7 +27,7 @@ beforeEach(() => { resetAllStores(); seedStore(useAuthStore, { user: buildUser(), isAuthenticated: true }); seedStore(useTripStore, { trip: buildTrip({ id: 1 }) }); - seedStore(useSettingsStore, { settings: { time_format: '24h', blur_booking_codes: false, temperature_unit: 'celsius', language: 'en', dark_mode: false, default_currency: 'USD', default_lat: 48.8566, default_lng: 2.3522, default_zoom: 10, map_tile_url: '', show_place_description: false, route_calculation: false } }); + seedStore(useSettingsStore, { settings: { time_format: '24h', blur_booking_codes: false, temperature_unit: 'celsius', language: 'en', dark_mode: false, default_currency: 'USD', default_lat: 48.8566, default_lng: 2.3522, default_zoom: 10, map_tile_url: '', show_place_description: false } }); }); describe('ReservationsPanel', () => { @@ -211,7 +211,7 @@ describe('ReservationsPanel', () => { }); it('FE-PLANNER-RESP-022: confirmation number is blurred when blur_booking_codes=true', () => { - seedStore(useSettingsStore, { settings: { time_format: '24h', blur_booking_codes: true, temperature_unit: 'celsius', language: 'en', dark_mode: false, default_currency: 'USD', default_lat: 48.8566, default_lng: 2.3522, default_zoom: 10, map_tile_url: '', show_place_description: false, route_calculation: false } }); + seedStore(useSettingsStore, { settings: { time_format: '24h', blur_booking_codes: true, temperature_unit: 'celsius', language: 'en', dark_mode: false, default_currency: 'USD', default_lat: 48.8566, default_lng: 2.3522, default_zoom: 10, map_tile_url: '', show_place_description: false } }); const res = buildReservation({ confirmation_number: 'ABC123', status: 'confirmed' }); render(); const codeEl = screen.getByText('ABC123'); @@ -220,7 +220,7 @@ describe('ReservationsPanel', () => { it('FE-PLANNER-RESP-023: confirmation code revealed on hover when blurred', async () => { const user = userEvent.setup(); - seedStore(useSettingsStore, { settings: { time_format: '24h', blur_booking_codes: true, temperature_unit: 'celsius', language: 'en', dark_mode: false, default_currency: 'USD', default_lat: 48.8566, default_lng: 2.3522, default_zoom: 10, map_tile_url: '', show_place_description: false, route_calculation: false } }); + seedStore(useSettingsStore, { settings: { time_format: '24h', blur_booking_codes: true, temperature_unit: 'celsius', language: 'en', dark_mode: false, default_currency: 'USD', default_lat: 48.8566, default_lng: 2.3522, default_zoom: 10, map_tile_url: '', show_place_description: false } }); const res = buildReservation({ confirmation_number: 'ABC123', status: 'confirmed' }); render(); const codeEl = screen.getByText('ABC123'); diff --git a/client/src/components/Settings/DisplaySettingsTab.test.tsx b/client/src/components/Settings/DisplaySettingsTab.test.tsx index d0ff467e..51f1b80b 100644 --- a/client/src/components/Settings/DisplaySettingsTab.test.tsx +++ b/client/src/components/Settings/DisplaySettingsTab.test.tsx @@ -161,29 +161,6 @@ describe('DisplaySettingsTab', () => { expect(updateSetting).toHaveBeenCalledWith('time_format', '24h'); }); - it('FE-COMP-DISPLAY-021: shows Route Calculation section', () => { - render(); - expect(screen.getByText(/route calculation/i)).toBeInTheDocument(); - }); - - it('FE-COMP-DISPLAY-022: route calculation On button is active when route_calculation is true', () => { - seedStore(useSettingsStore, { settings: buildSettings({ route_calculation: true }) }); - render(); - const onButtons = screen.getAllByText(/^On$/i); - const routeCalcOnBtn = onButtons[0].closest('button')!; - expect(routeCalcOnBtn.style.border).toContain('var(--text-primary)'); - }); - - it('FE-COMP-DISPLAY-023: clicking route calculation Off calls updateSetting with false', async () => { - const user = userEvent.setup(); - const updateSetting = vi.fn().mockResolvedValue(undefined); - seedStore(useSettingsStore, { settings: buildSettings({ route_calculation: true }), updateSetting }); - render(); - const offButtons = screen.getAllByText(/^Off$/i); - await user.click(offButtons[0]); - expect(updateSetting).toHaveBeenCalledWith('route_calculation', false); - }); - it('FE-COMP-DISPLAY-024: shows Blur Booking Codes section', () => { render(); expect(screen.getByText(/blur booking codes/i)).toBeInTheDocument(); diff --git a/client/src/components/Settings/DisplaySettingsTab.tsx b/client/src/components/Settings/DisplaySettingsTab.tsx index 575041f9..b645ae54 100644 --- a/client/src/components/Settings/DisplaySettingsTab.tsx +++ b/client/src/components/Settings/DisplaySettingsTab.tsx @@ -214,36 +214,6 @@ export default function DisplaySettingsTab(): React.ReactElement { - {/* Route Calculation */} -
- -
- {[ - { value: true, label: t('settings.on') || 'On' }, - { value: false, label: t('settings.off') || 'Off' }, - ].map(opt => ( - - ))} -
-
- {/* Booking route labels */}
diff --git a/client/src/hooks/useRouteCalculation.ts b/client/src/hooks/useRouteCalculation.ts index 13c15058..142b8168 100644 --- a/client/src/hooks/useRouteCalculation.ts +++ b/client/src/hooks/useRouteCalculation.ts @@ -1,5 +1,4 @@ import { useState, useCallback, useRef, useEffect, useMemo } from 'react' -import { useSettingsStore } from '../store/settingsStore' import { useTripStore } from '../store/tripStore' import { calculateRouteWithLegs } from '../components/Map/RouteCalculator' import type { TripStoreState } from '../store/tripStore' @@ -9,14 +8,13 @@ const TRANSPORT_TYPES = ['flight', 'train', 'bus', 'car', 'cruise'] /** * Manages route calculation state for a selected day. Extracts geo-coded waypoints from - * day assignments, draws a straight-line route, and optionally fetches per-segment - * driving/walking durations via OSRM. Aborts in-flight requests when the day changes. + * day assignments, draws a straight-line route immediately, then upgrades it to real OSRM + * road geometry with per-segment durations. Aborts in-flight requests when the day changes. */ export function useRouteCalculation(tripStore: TripStoreState, selectedDayId: number | null, enabled: boolean = true, profile: 'driving' | 'walking' | 'cycling' = 'driving') { const [route, setRoute] = useState<[number, number][][] | null>(null) const [routeInfo, setRouteInfo] = useState(null) const [routeSegments, setRouteSegments] = useState([]) - const routeCalcEnabled = useSettingsStore((s) => s.settings.route_calculation) !== false const routeAbortRef = useRef(null) const reservationsForSignature = useTripStore((s) => s.reservations) @@ -88,9 +86,8 @@ export function useRouteCalculation(tripStore: TripStoreState, selectedDayId: nu if (runs.length === 0) { setRoute(null); setRouteSegments([]); return } // Draw straight lines immediately for snappiness, then upgrade to the real - // OSRM road geometry. If route calc is disabled, keep the straight lines. + // OSRM road geometry. setRoute(straightLines()) - if (!routeCalcEnabled) { setRouteSegments([]); return } const controller = new AbortController() routeAbortRef.current = controller @@ -113,7 +110,7 @@ export function useRouteCalculation(tripStore: TripStoreState, selectedDayId: nu // Aborted (day changed) — newer call owns the state. Anything else: keep straight lines. if (!(err instanceof Error) || err.name !== 'AbortError') setRouteSegments([]) } - }, [routeCalcEnabled, enabled, profile]) + }, [enabled, profile]) // Stable signature for transport reservations on the selected day — changes when a transport // is added, removed, or repositioned, ensuring route recalc fires even on transport-only reorders. diff --git a/client/src/i18n/translations/ar.ts b/client/src/i18n/translations/ar.ts index c9a54cec..5e81722e 100644 --- a/client/src/i18n/translations/ar.ts +++ b/client/src/i18n/translations/ar.ts @@ -200,7 +200,6 @@ const ar: Record = { 'settings.language': 'اللغة', 'settings.temperature': 'وحدة الحرارة', 'settings.timeFormat': 'تنسيق الوقت', - 'settings.routeCalculation': 'حساب المسار', 'settings.blurBookingCodes': 'إخفاء رموز الحجز', 'settings.notifications': 'الإشعارات', 'settings.notifyTripInvite': 'دعوات الرحلات', diff --git a/client/src/i18n/translations/br.ts b/client/src/i18n/translations/br.ts index 7fa534c1..637285d5 100644 --- a/client/src/i18n/translations/br.ts +++ b/client/src/i18n/translations/br.ts @@ -195,7 +195,6 @@ const br: Record = { 'settings.language': 'Idioma', 'settings.temperature': 'Unidade de temperatura', 'settings.timeFormat': 'Formato de hora', - 'settings.routeCalculation': 'Cálculo de rota', 'settings.blurBookingCodes': 'Ocultar códigos de reserva', 'settings.notifications': 'Notificações', 'settings.notifyTripInvite': 'Convites de viagem', diff --git a/client/src/i18n/translations/cs.ts b/client/src/i18n/translations/cs.ts index 92ea45b9..fbc035d6 100644 --- a/client/src/i18n/translations/cs.ts +++ b/client/src/i18n/translations/cs.ts @@ -196,7 +196,6 @@ const cs: Record = { 'settings.language': 'Jazyk', 'settings.temperature': 'Jednotky teploty', 'settings.timeFormat': 'Formát času', - 'settings.routeCalculation': 'Výpočet trasy', 'settings.blurBookingCodes': 'Skrýt rezervační kódy', 'settings.notifications': 'Oznámení', 'settings.notifyTripInvite': 'Pozvánky na cesty', diff --git a/client/src/i18n/translations/de.ts b/client/src/i18n/translations/de.ts index a1399ed4..5fd4823a 100644 --- a/client/src/i18n/translations/de.ts +++ b/client/src/i18n/translations/de.ts @@ -198,7 +198,6 @@ const de: Record = { 'settings.language': 'Sprache', 'settings.temperature': 'Temperatureinheit', 'settings.timeFormat': 'Zeitformat', - 'settings.routeCalculation': 'Routenberechnung', 'settings.bookingLabels': 'Orts-Labels auf Buchungsrouten', 'settings.bookingLabelsHint': 'Zeigt Bahnhofs-/Flughafennamen auf der Karte. Wenn aus, wird nur das Icon angezeigt.', 'settings.blurBookingCodes': 'Buchungscodes verbergen', diff --git a/client/src/i18n/translations/en.ts b/client/src/i18n/translations/en.ts index a1c514f6..0fb72002 100644 --- a/client/src/i18n/translations/en.ts +++ b/client/src/i18n/translations/en.ts @@ -212,7 +212,6 @@ const en: Record = { 'settings.language': 'Language', 'settings.temperature': 'Temperature Unit', 'settings.timeFormat': 'Time Format', - 'settings.routeCalculation': 'Route Calculation', 'settings.bookingLabels': 'Booking route labels', 'settings.bookingLabelsHint': 'Show station / airport names on the map. When off, only the icon is shown.', 'settings.blurBookingCodes': 'Blur Booking Codes', diff --git a/client/src/i18n/translations/es.ts b/client/src/i18n/translations/es.ts index b1865a73..70aec75f 100644 --- a/client/src/i18n/translations/es.ts +++ b/client/src/i18n/translations/es.ts @@ -196,7 +196,6 @@ const es: Record = { 'settings.language': 'Idioma', 'settings.temperature': 'Unidad de temperatura', 'settings.timeFormat': 'Formato de hora', - 'settings.routeCalculation': 'Cálculo de ruta', 'settings.blurBookingCodes': 'Difuminar códigos de reserva', 'settings.notifications': 'Notificaciones', 'settings.notifyTripInvite': 'Invitaciones de viaje', diff --git a/client/src/i18n/translations/fr.ts b/client/src/i18n/translations/fr.ts index 8337a67c..56246dac 100644 --- a/client/src/i18n/translations/fr.ts +++ b/client/src/i18n/translations/fr.ts @@ -195,7 +195,6 @@ const fr: Record = { 'settings.language': 'Langue', 'settings.temperature': 'Unité de température', 'settings.timeFormat': 'Format de l\'heure', - 'settings.routeCalculation': 'Calcul d\'itinéraire', 'settings.blurBookingCodes': 'Masquer les codes de réservation', 'settings.notifications': 'Notifications', 'settings.notifyTripInvite': 'Invitations de voyage', diff --git a/client/src/i18n/translations/hu.ts b/client/src/i18n/translations/hu.ts index 18450c69..9f365430 100644 --- a/client/src/i18n/translations/hu.ts +++ b/client/src/i18n/translations/hu.ts @@ -195,7 +195,6 @@ const hu: Record = { 'settings.language': 'Nyelv', 'settings.temperature': 'Hőmérséklet egység', 'settings.timeFormat': 'Időformátum', - 'settings.routeCalculation': 'Útvonalszámítás', 'settings.blurBookingCodes': 'Foglalási kódok elrejtése', 'settings.notifications': 'Értesítések', 'settings.notifyTripInvite': 'Utazási meghívók', diff --git a/client/src/i18n/translations/id.ts b/client/src/i18n/translations/id.ts index 283c4e88..f1807dc0 100644 --- a/client/src/i18n/translations/id.ts +++ b/client/src/i18n/translations/id.ts @@ -198,7 +198,6 @@ const id: Record = { 'settings.language': 'Bahasa', 'settings.temperature': 'Satuan Suhu', 'settings.timeFormat': 'Format Waktu', - 'settings.routeCalculation': 'Perhitungan Rute', 'settings.blurBookingCodes': 'Sembunyikan Kode Pemesanan', 'settings.notifications': 'Notifikasi', 'settings.notifyTripInvite': 'Undangan perjalanan', diff --git a/client/src/i18n/translations/it.ts b/client/src/i18n/translations/it.ts index 3e6aeae7..d4b0d59d 100644 --- a/client/src/i18n/translations/it.ts +++ b/client/src/i18n/translations/it.ts @@ -195,7 +195,6 @@ const it: Record = { 'settings.language': 'Lingua', 'settings.temperature': 'Unità di Temperatura', 'settings.timeFormat': 'Formato Ora', - 'settings.routeCalculation': 'Calcolo Percorso', 'settings.blurBookingCodes': 'Nascondi codici di prenotazione', 'settings.notifications': 'Notifiche', 'settings.notifyTripInvite': 'Inviti di viaggio', diff --git a/client/src/i18n/translations/ja.ts b/client/src/i18n/translations/ja.ts index 51eb31b4..a431db16 100644 --- a/client/src/i18n/translations/ja.ts +++ b/client/src/i18n/translations/ja.ts @@ -212,7 +212,6 @@ const ja: Record = { 'settings.language': '言語', 'settings.temperature': '温度単位', 'settings.timeFormat': '時刻形式', - 'settings.routeCalculation': '経路計算', 'settings.bookingLabels': '予約ルートのラベル', 'settings.bookingLabelsHint': '地図に駅・空港名を表示。オフ時はアイコンのみ。', 'settings.blurBookingCodes': '予約コードをぼかす', diff --git a/client/src/i18n/translations/ko.ts b/client/src/i18n/translations/ko.ts index 82a8dfc0..c3a4849f 100644 --- a/client/src/i18n/translations/ko.ts +++ b/client/src/i18n/translations/ko.ts @@ -212,7 +212,6 @@ const ko: Record = { 'settings.language': '언어', 'settings.temperature': '온도 단위', 'settings.timeFormat': '시간 형식', - 'settings.routeCalculation': '경로 계산', 'settings.bookingLabels': '예약 경로 레이블', 'settings.bookingLabelsHint': '지도에 역 / 공항 이름을 표시합니다. 끄면 아이콘만 표시됩니다.', 'settings.blurBookingCodes': '예약 코드 흐리게', diff --git a/client/src/i18n/translations/nl.ts b/client/src/i18n/translations/nl.ts index 93694977..57af57ae 100644 --- a/client/src/i18n/translations/nl.ts +++ b/client/src/i18n/translations/nl.ts @@ -195,7 +195,6 @@ const nl: Record = { 'settings.language': 'Taal', 'settings.temperature': 'Temperatuureenheid', 'settings.timeFormat': 'Tijdnotatie', - 'settings.routeCalculation': 'Routeberekening', 'settings.blurBookingCodes': 'Boekingscodes vervagen', 'settings.notifications': 'Meldingen', 'settings.notifyTripInvite': 'Reisuitnodigingen', diff --git a/client/src/i18n/translations/pl.ts b/client/src/i18n/translations/pl.ts index 205ccaab..ce085b8f 100644 --- a/client/src/i18n/translations/pl.ts +++ b/client/src/i18n/translations/pl.ts @@ -178,7 +178,6 @@ const pl: Record = { 'settings.language': 'Język', 'settings.temperature': 'Jednostka temperatury', 'settings.timeFormat': 'Format czasu', - 'settings.routeCalculation': 'Obliczanie trasy', 'settings.blurBookingCodes': 'Rozmyj kody rezerwacji', 'settings.notifications': 'Powiadomienia', 'settings.notifyTripInvite': 'Zaproszenia do podróży', diff --git a/client/src/i18n/translations/ru.ts b/client/src/i18n/translations/ru.ts index 75b2141c..967f5d3a 100644 --- a/client/src/i18n/translations/ru.ts +++ b/client/src/i18n/translations/ru.ts @@ -195,7 +195,6 @@ const ru: Record = { 'settings.language': 'Язык', 'settings.temperature': 'Единица температуры', 'settings.timeFormat': 'Формат времени', - 'settings.routeCalculation': 'Расчёт маршрута', 'settings.blurBookingCodes': 'Скрыть коды бронирования', 'settings.notifications': 'Уведомления', 'settings.notifyTripInvite': 'Приглашения в поездку', diff --git a/client/src/i18n/translations/tr.ts b/client/src/i18n/translations/tr.ts index f359f84d..d2637fb0 100644 --- a/client/src/i18n/translations/tr.ts +++ b/client/src/i18n/translations/tr.ts @@ -212,7 +212,6 @@ const tr: Record = { 'settings.language': 'Dil', 'settings.temperature': 'Sıcaklık birimi', 'settings.timeFormat': 'Saat biçimi', - 'settings.routeCalculation': 'Route Calculation', 'settings.bookingLabels': 'Booking route labels', 'settings.bookingLabelsHint': 'Show station / airport names on the map. When off, only the icon is shown.', 'settings.blurBookingCodes': 'Blur Booking Codes', diff --git a/client/src/i18n/translations/uk.ts b/client/src/i18n/translations/uk.ts index 433016f6..01eb0609 100644 --- a/client/src/i18n/translations/uk.ts +++ b/client/src/i18n/translations/uk.ts @@ -209,7 +209,6 @@ const uk: Record = { 'settings.language': 'Мова', 'settings.temperature': 'Одиниця температури', 'settings.timeFormat': 'Формат часу', - 'settings.routeCalculation': 'Розрахунок маршруту', 'settings.blurBookingCodes': 'Приховати коди бронювання', 'settings.notifications': 'Сповіщення', 'settings.notifyTripInvite': 'Запрошення до поїздки', diff --git a/client/src/i18n/translations/zh.ts b/client/src/i18n/translations/zh.ts index 5c8f4979..20b0e80f 100644 --- a/client/src/i18n/translations/zh.ts +++ b/client/src/i18n/translations/zh.ts @@ -195,7 +195,6 @@ const zh: Record = { 'settings.language': '语言', 'settings.temperature': '温度单位', 'settings.timeFormat': '时间格式', - 'settings.routeCalculation': '路线计算', 'settings.blurBookingCodes': '模糊预订代码', 'settings.notifications': '通知', 'settings.notifyTripInvite': '旅行邀请', diff --git a/client/src/i18n/translations/zhTw.ts b/client/src/i18n/translations/zhTw.ts index 695eb974..b89ce88f 100644 --- a/client/src/i18n/translations/zhTw.ts +++ b/client/src/i18n/translations/zhTw.ts @@ -195,7 +195,6 @@ const zhTw: Record = { 'settings.language': '語言', 'settings.temperature': '溫度單位', 'settings.timeFormat': '時間格式', - 'settings.routeCalculation': '路線計算', 'settings.blurBookingCodes': '模糊預訂程式碼', 'settings.notifications': '通知', 'settings.notifyTripInvite': '旅行邀請', diff --git a/client/src/pages/DashboardPage.test.tsx b/client/src/pages/DashboardPage.test.tsx index 2a3530ee..9e26acaf 100644 --- a/client/src/pages/DashboardPage.test.tsx +++ b/client/src/pages/DashboardPage.test.tsx @@ -857,7 +857,6 @@ describe('DashboardPage', () => { temperature_unit: 'fahrenheit', time_format: '12h', show_place_description: false, - route_calculation: false, blur_booking_codes: false, dashboard_currency: 'on', dashboard_timezone: 'on', diff --git a/client/src/pages/TripPlannerPage.tsx b/client/src/pages/TripPlannerPage.tsx index f314bea8..27826347 100644 --- a/client/src/pages/TripPlannerPage.tsx +++ b/client/src/pages/TripPlannerPage.tsx @@ -830,7 +830,7 @@ export default function TripPlannerPage(): React.ReactElement | null { hasInspector={!!selectedPlace} hasDayDetail={!!showDayDetail && !selectedPlace} reservations={reservations} - showReservationStats={settings.route_calculation !== false} + showReservationStats={true} visibleConnectionIds={visibleConnections} onReservationClick={(rid) => { const r = reservations.find(x => x.id === rid) diff --git a/client/src/types.ts b/client/src/types.ts index 0886ddf6..4572c558 100644 --- a/client/src/types.ts +++ b/client/src/types.ts @@ -215,7 +215,6 @@ export interface Settings { temperature_unit: string time_format: string show_place_description: boolean - route_calculation?: boolean blur_booking_codes?: boolean map_booking_labels?: boolean map_provider?: 'leaflet' | 'mapbox-gl' diff --git a/client/tests/helpers/factories.ts b/client/tests/helpers/factories.ts index 8bc8b468..835518ff 100644 --- a/client/tests/helpers/factories.ts +++ b/client/tests/helpers/factories.ts @@ -258,7 +258,6 @@ export function buildSettings(overrides: Partial = {}): Settings { temperature_unit: 'fahrenheit', time_format: '12h', show_place_description: false, - route_calculation: false, blur_booking_codes: false, ...overrides, }; diff --git a/client/tests/integration/hooks/useRouteCalculation.test.ts b/client/tests/integration/hooks/useRouteCalculation.test.ts index 18fc38d1..125b39ba 100644 --- a/client/tests/integration/hooks/useRouteCalculation.test.ts +++ b/client/tests/integration/hooks/useRouteCalculation.test.ts @@ -1,7 +1,6 @@ import { renderHook, act } from '@testing-library/react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { useRouteCalculation } from '../../../src/hooks/useRouteCalculation'; -import { useSettingsStore } from '../../../src/store/settingsStore'; import { useTripStore } from '../../../src/store/tripStore'; import { buildAssignment, buildPlace } from '../../helpers/factories'; import type { TripStoreState } from '../../../src/store/tripStore'; @@ -47,8 +46,6 @@ const MOCK_ROUTE_WITH_LEGS = { describe('useRouteCalculation', () => { beforeEach(() => { vi.clearAllMocks(); - // Default: route_calculation disabled - useSettingsStore.setState({ settings: { route_calculation: false } as any }); // Reset trip store assignments so each test starts clean useTripStore.setState({ assignments: {} } as any); (calculateRouteWithLegs as ReturnType).mockResolvedValue(MOCK_ROUTE_WITH_LEGS); @@ -93,9 +90,7 @@ describe('useRouteCalculation', () => { ]); }); - it('FE-HOOK-ROUTE-004: with route_calculation enabled, calls calculateRouteWithLegs', async () => { - useSettingsStore.setState({ settings: { route_calculation: true } as any }); - + it('FE-HOOK-ROUTE-004: calls calculateRouteWithLegs and exposes the returned segments', async () => { const p1 = buildPlace({ lat: 48.8566, lng: 2.3522 }); const p2 = buildPlace({ lat: 51.5074, lng: -0.1278 }); const a1 = buildAssignment({ day_id: 5, order_index: 0, place: p1 }); @@ -112,28 +107,7 @@ describe('useRouteCalculation', () => { expect(result.current.routeSegments).toEqual(MOCK_SEGMENTS); }); - it('FE-HOOK-ROUTE-005: with route_calculation disabled, does not call calculateRouteWithLegs', async () => { - useSettingsStore.setState({ settings: { route_calculation: false } as any }); - - const p1 = buildPlace({ lat: 48.8566, lng: 2.3522 }); - const p2 = buildPlace({ lat: 51.5074, lng: -0.1278 }); - const a1 = buildAssignment({ day_id: 5, order_index: 0, place: p1 }); - const a2 = buildAssignment({ day_id: 5, order_index: 1, place: p2 }); - const store = buildMockStore({ '5': [a1, a2] }); - - const { result } = renderHook(() => - useRouteCalculation(store as TripStoreState, 5) - ); - - await act(async () => {}); - - expect(calculateRouteWithLegs).not.toHaveBeenCalled(); - expect(result.current.routeSegments).toEqual([]); - }); - it('FE-HOOK-ROUTE-006: assignments are sorted by order_index before extracting waypoints', async () => { - useSettingsStore.setState({ settings: { route_calculation: true } as any }); - const p1 = buildPlace({ lat: 10, lng: 10 }); const p2 = buildPlace({ lat: 20, lng: 20 }); // order_index 1 comes before 0 in the array, but should be sorted @@ -170,7 +144,6 @@ describe('useRouteCalculation', () => { }); it('FE-HOOK-ROUTE-008: AbortController.abort() is called when selectedDayId changes', async () => { - useSettingsStore.setState({ settings: { route_calculation: true } as any }); // Make calculateRouteWithLegs resolve slowly let resolveSegments!: (val: typeof MOCK_ROUTE_WITH_LEGS) => void; @@ -209,7 +182,6 @@ describe('useRouteCalculation', () => { }); it('FE-HOOK-ROUTE-009: AbortError from calculateSegments does not set routeSegments to []', async () => { - useSettingsStore.setState({ settings: { route_calculation: true } as any }); const abortError = new Error('Aborted'); abortError.name = 'AbortError'; @@ -231,7 +203,6 @@ describe('useRouteCalculation', () => { }); it('FE-HOOK-ROUTE-010: non-AbortError from calculateSegments sets routeSegments to []', async () => { - useSettingsStore.setState({ settings: { route_calculation: true } as any }); (calculateRouteWithLegs as ReturnType).mockRejectedValueOnce(new Error('Network error')); @@ -282,7 +253,6 @@ describe('useRouteCalculation', () => { }); it('FE-HOOK-ROUTE-013: route recalculates when assignments change via store update', async () => { - useSettingsStore.setState({ settings: { route_calculation: true } as any }); const p1 = buildPlace({ lat: 10, lng: 10 }); const p2 = buildPlace({ lat: 20, lng: 20 }); diff --git a/server/src/services/settingsService.ts b/server/src/services/settingsService.ts index 57f0e6c0..c1ccf9b3 100644 --- a/server/src/services/settingsService.ts +++ b/server/src/services/settingsService.ts @@ -10,7 +10,6 @@ export const DEFAULTABLE_USER_SETTING_KEYS = [ 'temperature_unit', 'dark_mode', 'time_format', - 'route_calculation', 'blur_booking_codes', 'map_tile_url', ] as const; @@ -23,7 +22,7 @@ const VALID_VALUES: Partial> = { dark_mode: [true, false, 'light', 'dark', 'auto'], }; -const BOOLEAN_KEYS = new Set(['route_calculation', 'blur_booking_codes']); +const BOOLEAN_KEYS = new Set(['blur_booking_codes']); function parseValue(raw: string): unknown { try { return JSON.parse(raw); } catch { return raw; }