feat: implement MapCanvas and ScanTerminalDashboard components for interactive weather data visualization

This commit is contained in:
2569718930@qq.com
2026-04-24 13:28:38 +08:00
parent 168bf6987c
commit b94289a51a
2 changed files with 16 additions and 4 deletions
@@ -7,8 +7,10 @@ import { useLeafletMap } from "@/hooks/useLeafletMap";
export function MapCanvas({
onCitySelect,
selectionMode = "focus",
}: {
onCitySelect?: (cityName: string) => void;
selectionMode?: "focus" | "select";
} = {}) {
const store = useDashboardStore();
const { containerRef } = useLeafletMap({
@@ -21,6 +23,10 @@ export function MapCanvas({
onRegisterStopMotion: store.registerMapStopMotion,
onSelectCity: (cityName) => {
onCitySelect?.(cityName);
if (selectionMode === "select") {
void store.selectCity(cityName);
return;
}
void store.focusCity(cityName);
},
selectedCity: store.selectedCity,
@@ -24,6 +24,7 @@ import {
FilterState,
ScanFilterPanel,
} from "@/components/dashboard/ScanFilterPanel";
import { DetailPanel as CityDetailPanel } from "@/components/dashboard/DetailPanel";
import { FutureForecastModal } from "@/components/dashboard/FutureForecastModal";
import { MapCanvas } from "@/components/dashboard/MapCanvas";
import { getWindowPhaseMeta } from "@/components/dashboard/OpportunityTable";
@@ -464,7 +465,7 @@ function buildAssistantContext(params: {
};
}
function DetailPanel({
function ScanOpportunityDetailPanel({
row,
marketScan,
loading,
@@ -1437,14 +1438,18 @@ function ScanTerminalScreen() {
const handleSelectRow = useCallback((row: ScanOpportunityRow) => {
setSelectedRowId(row.id);
}, []);
void store.selectCity(row.city);
}, [store]);
const renderMainView = () => {
if (resolvedView === "map") {
return (
<div className="scan-map-view">
<div className="scan-map-shell">
<MapCanvas onCitySelect={handleMapCitySelect} />
<MapCanvas
onCitySelect={handleMapCitySelect}
selectionMode="select"
/>
</div>
<div className="scan-map-caption">
{locale === "en-US"
@@ -1613,11 +1618,12 @@ function ScanTerminalScreen() {
</section>
</main>
<DetailPanel
<ScanOpportunityDetailPanel
row={activeDetailRow}
marketScan={selectedDetail}
loading={detailLoadingId === activeDetailRow?.id}
/>
<CityDetailPanel />
<AssistantWidget
terminalData={terminalData}
rows={timeSortedRows}