feat: add scan dashboard components and local development configuration

This commit is contained in:
2569718930@qq.com
2026-04-24 02:14:20 +08:00
parent 79b58a8b98
commit a1faacb302
5 changed files with 82 additions and 8 deletions
@@ -8,6 +8,11 @@ import type {
ScanOpportunityRow,
} from "@/lib/dashboard-types";
import { getLocalizedCityName } from "@/lib/dashboard-home-copy";
import {
formatTemperatureValue,
normalizeTemperatureLabel,
normalizeTemperatureSymbol,
} from "@/lib/dashboard-utils";
type PhaseMeta = {
label: string;
@@ -113,6 +118,7 @@ function ProbabilityPreview({
Boolean(item && (item.label || item.value != null)),
)
: [];
const tempSymbol = normalizeTemperatureSymbol(row.target_unit || row.temp_symbol);
if (!preview.length) {
const targetBase =
@@ -121,11 +127,10 @@ function ProbabilityPreview({
row.target_lower ??
row.target_upper ??
null;
const unit = row.target_unit || row.temp_symbol || "";
const targetLabel =
targetBase != null
? `${Math.round(Number(targetBase))}${unit}`
: row.target_label || "--";
? formatTemperatureValue(Number(targetBase), tempSymbol)
: normalizeTemperatureLabel(row.target_label, tempSymbol) || "--";
preview.push({
label: targetLabel,
model_probability: row.model_event_probability,
@@ -141,7 +146,9 @@ function ProbabilityPreview({
key={`${item.label}-${item.value ?? ""}`}
className={`scan-distribution-card ${item.highlighted ? "featured" : ""}`}
>
<strong>{item.label || "--"}</strong>
<strong>
{normalizeTemperatureLabel(item.label, tempSymbol) || item.label || "--"}
</strong>
<span>
{locale === "en-US" ? "Model" : "模型"}
<br />
@@ -43,6 +43,10 @@ import {
getLocalizedAirportName,
getLocalizedCityName,
} from "@/lib/dashboard-home-copy";
import {
formatTemperatureValue,
normalizeTemperatureLabel,
} from "@/lib/dashboard-utils";
const DEFAULT_FILTERS: FilterState = {
scan_mode: "tradable",
@@ -222,6 +226,7 @@ function DetailPanel({
detailSignal && detailSignal.market_slug === row.market_slug
? detailSignal
: row;
const tempSymbol = row.temp_symbol || displayRow.temp_symbol || "°C";
const yesRow = getSideRow(marketScan, row, "yes");
const noRow = getSideRow(marketScan, row, "no");
const comparisonBuckets = buildComparisonBuckets(marketScan, row);
@@ -276,26 +281,33 @@ function DetailPanel({
<div className="scan-kv">
<span>{isEn ? "Current Temp" : "当前温度"}</span>
<strong>
{row.current_temp != null ? `${row.current_temp}${row.temp_symbol || ""}` : "--"}
{row.current_temp != null
? formatTemperatureValue(row.current_temp, tempSymbol)
: "--"}
</strong>
</div>
<div className="scan-kv">
<span>{isEn ? "Day High (So Far)" : "今日最高(至今)"}</span>
<strong>
{row.current_max_so_far != null
? `${row.current_max_so_far}${row.temp_symbol || ""}`
? formatTemperatureValue(row.current_max_so_far, tempSymbol)
: "--"}
</strong>
</div>
<div className="scan-kv">
<span>{isEn ? "Target" : "目标温度"}</span>
<strong>{displayRow.target_label || "--"}</strong>
<strong>
{normalizeTemperatureLabel(displayRow.target_label, tempSymbol) || "--"}
</strong>
</div>
<div className="scan-kv">
<span>{isEn ? "Gap To Target" : "距离目标"}</span>
<strong className={Number(displayRow.gap_to_target || 0) <= 0 ? "warn" : "danger"}>
{displayRow.gap_to_target != null
? `${displayRow.gap_to_target >= 0 ? "+" : ""}${displayRow.gap_to_target.toFixed(1)}${row.temp_symbol || ""}`
? formatTemperatureValue(displayRow.gap_to_target, tempSymbol, {
signed: true,
digits: 1,
})
: "--"}
</strong>
</div>