refactor: replace embedded TradingView chart widget with a direct link redirect to the external site.

This commit is contained in:
xucheng 2026-01-19 17:26:22 +08:00
parent 5b501e3984
commit b6222b9b4b

View File

@ -1,7 +1,8 @@
"use client"
import { useEffect, useRef, useState } from "react"
import { useEffect } from "react"
import { ExternalLink } from "lucide-react"
import { Button } from "@/components/ui/button"
interface StockChartProps {
symbol: string
@ -9,26 +10,8 @@ interface StockChartProps {
}
export function StockChart({ symbol, market }: StockChartProps) {
const containerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
if (!containerRef.current) return
// Clear previous widget
containerRef.current.innerHTML = ""
// Create wrapper for widget
const widgetContainer = document.createElement("div")
widgetContainer.className = "tradingview-widget-container__widget h-full w-full"
containerRef.current.appendChild(widgetContainer)
const script = document.createElement("script")
script.src = "https://s3.tradingview.com/external-embedding/embed-widget-advanced-chart.js"
script.type = "text/javascript"
script.async = true
// Map Market/Symbol to TradingView format
console.log("[StockChart] Received market:", JSON.stringify(market), "symbol:", symbol)
const getTradingViewUrl = () => {
let exchange = "NASDAQ"
let tvSymbol = symbol
@ -38,52 +21,38 @@ export function StockChart({ symbol, market }: StockChartProps) {
else if (symbol.startsWith("4") || symbol.startsWith("8")) exchange = "BSE"
} else if (market === "HK") {
exchange = "HKEX"
// TradingView usually expects HK stocks without leading zeros if they are 4 digits, but let's check.
// Actually HKEX:700 works, HKEX:0700 might work too. Let's try to keep it safe.
// Ensure no leading zeros for int conversion check
tvSymbol = parseInt(symbol).toString()
} else if (market === "JP") {
exchange = "TSE"
} else if (market === "VN") {
exchange = "HOSE" // Primary VN exchange
exchange = "HOSE"
} else {
// US
exchange = "NASDAQ" // Default, could be NYSE
// Basic heuristic for US
// If 4 chars or more, likely Nasdaq, <=3 likely NYSE? Not 100% accurate but acceptable default.
exchange = "NASDAQ" // Default fallback
}
const fullSymbol = `${exchange}:${tvSymbol}`
return `https://cn.tradingview.com/chart/?symbol=${fullSymbol}`
}
script.innerHTML = JSON.stringify({
"autosize": true,
"symbol": fullSymbol,
"interval": "D",
"range": "12m",
"scale": "log",
"timezone": "Asia/Shanghai",
"theme": "light",
"style": "1",
"locale": "zh_CN",
"enable_publishing": false,
"allow_symbol_change": true,
"calendar": false,
"support_host": "https://www.tradingview.com"
})
containerRef.current.appendChild(script)
useEffect(() => {
const url = getTradingViewUrl()
// Attempt to open in new tab automatically
const win = window.open(url, '_blank')
if (!win) {
console.warn("Popup blocked. Please allow popups for this site.")
}
}, [symbol, market])
return (
<div className="h-[calc(100vh-100px)] w-full bg-background rounded-lg border overflow-hidden p-1">
<div className="tradingview-widget-container h-full w-full flex flex-col" ref={containerRef}>
<div className="tradingview-widget-copyright text-xs text-center text-muted-foreground p-2 mt-auto border-t bg-muted/20">
<a href={`https://cn.tradingview.com/chart/?symbol=${symbol}`} rel="noopener nofollow" target="_blank" className="hover:text-primary transition-colors flex items-center justify-center gap-1">
<span className="font-medium"> TradingView </span>
<span className="text-[10px] opacity-70">({symbol})</span>
<div className="w-full h-12 bg-muted/30 rounded-lg border border-dashed flex items-center justify-center">
<p className="text-xs text-muted-foreground flex items-center gap-1">
<span> TradingView ({symbol})...</span>
<a href={getTradingViewUrl()} target="_blank" rel="noopener noreferrer" className="underline hover:text-primary">
</a>
</div>
</div>
</p>
</div>
)
}