feat: implement MapCanvas and ScanTerminalDashboard components for interactive weather data visualization
This commit is contained in:
@@ -7,8 +7,10 @@ import { useLeafletMap } from "@/hooks/useLeafletMap";
|
|||||||
|
|
||||||
export function MapCanvas({
|
export function MapCanvas({
|
||||||
onCitySelect,
|
onCitySelect,
|
||||||
|
selectionMode = "focus",
|
||||||
}: {
|
}: {
|
||||||
onCitySelect?: (cityName: string) => void;
|
onCitySelect?: (cityName: string) => void;
|
||||||
|
selectionMode?: "focus" | "select";
|
||||||
} = {}) {
|
} = {}) {
|
||||||
const store = useDashboardStore();
|
const store = useDashboardStore();
|
||||||
const { containerRef } = useLeafletMap({
|
const { containerRef } = useLeafletMap({
|
||||||
@@ -21,6 +23,10 @@ export function MapCanvas({
|
|||||||
onRegisterStopMotion: store.registerMapStopMotion,
|
onRegisterStopMotion: store.registerMapStopMotion,
|
||||||
onSelectCity: (cityName) => {
|
onSelectCity: (cityName) => {
|
||||||
onCitySelect?.(cityName);
|
onCitySelect?.(cityName);
|
||||||
|
if (selectionMode === "select") {
|
||||||
|
void store.selectCity(cityName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
void store.focusCity(cityName);
|
void store.focusCity(cityName);
|
||||||
},
|
},
|
||||||
selectedCity: store.selectedCity,
|
selectedCity: store.selectedCity,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
FilterState,
|
FilterState,
|
||||||
ScanFilterPanel,
|
ScanFilterPanel,
|
||||||
} from "@/components/dashboard/ScanFilterPanel";
|
} from "@/components/dashboard/ScanFilterPanel";
|
||||||
|
import { DetailPanel as CityDetailPanel } from "@/components/dashboard/DetailPanel";
|
||||||
import { FutureForecastModal } from "@/components/dashboard/FutureForecastModal";
|
import { FutureForecastModal } from "@/components/dashboard/FutureForecastModal";
|
||||||
import { MapCanvas } from "@/components/dashboard/MapCanvas";
|
import { MapCanvas } from "@/components/dashboard/MapCanvas";
|
||||||
import { getWindowPhaseMeta } from "@/components/dashboard/OpportunityTable";
|
import { getWindowPhaseMeta } from "@/components/dashboard/OpportunityTable";
|
||||||
@@ -464,7 +465,7 @@ function buildAssistantContext(params: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function DetailPanel({
|
function ScanOpportunityDetailPanel({
|
||||||
row,
|
row,
|
||||||
marketScan,
|
marketScan,
|
||||||
loading,
|
loading,
|
||||||
@@ -1437,14 +1438,18 @@ function ScanTerminalScreen() {
|
|||||||
|
|
||||||
const handleSelectRow = useCallback((row: ScanOpportunityRow) => {
|
const handleSelectRow = useCallback((row: ScanOpportunityRow) => {
|
||||||
setSelectedRowId(row.id);
|
setSelectedRowId(row.id);
|
||||||
}, []);
|
void store.selectCity(row.city);
|
||||||
|
}, [store]);
|
||||||
|
|
||||||
const renderMainView = () => {
|
const renderMainView = () => {
|
||||||
if (resolvedView === "map") {
|
if (resolvedView === "map") {
|
||||||
return (
|
return (
|
||||||
<div className="scan-map-view">
|
<div className="scan-map-view">
|
||||||
<div className="scan-map-shell">
|
<div className="scan-map-shell">
|
||||||
<MapCanvas onCitySelect={handleMapCitySelect} />
|
<MapCanvas
|
||||||
|
onCitySelect={handleMapCitySelect}
|
||||||
|
selectionMode="select"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="scan-map-caption">
|
<div className="scan-map-caption">
|
||||||
{locale === "en-US"
|
{locale === "en-US"
|
||||||
@@ -1613,11 +1618,12 @@ function ScanTerminalScreen() {
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<DetailPanel
|
<ScanOpportunityDetailPanel
|
||||||
row={activeDetailRow}
|
row={activeDetailRow}
|
||||||
marketScan={selectedDetail}
|
marketScan={selectedDetail}
|
||||||
loading={detailLoadingId === activeDetailRow?.id}
|
loading={detailLoadingId === activeDetailRow?.id}
|
||||||
/>
|
/>
|
||||||
|
<CityDetailPanel />
|
||||||
<AssistantWidget
|
<AssistantWidget
|
||||||
terminalData={terminalData}
|
terminalData={terminalData}
|
||||||
rows={timeSortedRows}
|
rows={timeSortedRows}
|
||||||
|
|||||||
Reference in New Issue
Block a user