2026-03-09 10:36:03 +08:00
|
|
|
"use client";
|
|
|
|
|
|
2026-03-18 20:38:43 +08:00
|
|
|
import "leaflet/dist/leaflet.css";
|
|
|
|
|
|
2026-03-09 10:36:03 +08:00
|
|
|
import { useDashboardStore } from "@/hooks/useDashboardStore";
|
|
|
|
|
import { useLeafletMap } from "@/hooks/useLeafletMap";
|
|
|
|
|
|
2026-04-24 05:09:19 +08:00
|
|
|
export function MapCanvas({
|
|
|
|
|
onCitySelect,
|
2026-04-24 13:28:38 +08:00
|
|
|
selectionMode = "focus",
|
2026-04-24 05:09:19 +08:00
|
|
|
}: {
|
|
|
|
|
onCitySelect?: (cityName: string) => void;
|
2026-04-24 13:28:38 +08:00
|
|
|
selectionMode?: "focus" | "select";
|
2026-04-24 05:09:19 +08:00
|
|
|
} = {}) {
|
2026-03-09 10:36:03 +08:00
|
|
|
const store = useDashboardStore();
|
|
|
|
|
const { containerRef } = useLeafletMap({
|
|
|
|
|
cities: store.cities,
|
|
|
|
|
cityDetailsByName: store.cityDetailsByName,
|
|
|
|
|
citySummariesByName: store.citySummariesByName,
|
|
|
|
|
onClosePanel: store.closePanel,
|
|
|
|
|
onEnsureCityDetail: store.ensureCityDetail,
|
2026-04-12 10:44:03 +08:00
|
|
|
onMapInteractionChange: store.setMapInteractionActive,
|
2026-03-09 10:36:03 +08:00
|
|
|
onRegisterStopMotion: store.registerMapStopMotion,
|
|
|
|
|
onSelectCity: (cityName) => {
|
2026-04-24 05:09:19 +08:00
|
|
|
onCitySelect?.(cityName);
|
2026-04-24 13:28:38 +08:00
|
|
|
if (selectionMode === "select") {
|
|
|
|
|
void store.selectCity(cityName);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-04-22 23:24:20 +08:00
|
|
|
void store.focusCity(cityName);
|
2026-03-09 10:36:03 +08:00
|
|
|
},
|
|
|
|
|
selectedCity: store.selectedCity,
|
|
|
|
|
selectedDetail: store.selectedDetail,
|
2026-05-19 00:05:07 +08:00
|
|
|
suspendMotion: Boolean(store.futureModalDate),
|
2026-03-09 10:36:03 +08:00
|
|
|
isLoadingDetail: store.loadingState.cityDetail,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return <div ref={containerRef} className="map" />;
|
|
|
|
|
}
|