"use client"; import clsx from "clsx"; import { Search, Table2 } from "lucide-react"; import { useMemo, useState } from "react"; import type { ScanOpportunityRow } from "@/lib/dashboard-types"; import { MODEL_SUMMARY_MODEL_COLUMNS, buildModelSummaryRows, filterModelSummaryRows, formatModelSummaryTemp, type ModelSummaryRow, } from "@/lib/model-summary"; type ModelSummaryDashboardProps = { rows: ScanOpportunityRow[]; isEn: boolean; generatedText?: string; }; const SUMMARY_TEXT = { title: { en: "Model Summary", zh: "模型汇总" }, subtitle: { en: "Today high-temperature view across DEB and model cluster sources.", zh: "按今日最高温口径汇总 DEB 与多模型预测。", }, search: { en: "Search city or model", zh: "搜索城市或模型" }, city: { en: "City", zh: "城市" }, region: { en: "Region", zh: "区域" }, currentHigh: { en: "Current High", zh: "当前最高" }, median: { en: "Median", zh: "模型中位数" }, spread: { en: "Spread", zh: "分歧范围" }, updated: { en: "Updated", zh: "更新时间" }, empty: { en: "No model summary rows match the current filters.", zh: "当前筛选下没有模型汇总数据。" }, generated: { en: "Generated", zh: "生成" }, total: { en: "rows", zh: "行" }, } as const; function copy(key: keyof typeof SUMMARY_TEXT, isEn: boolean) { return SUMMARY_TEXT[key][isEn ? "en" : "zh"]; } function TemperatureCell({ value, symbol, emphasis, }: { value: number | null; symbol: string; emphasis?: "deb" | "median"; }) { const missing = value == null; return ( {formatModelSummaryTemp(value, symbol)} ); } function FilterToggle({ checked, label, onChange, }: { checked: boolean; label: string; onChange: (checked: boolean) => void; }) { return ( ); } function ModelSummaryRowView({ row, }: { row: ModelSummaryRow; }) { return ( {row.cityName} {row.regionLabel} {MODEL_SUMMARY_MODEL_COLUMNS.map((column) => ( ))} {row.updatedAt || "—"} ); } export function ModelSummaryDashboard({ rows, isEn, generatedText, }: ModelSummaryDashboardProps) { const [query, setQuery] = useState(""); const [debOnly, setDebOnly] = useState(false); const [wideSpreadOnly, setWideSpreadOnly] = useState(false); const summaryRows = useMemo(() => buildModelSummaryRows(rows, isEn), [rows, isEn]); const visibleRows = useMemo( () => filterModelSummaryRows(summaryRows, { query, debOnly, wideSpreadOnly, }), [summaryRows, query, debOnly, wideSpreadOnly], ); return (

{copy("title", isEn)}

{visibleRows.length}/{summaryRows.length} {copy("total", isEn)}

{copy("subtitle", isEn)} {generatedText ? ( {copy("generated", isEn)} {generatedText} ) : null}

setQuery(event.target.value)} placeholder={copy("search", isEn)} className="h-8 w-full rounded border border-slate-300 bg-white pl-8 pr-2 text-xs font-semibold text-slate-700 outline-none transition focus:border-blue-400 focus:ring-2 focus:ring-blue-100" />
{MODEL_SUMMARY_MODEL_COLUMNS.map((column) => ( ))} {visibleRows.map((row) => ( ))}
{copy("city", isEn)} {copy("region", isEn)} {copy("currentHigh", isEn)} DEB {column.label} {copy("median", isEn)} {copy("spread", isEn)} {copy("updated", isEn)}
{!visibleRows.length && (
{copy("empty", isEn)}
)}
); }