"use client" import React, { useState } from 'react' import TradeModal from './TradeModal' import ScreenshotGallery from './ScreenshotGallery' const layouts = (process.env.NEXT_PUBLIC_TRADINGVIEW_LAYOUTS || 'ai,Diy module').split(',').map(l => l.trim()) const timeframes = [ { label: '1m', value: '1' }, { label: '5m', value: '5' }, { label: '15m', value: '15' }, { label: '1h', value: '60' }, { label: '4h', value: '240' }, { label: '1d', value: 'D' }, { label: '1w', value: 'W' }, { label: '1M', value: 'M' }, ] const popularCoins = [ { name: 'Bitcoin', symbol: 'BTCUSD', icon: 'โ‚ฟ', color: 'from-orange-400 to-orange-600' }, { name: 'Ethereum', symbol: 'ETHUSD', icon: 'ฮž', color: 'from-blue-400 to-blue-600' }, { name: 'Solana', symbol: 'SOLUSD', icon: 'โ—Ž', color: 'from-purple-400 to-purple-600' }, { name: 'Sui', symbol: 'SUIUSD', icon: '๐Ÿ”ท', color: 'from-cyan-400 to-cyan-600' }, { name: 'Avalanche', symbol: 'AVAXUSD', icon: '๐Ÿ”บ', color: 'from-red-400 to-red-600' }, { name: 'Cardano', symbol: 'ADAUSD', icon: 'โ™ ', color: 'from-indigo-400 to-indigo-600' }, { name: 'Polygon', symbol: 'MATICUSD', icon: '๐Ÿ”ท', color: 'from-violet-400 to-violet-600' }, { name: 'Chainlink', symbol: 'LINKUSD', icon: '๐Ÿ”—', color: 'from-blue-400 to-blue-600' }, ] // Progress tracking interfaces interface ProgressStep { id: string title: string description: string status: 'pending' | 'active' | 'completed' | 'error' startTime?: number endTime?: number details?: string } interface AnalysisProgress { currentStep: number totalSteps: number steps: ProgressStep[] timeframeProgress?: { current: number total: number currentTimeframe?: string } } interface AIAnalysisPanelProps { onAnalysisComplete?: (analysis: any, symbol: string) => void } export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelProps = {}) { const [symbol, setSymbol] = useState('BTCUSD') const [selectedLayouts, setSelectedLayouts] = useState(['ai', 'diy']) // Default to both AI and DIY const [selectedTimeframes, setSelectedTimeframes] = useState(['60']) // Support multiple timeframes const [loading, setLoading] = useState(false) const [result, setResult] = useState(null) const [error, setError] = useState(null) const [progress, setProgress] = useState(null) const [modalOpen, setModalOpen] = useState(false) const [modalData, setModalData] = useState(null) const [enlargedScreenshot, setEnlargedScreenshot] = useState(null) const [tradeModalOpen, setTradeModalOpen] = useState(false) const [tradeModalData, setTradeModalData] = useState(null) // Helper function to safely render any value const safeRender = (value: any): string => { if (typeof value === 'string') return value if (typeof value === 'number') return value.toString() if (Array.isArray(value)) return value.join(', ') if (typeof value === 'object' && value !== null) { return JSON.stringify(value) } return String(value) } const toggleLayout = (layout: string) => { setSelectedLayouts(prev => prev.includes(layout) ? prev.filter(l => l !== layout) : [...prev, layout] ) } const toggleTimeframe = (timeframe: string) => { setSelectedTimeframes(prev => prev.includes(timeframe) ? prev.filter(tf => tf !== timeframe) : [...prev, timeframe] ) } // Helper function to create initial progress steps const createProgressSteps = (timeframes: string[], layouts: string[]): ProgressStep[] => { const steps: ProgressStep[] = [] if (timeframes.length > 1) { steps.push({ id: 'init', title: 'Initializing Multi-Timeframe Analysis', description: `Preparing to analyze ${timeframes.length} timeframes`, status: 'pending' }) } else { steps.push({ id: 'init', title: 'Initializing Analysis', description: `Setting up screenshot service for ${layouts.join(', ')} layout(s)`, status: 'pending' }) } steps.push({ id: 'browser', title: 'Starting Browser Sessions', description: `Launching ${layouts.length} browser session(s)`, status: 'pending' }) steps.push({ id: 'auth', title: 'TradingView Authentication', description: 'Logging into TradingView accounts', status: 'pending' }) steps.push({ id: 'navigation', title: 'Chart Navigation', description: 'Navigating to chart layouts and timeframes', status: 'pending' }) steps.push({ id: 'loading', title: 'Chart Data Loading', description: 'Waiting for chart data and indicators to load', status: 'pending' }) steps.push({ id: 'capture', title: 'Screenshot Capture', description: 'Capturing high-quality chart screenshots', status: 'pending' }) steps.push({ id: 'analysis', title: 'AI Analysis', description: 'Analyzing screenshots with AI for trading insights', status: 'pending' }) return steps } // Helper function to update progress const updateProgress = (stepId: string, status: ProgressStep['status'], details?: string) => { setProgress(prev => { if (!prev) return null const updatedSteps = prev.steps.map(step => { if (step.id === stepId) { const updatedStep = { ...step, status, details: details || step.details } if (status === 'active' && !step.startTime) { updatedStep.startTime = Date.now() } else if ((status === 'completed' || status === 'error') && !step.endTime) { updatedStep.endTime = Date.now() } return updatedStep } return step }) const currentStepIndex = updatedSteps.findIndex(step => step.status === 'active') return { ...prev, steps: updatedSteps, currentStep: currentStepIndex >= 0 ? currentStepIndex + 1 : prev.currentStep } }) } const performAnalysis = async (analysisSymbol = symbol, analysisTimeframes = selectedTimeframes) => { if (loading || selectedLayouts.length === 0 || analysisTimeframes.length === 0) return setLoading(true) setError(null) setResult(null) // Initialize progress tracking const steps = createProgressSteps(analysisTimeframes, selectedLayouts) setProgress({ currentStep: 0, totalSteps: steps.length, steps, timeframeProgress: analysisTimeframes.length > 1 ? { current: 0, total: analysisTimeframes.length } : undefined }) try { updateProgress('init', 'active') if (analysisTimeframes.length === 1) { // Single timeframe analysis await new Promise(resolve => setTimeout(resolve, 500)) // Brief pause for UI updateProgress('init', 'completed') updateProgress('browser', 'active', 'Starting browser session...') const response = await fetch('/api/enhanced-screenshot', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ symbol: analysisSymbol, timeframe: analysisTimeframes[0], layouts: selectedLayouts, analyze: true }) }) // Since we can't track internal API progress in real-time, we'll simulate logical progression await new Promise(resolve => setTimeout(resolve, 1000)) updateProgress('browser', 'completed') updateProgress('auth', 'active', 'Authenticating with TradingView...') await new Promise(resolve => setTimeout(resolve, 2000)) updateProgress('auth', 'completed') updateProgress('navigation', 'active', `Navigating to ${analysisSymbol} chart...`) await new Promise(resolve => setTimeout(resolve, 2000)) updateProgress('navigation', 'completed') updateProgress('loading', 'active', 'Loading chart data and indicators...') await new Promise(resolve => setTimeout(resolve, 3000)) updateProgress('loading', 'completed') updateProgress('capture', 'active', 'Capturing screenshots...') const data = await response.json() if (!response.ok) { updateProgress('capture', 'error', data.error || 'Screenshot capture failed') throw new Error(data.error || 'Analysis failed') } updateProgress('capture', 'completed', `Captured ${data.screenshots?.length || 0} screenshot(s)`) updateProgress('analysis', 'active', 'Running AI analysis...') await new Promise(resolve => setTimeout(resolve, 1000)) updateProgress('analysis', 'completed', 'Analysis complete!') setResult(data) // Call the callback with analysis result if provided if (onAnalysisComplete && data.analysis) { onAnalysisComplete(data.analysis, analysisSymbol) } } else { // Multiple timeframe analysis await new Promise(resolve => setTimeout(resolve, 500)) updateProgress('init', 'completed', `Starting analysis for ${analysisTimeframes.length} timeframes`) const results = [] for (let i = 0; i < analysisTimeframes.length; i++) { const tf = analysisTimeframes[i] const timeframeLabel = timeframes.find(t => t.value === tf)?.label || tf // Update timeframe progress setProgress(prev => prev ? { ...prev, timeframeProgress: { ...prev.timeframeProgress!, current: i + 1, currentTimeframe: timeframeLabel } } : null) console.log(`๐Ÿงช Analyzing timeframe: ${timeframeLabel}`) if (i === 0) { updateProgress('browser', 'active', `Processing ${timeframeLabel} - Starting browser...`) } const response = await fetch('/api/enhanced-screenshot', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ symbol: analysisSymbol, timeframe: tf, layouts: selectedLayouts, analyze: true }) }) if (i === 0) { updateProgress('browser', 'completed') updateProgress('auth', 'active', `Processing ${timeframeLabel} - Authenticating...`) await new Promise(resolve => setTimeout(resolve, 1000)) updateProgress('auth', 'completed') } updateProgress('navigation', 'active', `Processing ${timeframeLabel} - Navigating to chart...`) await new Promise(resolve => setTimeout(resolve, 1000)) updateProgress('loading', 'active', `Processing ${timeframeLabel} - Loading chart data...`) await new Promise(resolve => setTimeout(resolve, 1500)) updateProgress('capture', 'active', `Processing ${timeframeLabel} - Capturing screenshots...`) const result = await response.json() results.push({ timeframe: tf, timeframeLabel, success: response.ok, result }) updateProgress('analysis', 'active', `Processing ${timeframeLabel} - Running AI analysis...`) // Small delay between requests await new Promise(resolve => setTimeout(resolve, 2000)) } updateProgress('navigation', 'completed') updateProgress('loading', 'completed') updateProgress('capture', 'completed', `Captured screenshots for all ${analysisTimeframes.length} timeframes`) updateProgress('analysis', 'completed', `Completed analysis for all timeframes!`) const multiResult = { type: 'multi_timeframe', symbol: analysisSymbol, summary: `Analyzed ${results.length} timeframes for ${analysisSymbol}`, results } setResult(multiResult) // Call the callback with the first successful analysis result if provided if (onAnalysisComplete) { const firstSuccessfulResult = results.find(r => r.success && r.result?.analysis) if (firstSuccessfulResult) { onAnalysisComplete(firstSuccessfulResult.result.analysis, analysisSymbol) } } } } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to perform analysis' setError(errorMessage) // Mark current active step as error setProgress(prev => { if (!prev) return null const activeStepIndex = prev.steps.findIndex(step => step.status === 'active') if (activeStepIndex >= 0) { const updatedSteps = [...prev.steps] updatedSteps[activeStepIndex] = { ...updatedSteps[activeStepIndex], status: 'error', details: errorMessage, endTime: Date.now() } return { ...prev, steps: updatedSteps } } return prev }) } finally { setLoading(false) } } const quickAnalyze = async (coinSymbol: string, quickTimeframes = selectedTimeframes) => { setSymbol(coinSymbol) if (!loading) { await performAnalysis(coinSymbol, quickTimeframes) } } const quickTimeframeTest = async (testTimeframe: string) => { // Toggle the timeframe in selection instead of replacing const newTimeframes = selectedTimeframes.includes(testTimeframe) ? selectedTimeframes.filter(tf => tf !== testTimeframe) : [...selectedTimeframes, testTimeframe] setSelectedTimeframes(newTimeframes) if (!loading && symbol && newTimeframes.length > 0) { await performAnalysis(symbol, newTimeframes) } } const testAllTimeframes = async () => { if (loading) return const allTimeframeValues = timeframes.map(tf => tf.value) setSelectedTimeframes(allTimeframeValues) if (!loading && symbol) { await performAnalysis(symbol, allTimeframeValues) } } async function handleAnalyze() { await performAnalysis() } // Trade initiation handler const handleTradeClick = (tfResult: any) => { console.log('๐Ÿ”ฅ AIAnalysisPanel handleTradeClick called with:', tfResult) const analysis = tfResult?.result?.analysis || tfResult?.analysis || {} console.log('๐Ÿ”ฅ Extracted analysis:', analysis) // Enhanced data extraction with better fallbacks let entryPrice = '' let takeProfit1 = '' let takeProfit2 = '' let stopLoss = '' // Extract entry price with multiple fallback options if (analysis.entry?.price) { entryPrice = analysis.entry.price.toString() } else if (analysis.entry && typeof analysis.entry === 'number') { entryPrice = analysis.entry.toString() } else if (analysis.entry && typeof analysis.entry === 'string') { entryPrice = analysis.entry } // Extract take profit 1 with multiple fallback options if (analysis.takeProfits?.tp1?.price) { takeProfit1 = analysis.takeProfits.tp1.price.toString() } else if (analysis.takeProfits?.tp1 && typeof analysis.takeProfits.tp1 === 'number') { takeProfit1 = analysis.takeProfits.tp1.toString() } else if (analysis.takeProfits && typeof analysis.takeProfits === 'number') { takeProfit1 = analysis.takeProfits.toString() } else if (analysis.takeProfit?.price) { takeProfit1 = analysis.takeProfit.price.toString() } else if (analysis.takeProfit && typeof analysis.takeProfit === 'number') { takeProfit1 = analysis.takeProfit.toString() } // Extract take profit 2 if available if (analysis.takeProfits?.tp2?.price) { takeProfit2 = analysis.takeProfits.tp2.price.toString() } else if (analysis.takeProfits?.tp2 && typeof analysis.takeProfits.tp2 === 'number') { takeProfit2 = analysis.takeProfits.tp2.toString() } // Extract stop loss with multiple fallback options if (analysis.stopLoss?.price) { stopLoss = analysis.stopLoss.price.toString() } else if (analysis.stopLoss && typeof analysis.stopLoss === 'number') { stopLoss = analysis.stopLoss.toString() } else if (analysis.stopLoss && typeof analysis.stopLoss === 'string') { stopLoss = analysis.stopLoss } const tradeData = { entry: entryPrice, tp: takeProfit1, // This maps to tp1 in the modal tp2: takeProfit2, // This will be handled in the modal sl: stopLoss, symbol: symbol, timeframe: tfResult?.timeframeLabel || tfResult?.timeframe || '', } console.log('๐Ÿ”ฅ Enhanced trade data extraction:', { originalAnalysis: analysis, extractedData: tradeData }) setTradeModalData(tradeData) console.log('๐Ÿ”ฅ Opening trade modal...') setTradeModalOpen(true) } // Trade execution API call const executeTrade = async (tradeData: any) => { try { // Use real DEX trading for manual trades const response = await fetch('/api/trading/execute-dex', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ symbol: tradeData.symbol || symbol, side: 'BUY', // Could be derived from analysis amount: parseFloat(tradeData.positionSize) || parseFloat(tradeData.size), stopLoss: parseFloat(tradeData.sl), takeProfit: parseFloat(tradeData.tp1), // Use TP1 as primary target useRealDEX: true, // Enable real trading for manual execution tradingPair: `${tradeData.symbol || symbol}/USDC`, quickSwap: false }) }) const result = await response.json() if (response.ok && result.success) { // Show detailed success message for DEX execution let message = `โœ… Real DEX Trade executed successfully!\n\n` message += `๐Ÿ“Š Transaction ID: ${result.trade?.txId || result.txId}\n` message += `๐Ÿ’ฐ Symbol: ${tradeData.symbol || symbol}\n` message += `๐Ÿ“ˆ Size: ${tradeData.positionSize || tradeData.size}\n` message += `๐Ÿช DEX: ${result.trade?.dex || 'Jupiter'}\n` if (tradeData.sl) message += `๐Ÿ›‘ Stop Loss: $${tradeData.sl}\n` if (tradeData.tp1) message += `๐ŸŽฏ Take Profit: $${tradeData.tp1}\n` if (result.trade?.monitoring) { message += `\n๐Ÿ”„ Position monitoring: ACTIVE` } alert(message) } else { // Show detailed error message const errorMsg = result.error || 'Unknown error occurred' if (errorMsg.includes('not configured') || errorMsg.includes('Wallet not initialized')) { alert(`โŒ Trade Failed: Jupiter DEX Not Configured\n\nPlease configure your Jupiter DEX wallet in the settings before executing real trades.\n\nError: ${errorMsg}`) } else if (errorMsg.includes('insufficient') || errorMsg.includes('balance')) { alert(`โŒ Trade Failed: Insufficient Balance\n\nPlease ensure you have enough tokens in your wallet.\n\nError: ${errorMsg}`) } else if (errorMsg.includes('Real Jupiter Perpetuals trading not yet implemented')) { alert(`โŒ Real Trading Not Available\n\nReal Jupiter Perpetuals trading is still in development. This trade will be simulated instead.\n\nTo use real spot trading, reduce the leverage to 1x.`) } else { alert(`โŒ Trade Failed\n\nError: ${errorMsg}`) } } } catch (error) { console.error('Trade execution failed:', error) alert('โŒ Trade execution failed due to network error.\n\nPlease check your connection and try again.') } setTradeModalOpen(false) } // Screenshot gallery modal const handleScreenshotClick = (src: string) => { setEnlargedScreenshot(src) } return (

๐Ÿค– AI Chart Analysis

AI Powered
{/* Quick Coin & Timeframe Analysis */}

Quick Analysis

Select coin + timeframe combo for instant analysis
{/* Quick Timeframe Presets */}
{/* Coin Selection */}
{popularCoins.map(coin => ( ))}
{/* Advanced Analysis Section */}

Advanced Analysis

{/* Symbol Input */}
setSymbol(e.target.value.toUpperCase())} placeholder="e.g., BTCUSD, ETHUSD" />
{/* Timeframe Selection */}
{timeframes.map(tf => ( ))}
{selectedTimeframes.length > 0 && (
Selected timeframes: {selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label).join(', ')}
๐Ÿ’ก Multiple timeframes provide broader market outlook
)}
{/* Layout Selection */}
{layouts.map(layout => ( ))}
{selectedLayouts.length > 0 && (
Selected layouts: {selectedLayouts.join(', ')}
)}
{/* Quick Timeframe Actions */}
{timeframes.map(tf => ( ))}
{/* Analyze Button */}
{/* Results Section */} {error && (
โš ๏ธ

Analysis Error

{error}

)} {loading && progress && (
{/* Header */}

AI Analysis in Progress

Analyzing {symbol} โ€ข {selectedLayouts.join(', ')} layouts

{/* Overall Progress */}
Step {progress.currentStep} of {progress.totalSteps}
{Math.round((progress.currentStep / progress.totalSteps) * 100)}% Complete
{/* Multi-timeframe progress */} {progress.timeframeProgress && (
Multi-Timeframe Analysis
{progress.timeframeProgress.current}/{progress.timeframeProgress.total} timeframes
{progress.timeframeProgress.currentTimeframe && (

Current: {progress.timeframeProgress.currentTimeframe}

)}
)} {/* Progress Steps */}
{progress.steps.map((step, index) => { const isActive = step.status === 'active' const isCompleted = step.status === 'completed' const isError = step.status === 'error' const isPending = step.status === 'pending' return (
{/* Step Icon */}
{isCompleted ? 'โœ“' : isError ? 'โœ—' : isActive ? 'โŸณ' : index + 1}
{/* Step Content */}
{step.title}
{/* Timing */} {(step.startTime || step.endTime) && ( {step.endTime && step.startTime ? `${((step.endTime - step.startTime) / 1000).toFixed(1)}s` : isActive && step.startTime ? `${((Date.now() - step.startTime) / 1000).toFixed(0)}s` : '' } )}

{step.details || step.description}

{/* Active indicator */} {isActive && (
)}
) })}
{/* Overall Progress Bar */}
)} {result && result.type === 'multi_timeframe' && (

๐Ÿ“Š Multi-Timeframe Analysis

{result.symbol} โ€ข {result.results.length} timeframes

Analysis Summary

{result.summary}

{result.results.map((timeframeResult: any, index: number) => (
{timeframeResult.success ? 'โœ…' : 'โŒ'} {timeframeResult.timeframeLabel} Timeframe
{timeframeResult.success && timeframeResult.result.analysis && ( )} {timeframeResult.success ? 'Analysis Complete' : 'Failed'}
{timeframeResult.success && timeframeResult.result.analysis && (
Sentiment
{safeRender(timeframeResult.result.analysis.marketSentiment)}
Recommendation
{safeRender(timeframeResult.result.analysis.recommendation)}
Confidence
{safeRender(timeframeResult.result.analysis.confidence)}%
)} {timeframeResult.success && timeframeResult.result.analysis?.entry && (
Entry Setup
๐Ÿ“ ${safeRender(timeframeResult.result.analysis.entry.price)} {timeframeResult.result.analysis.entry.buffer && ( {safeRender(timeframeResult.result.analysis.entry.buffer)} )}
{timeframeResult.result.analysis.stopLoss && (
๐Ÿ›‘ SL: ${safeRender(timeframeResult.result.analysis.stopLoss.price)}
)} {timeframeResult.result.analysis.takeProfits && (
{timeframeResult.result.analysis.takeProfits.tp1 && (
๐ŸŽฏ TP1: ${typeof timeframeResult.result.analysis.takeProfits.tp1.price !== 'undefined' ? safeRender(timeframeResult.result.analysis.takeProfits.tp1.price) : safeRender(timeframeResult.result.analysis.takeProfits.tp1)}
)} {timeframeResult.result.analysis.takeProfits.tp2 && (
๐ŸŽฏ TP2: ${typeof timeframeResult.result.analysis.takeProfits.tp2.price !== 'undefined' ? safeRender(timeframeResult.result.analysis.takeProfits.tp2.price) : safeRender(timeframeResult.result.analysis.takeProfits.tp2)}
)} {/* Fallback for simple take profit format */} {!timeframeResult.result.analysis.takeProfits.tp1 && !timeframeResult.result.analysis.takeProfits.tp2 && (
๐ŸŽฏ TP: {typeof timeframeResult.result.analysis.takeProfits === 'object' ? Object.values(timeframeResult.result.analysis.takeProfits).map((tp: any) => `$${safeRender(tp)}`).join(', ') : `$${safeRender(timeframeResult.result.analysis.takeProfits)}`}
)}
)}
)} {!timeframeResult.success && (
Analysis failed for this timeframe
)}
))}
)} {result && result.analysis && (

โœ… Analysis Complete

{result.analysis && ( )} {result.screenshots && (
Screenshots: {result.screenshots.length} captured
)}
{/* Summary */}

Market Summary

{safeRender(result.analysis.summary)}

{/* Key Metrics */}

Market Sentiment

{safeRender(result.analysis.marketSentiment)}

Recommendation

{safeRender(result.analysis.recommendation)}

{result.analysis.confidence && (

{safeRender(result.analysis.confidence)}% confidence

)}
{/* Trading Levels */} {result.analysis.keyLevels && (

Resistance Levels

{result.analysis.keyLevels.resistance?.join(', ') || 'None identified'}

Support Levels

{result.analysis.keyLevels.support?.join(', ') || 'None identified'}

)} {/* Trading Setup */} {(result.analysis.entry || result.analysis.stopLoss || result.analysis.takeProfits) && (

Trading Setup

{result.analysis.entry && (
Entry Point

๐Ÿ“ ${safeRender(result.analysis.entry.price || result.analysis.entry)} {result.analysis.entry.buffer && ( {safeRender(result.analysis.entry.buffer)} )}

{result.analysis.entry.rationale && (

๐Ÿ’ก {safeRender(result.analysis.entry.rationale)}

)}
)} {result.analysis.stopLoss && (
Stop Loss

๐Ÿ›‘ ${safeRender(result.analysis.stopLoss.price || result.analysis.stopLoss)}

{result.analysis.stopLoss.rationale && (

๐Ÿ’ก {safeRender(result.analysis.stopLoss.rationale)}

)}
)} {result.analysis.takeProfits && (
Take Profit Targets
{result.analysis.takeProfits.tp1 && (
๐Ÿฅ‰ TP1: ${typeof result.analysis.takeProfits.tp1.price !== 'undefined' ? result.analysis.takeProfits.tp1.price : safeRender(result.analysis.takeProfits.tp1)}
{result.analysis.takeProfits.tp1.description && (

๐Ÿ“‹ {safeRender(result.analysis.takeProfits.tp1.description)}

)} {result.analysis.takeProfits.tp1.rsiExpectation && (

๐Ÿ“Š RSI: {safeRender(result.analysis.takeProfits.tp1.rsiExpectation)}

)} {result.analysis.takeProfits.tp1.obvExpectation && (

๐Ÿ“ˆ OBV: {safeRender(result.analysis.takeProfits.tp1.obvExpectation)}

)}
)} {result.analysis.takeProfits.tp2 && (
๐Ÿฅˆ TP2: ${typeof result.analysis.takeProfits.tp2.price !== 'undefined' ? result.analysis.takeProfits.tp2.price : safeRender(result.analysis.takeProfits.tp2)}
{result.analysis.takeProfits.tp2.description && (

๐Ÿ“‹ {safeRender(result.analysis.takeProfits.tp2.description)}

)} {result.analysis.takeProfits.tp2.rsiExpectation && (

๐Ÿ“Š RSI: {safeRender(result.analysis.takeProfits.tp2.rsiExpectation)}

)} {result.analysis.takeProfits.tp2.obvExpectation && (

๐Ÿ“ˆ OBV: {safeRender(result.analysis.takeProfits.tp2.obvExpectation)}

)}
)} {/* Fallback for simple take profit format */} {!result.analysis.takeProfits.tp1 && !result.analysis.takeProfits.tp2 && (

{typeof result.analysis.takeProfits === 'object' ? Object.values(result.analysis.takeProfits).map(tp => `$${safeRender(tp)}`).join(', ') : `$${safeRender(result.analysis.takeProfits)}`}

)}
)}
)} {/* Risk Management & Confirmation */} {(result.analysis.riskToReward || result.analysis.confirmationTrigger) && (

Risk Management

{result.analysis.riskToReward && (
Risk/Reward Ratio

โš–๏ธ {safeRender(result.analysis.riskToReward)}

)} {result.analysis.confirmationTrigger && (
Confirmation Trigger

๐Ÿ”” {safeRender(result.analysis.confirmationTrigger)}

)}
)} {/* Timeframe Risk Assessment */} {result.analysis.timeframeRisk && (

โฐ Timeframe Risk Assessment

{result.analysis.timeframeRisk.assessment && (
Risk Level

๐Ÿ“Š {safeRender(result.analysis.timeframeRisk.assessment)}

)} {result.analysis.timeframeRisk.positionSize && (
Position Size

๐Ÿ’ผ {safeRender(result.analysis.timeframeRisk.positionSize)}

)} {result.analysis.timeframeRisk.leverageRecommendation && (
Leverage

๐ŸŽš๏ธ {safeRender(result.analysis.timeframeRisk.leverageRecommendation)}

)}
)} {/* Technical Indicators */} {result.analysis.indicatorAnalysis && (

๐Ÿ“ˆ Technical Indicators

{result.analysis.indicatorAnalysis.rsi && (
๐Ÿ“Š RSI

{safeRender(result.analysis.indicatorAnalysis.rsi)}

)} {result.analysis.indicatorAnalysis.vwap && (
๐Ÿ“ˆ VWAP

{safeRender(result.analysis.indicatorAnalysis.vwap)}

)} {result.analysis.indicatorAnalysis.obv && (
๐Ÿ“Š OBV

{safeRender(result.analysis.indicatorAnalysis.obv)}

)} {result.analysis.indicatorAnalysis.macd && (
๐Ÿ“‰ MACD

{safeRender(result.analysis.indicatorAnalysis.macd)}

)}
)} {/* Alternatives */} {result.analysis.alternatives && (

๐Ÿ”„ Alternative Strategies

{result.analysis.alternatives.tigherStopOption && (
๐ŸŽฏ Tighter Stop Option

{safeRender(result.analysis.alternatives.tigherStopOption)}

)} {result.analysis.alternatives.scaledEntry && (
๐Ÿ“Š Scaled Entry

{safeRender(result.analysis.alternatives.scaledEntry)}

)} {result.analysis.alternatives.invalidationScenario && (
โŒ Invalidation Scenario

{safeRender(result.analysis.alternatives.invalidationScenario)}

)}
)} {/* Layout Comparison Section */} {result.analysis.layoutComparison && (

Multi-Layout Analysis

{result.analysis.layoutComparison.aiLayout && (
AI Layout Insights

{result.analysis.layoutComparison.aiLayout}

)} {result.analysis.layoutComparison.diyLayout && (
DIY Layout Insights

{result.analysis.layoutComparison.diyLayout}

)}
{result.analysis.layoutComparison.consensus && (
Layout Consensus

{result.analysis.layoutComparison.consensus}

)} {result.analysis.layoutComparison.divergences && (
Layout Divergences

{result.analysis.layoutComparison.divergences}

)}
)} {/* Enhanced Indicator Analysis */} {result.analysis.indicatorAnalysis?.crossLayoutConsensus && (

Cross-Layout Consensus

{result.analysis.indicatorAnalysis.crossLayoutConsensus}

)}
)} {result && !result.analysis && result.screenshots && (

Screenshots Captured

Screenshots were captured successfully, but AI analysis failed or was not requested.

Screenshots: {result.screenshots.length} captured
{result.screenshots.map((screenshot: string, index: number) => (
{screenshot.split('/').pop()}
))}
)} {/* Screenshot Gallery */} {result && result.screenshots && ( timeframes.find(t => t.value === tf)?.label || tf)} enlargedImage={enlargedScreenshot} onImageClick={handleScreenshotClick} onClose={() => setEnlargedScreenshot(null)} /> )} {/* Multi-timeframe Screenshot Gallery */} {result && result.type === 'multi_timeframe' && result.results && ( r.success && r.result.screenshots).flatMap((r: any) => r.result.screenshots)} symbol={symbol} timeframes={result.results.filter((r: any) => r.success).map((r: any) => r.timeframeLabel)} enlargedImage={enlargedScreenshot} onImageClick={handleScreenshotClick} onClose={() => setEnlargedScreenshot(null)} /> )} {/* Trade Modal */} {console.log('๐Ÿ”ฅ About to render TradeModal with:', { isOpen: tradeModalOpen, tradeData: tradeModalData })} { console.log('๐Ÿ”ฅ TradeModal onClose called') setTradeModalOpen(false) }} tradeData={tradeModalData} onExecute={executeTrade} />
) }