Files
nofx/web/src/components/ChartTabs.tsx
tinkle-community 0636ced476 feat: improve trading UI with interactive position table and chart tabs
- Add clickable position rows that scroll to chart and update symbol
- Add framer-motion animations to chart tab transitions
- Sync exchange selection between positions and TradingView chart
- Optimize position table layout with compact styling
- Update CSS with glass effects and premium button styles
2025-12-08 00:34:49 +08:00

110 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect } from 'react'
import { EquityChart } from './EquityChart'
import { TradingViewChart } from './TradingViewChart'
import { useLanguage } from '../contexts/LanguageContext'
import { t } from '../i18n/translations'
import { BarChart3, CandlestickChart } from 'lucide-react'
import { motion, AnimatePresence } from 'framer-motion'
interface ChartTabsProps {
traderId: string
selectedSymbol?: string // 从外部选择的币种
updateKey?: number // 强制更新的 key
exchangeId?: string // 交易所ID
}
type ChartTab = 'equity' | 'kline'
export function ChartTabs({ traderId, selectedSymbol, updateKey, exchangeId }: ChartTabsProps) {
const { language } = useLanguage()
const [activeTab, setActiveTab] = useState<ChartTab>('equity')
const [chartSymbol, setChartSymbol] = useState<string>('BTCUSDT')
// 当从外部选择币种时自动切换到K线图
useEffect(() => {
if (selectedSymbol) {
console.log('[ChartTabs] 收到币种选择:', selectedSymbol, 'updateKey:', updateKey)
setChartSymbol(selectedSymbol)
setActiveTab('kline')
}
}, [selectedSymbol, updateKey])
console.log('[ChartTabs] rendering, activeTab:', activeTab)
return (
<div className="binance-card">
{/* Tab Headers - 这是Tab切换按钮区域 */}
<div
className="flex items-center gap-2 p-3"
style={{
borderBottom: '1px solid #2B3139',
background: '#0B0E11',
}}
>
<button
onClick={() => {
console.log('[ChartTabs] switching to equity')
setActiveTab('equity')
}}
className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold transition-all ${activeTab === 'equity'
? 'bg-yellow-500/10 text-yellow-500 border border-yellow-500/30 shadow-[0_0_10px_rgba(252,213,53,0.15)]'
: 'text-gray-400 hover:text-white hover:bg-white/5 border border-transparent'
}`}
>
<BarChart3 className="w-4 h-4" />
{t('accountEquityCurve', language)}
</button>
<button
onClick={() => {
console.log('[ChartTabs] switching to kline')
setActiveTab('kline')
}}
className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold transition-all ${activeTab === 'kline'
? 'bg-yellow-500/10 text-yellow-500 border border-yellow-500/30 shadow-[0_0_10px_rgba(252,213,53,0.15)]'
: 'text-gray-400 hover:text-white hover:bg-white/5 border border-transparent'
}`}
>
<CandlestickChart className="w-4 h-4" />
{t('marketChart', language)}
</button>
</div>
{/* Tab Content */}
<div className="relative overflow-hidden min-h-[400px]">
<AnimatePresence mode="wait">
{activeTab === 'equity' ? (
<motion.div
key="equity"
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 20 }}
transition={{ duration: 0.2 }}
className="h-full"
>
<EquityChart traderId={traderId} embedded />
</motion.div>
) : (
<motion.div
key={`kline-${chartSymbol}-${exchangeId}`}
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: -20 }}
transition={{ duration: 0.2 }}
className="h-full"
>
<TradingViewChart
height={400}
embedded
defaultSymbol={chartSymbol}
defaultExchange={exchangeId}
key={`${chartSymbol}-${exchangeId}-${updateKey || ''}`}
/>
</motion.div>
)}
</AnimatePresence>
</div>
</div>
)
}