"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import clsx from "clsx"; import type { ScanOpportunityRow } from "@/lib/dashboard-types"; import { REGIONS, getCityRegion } from "./continent-grouping"; import { rowName, temp } from "./utils"; interface CitySelectorDropdownProps { isEn: boolean; rows: ScanOpportunityRow[]; onSelectCity: (city: string) => void; onClose: () => void; className?: string; } export function CitySelectorDropdown({ isEn, rows, onSelectCity, onClose, className, }: CitySelectorDropdownProps) { const containerRef = useRef(null); const inputRef = useRef(null); const [searchQuery, setSearchQuery] = useState(""); const [activeTab, setActiveTab] = useState("all"); // Auto-focus input on mount useEffect(() => { inputRef.current?.focus(); }, []); // Handle click outside and Escape key useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { onClose(); } }; const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { onClose(); } }; document.addEventListener("mousedown", handleClickOutside); document.addEventListener("keydown", handleKeyDown); return () => { document.removeEventListener("mousedown", handleClickOutside); document.removeEventListener("keydown", handleKeyDown); }; }, [onClose]); // Tab definitions const tabs = useMemo(() => { return [ { key: "all", labelEn: "ALL", labelZh: "全部" }, ...REGIONS.map((r) => ({ key: r.key, labelEn: r.labelEn.replace("Asia", "").replace("America", "").trim() || r.labelEn, labelZh: r.labelZh, })), ]; }, []); // Filter rows const filteredRows = useMemo(() => { const q = searchQuery.toLowerCase().trim(); return rows.filter((row) => { // 1. Region filter if (activeTab !== "all") { const region = getCityRegion(row); if (region !== activeTab) return false; } // 2. Query filter if (!q) return true; const haystack = [ row.city, row.city_display_name, row.display_name, row.airport, ] .filter(Boolean) .map((s) => s!.toLowerCase()); return haystack.some((s) => s.includes(q)); }); }, [rows, searchQuery, activeTab]); return (
e.stopPropagation()} // Prevent card activation > {/* Search Input Area */}
setSearchQuery(e.target.value)} placeholder={isEn ? "Search city or airport..." : "搜索城市、机场..."} className="w-full px-2.5 py-1.5 border border-slate-300 rounded bg-white text-xs outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500/20" />
{/* Region filter tabs */}
{tabs.map((tab) => { const isActive = activeTab === tab.key; return ( ); })}
{/* Scrollable list */}
{filteredRows.length === 0 ? (
{isEn ? "No matching cities" : "无匹配城市"}
) : ( filteredRows.map((row) => { const cityName = rowName(row); const obsTemp = row.current_temp ?? row.current_max_so_far; const debPrediction = row.deb_prediction; const symbol = row.temp_symbol || "°C"; return ( ); }) )}
); }