diff --git a/frontend/components/dashboard/FutureForecastModal.tsx b/frontend/components/dashboard/FutureForecastModal.tsx index 9197bebc..ca803453 100644 --- a/frontend/components/dashboard/FutureForecastModal.tsx +++ b/frontend/components/dashboard/FutureForecastModal.tsx @@ -26,10 +26,9 @@ import { import { getTemperatureChartData } from "@/lib/chart-utils"; import { getFutureModalView, - getModelView, - getProbabilityView, getWeatherSummary, } from "@/lib/dashboard-utils"; +import { getModelView, getProbabilityView } from "@/lib/model-utils"; import { getTodayPaceView } from "@/lib/pace-utils"; import { dashboardClient } from "@/lib/dashboard-client"; import { diff --git a/frontend/components/dashboard/OpportunityTable.tsx b/frontend/components/dashboard/OpportunityTable.tsx index 9ff0f342..e94848df 100644 --- a/frontend/components/dashboard/OpportunityTable.tsx +++ b/frontend/components/dashboard/OpportunityTable.tsx @@ -8,10 +8,7 @@ import type { ScanOpportunityRow, } from "@/lib/dashboard-types"; import { getLocalizedCityName } from "@/lib/dashboard-home-copy"; -import { - getModelView, - getProbabilityView, -} from "@/lib/dashboard-utils"; +import { getModelView, getProbabilityView } from "@/lib/model-utils"; import { getTodayPaceView } from "@/lib/pace-utils"; import { formatTemperatureValue, diff --git a/frontend/components/dashboard/PanelSections.tsx b/frontend/components/dashboard/PanelSections.tsx index 333a142f..46bb0c42 100644 --- a/frontend/components/dashboard/PanelSections.tsx +++ b/frontend/components/dashboard/PanelSections.tsx @@ -15,11 +15,10 @@ import { import { getTemperatureChartData } from "@/lib/chart-utils"; import { getHeroMetaItems, - getModelView, - getProbabilityView, getRiskBadgeLabel, getWeatherSummary, } from "@/lib/dashboard-utils"; +import { getModelView, getProbabilityView } from "@/lib/model-utils"; import { normalizeObservationSourceCode, normalizeObservationSourceLabel, diff --git a/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx b/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx index b4c331b9..1d8f9652 100644 --- a/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx +++ b/frontend/components/dashboard/scan-terminal/AiPinnedCityCard.tsx @@ -21,7 +21,7 @@ import { useCityMarketScan, } from "@/components/dashboard/scan-terminal/use-ai-city-card-data"; import type { CityDetail, ScanOpportunityRow } from "@/lib/dashboard-types"; -import { getModelView } from "@/lib/dashboard-utils"; +import { getModelView } from "@/lib/model-utils"; import { getTodayPaceView } from "@/lib/pace-utils"; import { formatTemperatureValue } from "@/lib/temperature-utils"; diff --git a/frontend/lib/dashboard-utils.ts b/frontend/lib/dashboard-utils.ts index 85a6e7ba..0fcdb183 100644 --- a/frontend/lib/dashboard-utils.ts +++ b/frontend/lib/dashboard-utils.ts @@ -22,6 +22,7 @@ import { formatTafMarkerType } from "@/lib/taf-utils"; import { normalizeHm } from "@/lib/time-utils"; export { getTemperatureChartData } from "@/lib/chart-utils"; +export { getModelView, getProbabilityView } from "@/lib/model-utils"; export { getTodayPaceView } from "@/lib/pace-utils"; export { formatTemperatureValue, @@ -246,56 +247,6 @@ export function getHeroMetaItems(detail: CityDetail, locale: Locale = "zh-CN") { return parts; } -export function getProbabilityView(detail: CityDetail, targetDate?: string | null) { - const date = targetDate || detail.local_date; - if (date === detail.local_date) { - return { - calibrationMode: detail.probabilities?.calibration_mode ?? null, - calibrationVersion: detail.probabilities?.calibration_version ?? null, - engine: detail.probabilities?.engine ?? null, - mu: detail.probabilities?.mu ?? null, - probabilities: detail.probabilities?.distribution || [], - probabilitiesAll: - detail.probabilities?.distribution_all || - detail.probabilities?.distribution || - [], - shadowProbabilities: detail.probabilities?.shadow_distribution || [], - shadowProbabilitiesAll: - detail.probabilities?.shadow_distribution_all || - detail.probabilities?.shadow_distribution || - [], - }; - } - - const daily = detail.multi_model_daily?.[date]; - return { - calibrationMode: null, - calibrationVersion: null, - engine: null, - mu: daily?.deb?.prediction ?? null, - probabilities: daily?.probabilities || [], - probabilitiesAll: daily?.probabilities_all || daily?.probabilities || [], - shadowProbabilities: [], - shadowProbabilitiesAll: [], - }; -} - -export function getModelView(detail: CityDetail, targetDate?: string | null) { - const date = targetDate || detail.local_date; - const daily = detail.multi_model_daily?.[date]; - if (daily) { - return { - deb: daily.deb?.prediction ?? null, - models: daily.models || {}, - }; - } - - return { - deb: detail.deb?.prediction ?? null, - models: detail.multi_model || {}, - }; -} - export function parseAiAnalysis(analysis: CityDetail["ai_analysis"]) { const fallback = { bullets: [] as string[], diff --git a/frontend/lib/model-utils.ts b/frontend/lib/model-utils.ts new file mode 100644 index 00000000..acf10bd1 --- /dev/null +++ b/frontend/lib/model-utils.ts @@ -0,0 +1,51 @@ +import type { CityDetail } from "@/lib/dashboard-types"; + +export function getProbabilityView(detail: CityDetail, targetDate?: string | null) { + const date = targetDate || detail.local_date; + if (date === detail.local_date) { + return { + calibrationMode: detail.probabilities?.calibration_mode ?? null, + calibrationVersion: detail.probabilities?.calibration_version ?? null, + engine: detail.probabilities?.engine ?? null, + mu: detail.probabilities?.mu ?? null, + probabilities: detail.probabilities?.distribution || [], + probabilitiesAll: + detail.probabilities?.distribution_all || + detail.probabilities?.distribution || + [], + shadowProbabilities: detail.probabilities?.shadow_distribution || [], + shadowProbabilitiesAll: + detail.probabilities?.shadow_distribution_all || + detail.probabilities?.shadow_distribution || + [], + }; + } + + const daily = detail.multi_model_daily?.[date]; + return { + calibrationMode: null, + calibrationVersion: null, + engine: null, + mu: daily?.deb?.prediction ?? null, + probabilities: daily?.probabilities || [], + probabilitiesAll: daily?.probabilities_all || daily?.probabilities || [], + shadowProbabilities: [], + shadowProbabilitiesAll: [], + }; +} + +export function getModelView(detail: CityDetail, targetDate?: string | null) { + const date = targetDate || detail.local_date; + const daily = detail.multi_model_daily?.[date]; + if (daily) { + return { + deb: daily.deb?.prediction ?? null, + models: daily.models || {}, + }; + } + + return { + deb: detail.deb?.prediction ?? null, + models: detail.multi_model || {}, + }; +}