"use client"; import React from "react"; import { Star } from "lucide-react"; import { useI18n } from "@/hooks/useI18n"; import type { ScanOpportunityRow } from "@/lib/dashboard-types"; import { getLocalizedCityName } from "@/lib/dashboard-home-copy"; function formatPercent(value?: number | null, signed = false) { if (value == null || Number.isNaN(Number(value))) return "--"; const numeric = Number(value); return `${signed && numeric >= 0 ? "+" : ""}${numeric.toFixed(1)}%`; } function formatVolume(value?: number | null) { const numeric = Number(value || 0); if (!Number.isFinite(numeric) || numeric <= 0) return "--"; if (numeric >= 1_000_000) return `$${(numeric / 1_000_000).toFixed(1)}M`; if (numeric >= 1_000) return `$${(numeric / 1_000).toFixed(0)}K`; return `$${numeric.toFixed(0)}`; } function formatWindowMinutes(value: number | null | undefined, locale: string) { if (value == null || !Number.isFinite(Number(value))) return "--"; const minutes = Math.max(0, Math.round(Number(value))); const hours = Math.floor(minutes / 60); const remains = minutes % 60; if (locale === "en-US") { if (hours <= 0) return `${remains}m left`; return `${hours}h ${remains}m left`; } if (hours <= 0) return `剩余 ${remains} 分钟`; return `剩余 ${hours}h ${remains}m`; } function formatAction(row: ScanOpportunityRow, locale: string) { if (row.action) return row.action; if (row.side === "yes") { return `${locale === "en-US" ? "Buy Yes" : "买入 Yes"} ${row.target_label || ""}`.trim(); } if (row.side === "no") { return `${locale === "en-US" ? "Buy No" : "买入 No"} ${row.target_label || ""}`.trim(); } return "--"; } function getPhaseMeta( row: ScanOpportunityRow, locale: string, ): { label: string; tone: "green" | "amber" | "blue" | "red" } { const mode = String(row.window_phase || "").toLowerCase(); if (mode === "active_peak" || mode === "setup_today") { return { label: locale === "en-US" ? "Touch Play" : "触达博弈", tone: "red", }; } if (mode === "tomorrow" || mode === "week_ahead") { return { label: locale === "en-US" ? "Early" : "早期机会", tone: "blue", }; } if (row.trend_alignment) { return { label: locale === "en-US" ? "Trend" : "趋势确认", tone: "amber", }; } return { label: locale === "en-US" ? "Tradable" : "可交易", tone: "green", }; } function scoreTone(score?: number | null) { const numeric = Number(score || 0); if (numeric >= 85) return "green"; if (numeric >= 70) return "yellow"; return "gray"; } function ProbabilityPreview({ row, locale, }: { row: ScanOpportunityRow; locale: string; }) { const targetBase = row.target_value ?? row.target_threshold ?? 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 || "--"; return (