Files
PolyWeather/frontend/components/dashboard/opportunity-detail.ts
T
2569718930@qq.com 2b1d7c0b65 Improve dashboard maintainability before the next release
The dashboard had several oversized orchestration, component, and CSS files that made product-copy changes and mobile/performance work risky. This refactor preserves behavior while splitting scan terminal CSS, opportunity helpers, future forecast panels, history/detail charts, and probability/model sections into smaller ownership boundaries.

Constraint: No user-visible version bump because this batch is architecture and performance cleanup, not a release announcement.

Rejected: Rewrite dashboard state management in the same batch | too broad for a safe upload after CSS and component splitting.

Confidence: high

Scope-risk: moderate

Reversibility: clean

Directive: Keep new component/CSS boundaries instead of moving product copy back into the large dashboard files.

Tested: npm run build; npm run test:business; git diff --check

Not-tested: Browser visual smoke test after push
2026-04-28 20:19:17 +08:00

38 lines
1.3 KiB
TypeScript

import type { CityDetail, ScanOpportunityRow } from "@/lib/dashboard-types";
export function normalizeLookupKey(value?: string | null) {
return String(value || "")
.trim()
.toLowerCase()
.replace(/[\s_-]+/g, "");
}
export function getDetailForRow(
row: Pick<ScanOpportunityRow, "city" | "city_display_name" | "display_name">,
cityDetailsByName?: Record<string, CityDetail>,
) {
if (!cityDetailsByName) return null;
const rowKeys = [row.city, row.city_display_name, row.display_name]
.map(normalizeLookupKey)
.filter(Boolean);
return (
Object.entries(cityDetailsByName).find(([name, detail]) => {
const detailKeys = [name, detail.name, detail.display_name]
.map(normalizeLookupKey)
.filter(Boolean);
return rowKeys.some((key) => detailKeys.includes(key));
})?.[1] || null
);
}
export function getDetailViewDate(detail: CityDetail, row?: ScanOpportunityRow | null) {
if (!row) return detail.local_date;
const rawDate = row.selected_date || row.local_date || "";
const phase = String(row.window_phase || "").toLowerCase();
if ((phase === "tomorrow" || phase === "week_ahead") && rawDate) return rawDate;
if (!rawDate || rawDate === detail.local_date || row.local_date === detail.local_date) {
return detail.local_date;
}
return detail.local_date || rawDate;
}