"use client"; import { useMemo, useState, type KeyboardEvent } from "react"; import { LoaderCircle, MapPin, Search, X } from "lucide-react"; import { CurrentLocationControl } from "@/components/weather/current-location-control"; import { useLocationSearch } from "@/hooks/use-location-search"; import { useI18n } from "@/lib/i18n"; import { createSelectedLocation, locateSynopStations } from "@/lib/location-utils"; import { useWeatherStore } from "@/lib/store"; import { formatDistance } from "@/lib/weather-utils"; import type { MeteoStationPosition, SynopStation } from "@/types/imgw"; import type { SelectedLocation } from "@/types/location"; export function LocationSearch({ stations, positions, }: { stations: SynopStation[]; positions: MeteoStationPosition[]; }) { const { language, t } = useI18n(); const [query, setQuery] = useState(""); const [isFocused, setIsFocused] = useState(false); const selectedLocation = useWeatherStore((state) => state.selectedLocation); const distanceUnit = useWeatherStore((state) => state.distanceUnit); const selectLocation = useWeatherStore((state) => state.selectLocation); const { data: locations, isFetching, isError } = useLocationSearch(query, language); const locatedStations = useMemo(() => locateSynopStations(stations, positions), [positions, stations]); const suggestions = useMemo( () => (locations ?? []).map((location) => ({ location, selected: createSelectedLocation(location, locatedStations), })), [locatedStations, locations], ); const showSuggestions = isFocused && query.trim().length >= 2; const isPreparingStations = positions.length === 0 && suggestions.some(({ selected }) => selected.region === "PL" && !selected.stationName); function chooseLocation(location: SelectedLocation) { selectLocation(location); setQuery(""); setIsFocused(false); } function handleSearchKeyDown(event: KeyboardEvent) { const firstSuggestion = suggestions[0]?.selected; if (event.key !== "Enter" || !showSuggestions || !firstSuggestion) return; event.preventDefault(); chooseLocation(firstSuggestion); } return (

{t("location.label")}

{showSuggestions && (
{isPreparingStations ? (

{t("location.preparing")}

) : isError ? (

{t("location.error")}

) : !isFetching && !suggestions.length ? (

{t("location.empty")}

) : ( suggestions.map(({ location, selected }) => ( )) )}
)}
{selectedLocation && (

{selectedLocation.stationName && selectedLocation.distanceKm !== null ? t("location.currentSource", { location: selectedLocation.name, station: selectedLocation.stationName, distance: formatDistance(selectedLocation.distanceKm, language, distanceUnit), }) : t("location.currentSourceGlobal", { location: selectedLocation.name })}

)}

{t("location.attribution")}{" "} Open-Meteo / GeoNames

); }