diff --git a/client/src/components/Roadtrip/RoadtripSidebar.tsx b/client/src/components/Roadtrip/RoadtripSidebar.tsx index 41a798387..df5afdddd 100644 --- a/client/src/components/Roadtrip/RoadtripSidebar.tsx +++ b/client/src/components/Roadtrip/RoadtripSidebar.tsx @@ -8,7 +8,7 @@ import { } from 'lucide-react' import MDancingTrek from '../../mobile/components/MDancingTrek' import type { RefuelSearch } from './useRefuelSearch' -import type { RefuelCandidate } from './refuelSuggestion' +import { REFUEL_EMPTY_KEY, REFUEL_WORDS, refuelBandState, type RefuelCandidate } from './refuelSuggestion' import type { DryPoint } from './roadtripModel' import { useTranslation } from '../../i18n/TranslationContext' import { Tooltip } from '../shared/Tooltip' @@ -445,9 +445,10 @@ function RefuelBand({ dry, refuel, dayId, onAsk, onAccept }: { const { vehicleKind } = useVehicleRange() const electric = vehicleKind === 'electric' const DryIcon = electric ? Zap : Fuel - const key = `${dayId}:${dry.legIndex}` - const open = refuel.openFor === key - const settled = open && !refuel.loading && refuel.outcome + const words = REFUEL_WORDS[electric ? 'electric' : 'fuel'] + // Which control, which sentence and which offers: decided in refuelSuggestion so the + // phone band reads the same answer instead of keeping its own copy of the conditions. + const band = refuelBandState(refuel, dayId, dry.legIndex) return (
@@ -490,7 +491,7 @@ function RefuelBand({ dry, refuel, dayId, onAsk, onAccept }: { className="truncate font-geist font-semibold uppercase tracking-[0.16em] text-danger" style={{ fontSize: FS.label }} > - {t(electric ? 'roadtrip.refuel.dryElectric' : 'roadtrip.refuel.dry')} + {t(words.dry)}
{/* How far INTO this leg, where a drive band keeps its figures. Not the range that was crossed: that is the traveller's own setting, says @@ -513,7 +514,7 @@ function RefuelBand({ dry, refuel, dayId, onAsk, onAccept }: { found nothing leaves a button rather than a dead end — the place search is a shared public service that does time out, and "it did not answer" with no way to retry reads as broken rather than as busy. */} - {open && (refuel.loading || refuel.results.length) ? ( + {band.control === 'close' ? ( - {/* Blunt rather than greyed out: the button keeps its shape and says why. */} - {offline && ( - {t('mobileTrip.rtSearchOffline')} - )} - + ) : ( + + )} + + + {/* Blunt rather than silent: the lamp keeps its place and this says why it is out. */} + {onSearch && offline && band.control !== 'close' && ( + {t('mobileTrip.rtSearchOffline')} )} - {open && refuel.loading && ( + {band.loading && ( {t('roadtrip.refuel.looking')} )} {/* The answer, in the band that asked. The desktop puts it in the rail row for the same reason: a station offered somewhere other than where the tank runs out is - an offer somebody has to go and find. Three at most: this is an offer beside a - plan, and the search sheet above is where all of them live. */} - {settled && (refuel.results.length ? ( + an offer somebody has to go and find. */} + {band.offers.length > 0 && ( - ) : ( - /* Three sentences for three different facts. "Nothing on this stretch" after a - request that failed states something that was never checked. */ - - {refuel.outcome === 'none' - ? t('roadtrip.refuel.none') - : refuel.outcome === 'incomplete' - ? t('roadtrip.refuel.incomplete') - : t('roadtrip.refuel.failed')} - - ))} + )} + + {/* Three sentences for three different facts. "Nothing on this stretch" after a + request that failed states something that was never checked. */} + {band.empty && ( + {t(REFUEL_EMPTY_KEY[band.empty])} + )} ) } @@ -303,7 +364,7 @@ function RefuelOffer({ poi, chrome, electric, onAccept }: {