import { useState, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { Slider } from '../ui/Slider'; import { IconButton } from '../ui/IconButton'; import { PillToggle } from '../ui/PillToggle'; import { DestinationDropdown } from '../ui/DestinationDropdown'; import InfoPopup from '../ui/InfoPopup'; import { TravelTimeInfoPopup } from '../ui/TravelTimeInfoPopup'; import { CloseIcon } from '../ui/icons/CloseIcon'; import { EyeIcon } from '../ui/icons/EyeIcon'; import { InfoIcon } from '../ui/icons/InfoIcon'; import { formatFilterValue, formatNumber } from '../../lib/format'; import { useTravelDestinations } from '../../hooks/useTravelDestinations'; import { MODE_ICONS, useTranslatedModes, type TransportMode } from '../../hooks/useTravelTime'; interface TravelTimeCardProps { mode: TransportMode; slug: string; label: string; timeRange: [number, number] | null; useBest: boolean; isPinned: boolean; isActive: boolean; dragValue: [number, number] | null; onTogglePin: () => void; onSetDestination: (slug: string, label: string, lat: number, lon: number) => void; onTimeRangeChange: (range: [number, number]) => void; onDragStart: () => void; onDragChange: (value: [number, number]) => void; onDragEnd: () => void; onToggleBest: () => void; onRemove: () => void; filterImpact?: number; destinationDropdownPortal?: boolean; } export function TravelTimeCard({ mode, slug, label, timeRange, useBest, isPinned, isActive, dragValue, onTogglePin, onSetDestination, onTimeRangeChange: _onTimeRangeChange, onDragStart, onDragChange, onDragEnd, onToggleBest, onRemove, filterImpact, destinationDropdownPortal = true, }: TravelTimeCardProps) { const { t } = useTranslation(); const modes = useTranslatedModes(); const { destinations, loading: destinationsLoading } = useTravelDestinations(mode); const [showInfo, setShowInfo] = useState(false); const [showBestInfo, setShowBestInfo] = useState(false); const handleDestinationSelect = useCallback( (selectedSlug: string, selectedLabel: string, lat: number, lon: number) => { onSetDestination(selectedSlug, selectedLabel, lat, lon); }, [onSetDestination] ); const sliderMin = 0; const sliderMax = 120; const displayRange = isActive && dragValue ? dragValue : (timeRange ?? [sliderMin, sliderMax]); const ModeIcon = MODE_ICONS[mode]; return (
{/* Header */}
{t('travel.travelTime', { mode: modes.label(mode) })}
setShowInfo(true)} title={t('filters.aboutData')}> {slug && ( )} onRemove()} title={t('travel.removeTravelTime')}>
{/* Destination */} onSetDestination('', '', 0, 0)} placeholder={t('travel.selectDestination')} portal={destinationDropdownPortal} /> {/* Best-case toggle — transit only, shown when destination is set */} {slug && mode === 'transit' && (
setShowBestInfo(true)} title={t('travel.bestCaseTitle')}>
)} {showInfo && setShowInfo(false)} />} {showBestInfo && ( setShowBestInfo(false)}>

)} {/* Time range slider — only show when we have data */} {slug && (

{t('travel.maxTime')} onDragChange([min, max])} onPointerDown={() => onDragStart()} onPointerUp={() => onDragEnd()} />
{formatFilterValue(displayRange[0])} {t('common.min')} {formatFilterValue(displayRange[1])} {t('common.min')}
{filterImpact != null && filterImpact > 0 && (

{t('filters.withoutThisFilter', { value: formatNumber(filterImpact) })}

)}
)}
); }