"use client"; import { useMemo, useState, type KeyboardEvent } from "react"; import { LoaderCircle, MapPin, Search, X } from "lucide-react"; import { useLocationSearch } from "@/hooks/use-location-search"; import { useWeatherStore } from "@/lib/store"; import { findNearestSynopStation, locateSynopStations } from "@/lib/location-utils"; import { useI18n } from "@/lib/i18n"; import type { MeteoStationPosition, SynopStation } from "@/types/imgw"; import type { SelectedLocation } from "@/types/location"; import { CurrentLocationControl } from "@/components/weather/current-location-control"; 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 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, nearest: findNearestSynopStation(location, locatedStations), })).filter((suggestion) => suggestion.nearest !== null), [locatedStations, locations]); const showSuggestions = isFocused && query.trim().length >= 2; const isPreparingStations = positions.length === 0; function chooseLocation(location: SelectedLocation) { selectLocation(location); setQuery(""); setIsFocused(false); } function handleSearchKeyDown(event: KeyboardEvent) { const firstSuggestion = suggestions[0]?.nearest; 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, nearest }) => nearest && ( ))}
)}
{selectedLocation && (

{t("location.currentSource", { location: selectedLocation.name, station: selectedLocation.stationName, distance: selectedLocation.distanceKm })}

)}

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

); }