Files
trading_bot_v3/components/AIAnalysisPanel.tsx
mindesbunister 4f125ac6b6 🎨 Beautiful take profit display and enhanced trading UI
- Enhanced take profit section with structured TP1/TP2 display
- Added RSI/OBV expectations for each target with color-coded indicators
- Implemented comprehensive risk management section with R:R ratios
- Added timeframe risk assessment with leverage recommendations
- Enhanced technical indicators section with organized layout
- Added alternative strategies section for tighter stops and scaled entries
- Improved entry point and stop loss display with emojis and better formatting
- Professional trading dashboard with all analysis components beautifully displayed
2025-07-13 17:58:52 +02:00

709 lines
33 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import React, { useState } from 'react'
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' },
]
export default function AIAnalysisPanel() {
const [symbol, setSymbol] = useState('BTCUSD')
const [selectedLayouts, setSelectedLayouts] = useState<string[]>([layouts[0]])
const [timeframe, setTimeframe] = useState('60')
const [loading, setLoading] = useState(false)
const [result, setResult] = useState<any>(null)
const [error, setError] = useState<string | null>(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 performAnalysis = async (analysisSymbol = symbol, analysisTimeframe = timeframe) => {
if (loading || selectedLayouts.length === 0) return
setLoading(true)
setError(null)
setResult(null)
try {
const response = await fetch('/api/enhanced-screenshot', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
symbol: analysisSymbol,
timeframe: analysisTimeframe,
layouts: selectedLayouts,
analyze: true // Request AI analysis of captured screenshots
})
})
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || 'Analysis failed')
}
setResult(data)
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to perform analysis')
} finally {
setLoading(false)
}
}
const quickAnalyze = async (coinSymbol: string) => {
setSymbol(coinSymbol)
if (!loading) {
await performAnalysis(coinSymbol)
}
}
const quickTimeframeTest = async (testTimeframe: string) => {
setTimeframe(testTimeframe)
if (!loading && symbol) {
await performAnalysis(symbol, testTimeframe)
}
}
const testAllTimeframes = async () => {
if (loading) return
setLoading(true)
setError(null)
const results = []
try {
for (const tf of timeframes) {
console.log(`🧪 Testing timeframe: ${tf.label}`)
setTimeframe(tf.value)
const response = await fetch('/api/enhanced-screenshot', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
symbol,
timeframe: tf.value,
layouts: selectedLayouts,
analyze: true // Request AI analysis for timeframe testing too
})
})
const result = await response.json()
results.push({ timeframe: tf.label, success: response.ok, result })
// Small delay between tests
await new Promise(resolve => setTimeout(resolve, 2000))
}
setResult({
type: 'timeframe_test',
summary: `Tested ${results.length} timeframes`,
results
})
} catch (err) {
setError(err instanceof Error ? err.message : 'Timeframe testing failed')
} finally {
setLoading(false)
}
}
async function handleAnalyze() {
await performAnalysis()
}
return (
<div className="card card-gradient">
<div className="flex items-center justify-between mb-6">
<h2 className="text-xl font-bold text-white flex items-center">
<span className="w-8 h-8 bg-gradient-to-br from-cyan-400 to-blue-600 rounded-lg flex items-center justify-center mr-3">
🤖
</span>
AI Chart Analysis
</h2>
<div className="flex items-center space-x-2 text-sm text-gray-400">
<div className="w-2 h-2 bg-cyan-400 rounded-full animate-pulse"></div>
<span>AI Powered</span>
</div>
</div>
{/* Quick Coin Selection */}
<div className="mb-8">
<div className="flex items-center justify-between mb-4">
<h3 className="text-sm font-semibold text-gray-300 flex items-center">
<span className="w-4 h-4 bg-yellow-500 rounded-full mr-2"></span>
Quick Analysis
</h3>
<span className="text-xs text-gray-500">Click any coin for instant analysis</span>
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
{popularCoins.map(coin => (
<button
key={coin.symbol}
onClick={() => quickAnalyze(coin.symbol)}
disabled={loading}
className={`group relative p-4 rounded-xl border transition-all duration-300 ${
symbol === coin.symbol
? 'border-cyan-500 bg-cyan-500/10 shadow-lg shadow-cyan-500/20'
: 'border-gray-700 bg-gray-800/50 hover:border-gray-600 hover:bg-gray-800'
} ${loading ? 'opacity-50 cursor-not-allowed' : 'hover:scale-105 hover:shadow-lg'}`}
>
<div className={`w-10 h-10 bg-gradient-to-br ${coin.color} rounded-lg flex items-center justify-center mb-3 mx-auto text-white font-bold`}>
{coin.icon}
</div>
<div className="text-xs font-semibold text-white">{coin.name}</div>
<div className="text-xs text-gray-400 mt-1">{coin.symbol}</div>
{symbol === coin.symbol && (
<div className="absolute top-2 right-2 w-2 h-2 bg-cyan-400 rounded-full animate-pulse"></div>
)}
</button>
))}
</div>
</div>
{/* Advanced Controls */}
<div className="border-t border-gray-700 pt-6">
<h3 className="text-sm font-semibold text-gray-300 mb-4 flex items-center">
<span className="w-4 h-4 bg-purple-500 rounded-full mr-2"></span>
Advanced Analysis
</h3>
{/* Symbol and Timeframe */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<div className="md:col-span-2">
<label className="block text-xs font-medium text-gray-400 mb-2">Trading Pair</label>
<input
className="w-full px-4 py-3 bg-gray-800/50 border border-gray-700 rounded-lg text-white placeholder-gray-500 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all"
value={symbol}
onChange={e => setSymbol(e.target.value.toUpperCase())}
placeholder="e.g., BTCUSD, ETHUSD"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 mb-2">Timeframe</label>
<select
className="w-full px-4 py-3 bg-gray-800/50 border border-gray-700 rounded-lg text-white focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20 transition-all"
value={timeframe}
onChange={e => setTimeframe(e.target.value)}
>
{timeframes.map(tf => (
<option key={tf.value} value={tf.value} className="bg-gray-800">
{tf.label}
</option>
))}
</select>
</div>
</div>
{/* Layout Selection */}
<div className="mb-6">
<label className="block text-xs font-medium text-gray-400 mb-3">Analysis Layouts</label>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
{layouts.map(layout => (
<label key={layout} className="group relative">
<input
type="checkbox"
checked={selectedLayouts.includes(layout)}
onChange={() => toggleLayout(layout)}
className="sr-only"
/>
<div className={`flex items-center p-3 rounded-lg border cursor-pointer transition-all ${
selectedLayouts.includes(layout)
? 'border-cyan-500 bg-cyan-500/10 text-cyan-300'
: 'border-gray-700 bg-gray-800/30 text-gray-300 hover:border-gray-600 hover:bg-gray-800/50'
}`}>
<div className={`w-4 h-4 rounded border-2 mr-3 flex items-center justify-center ${
selectedLayouts.includes(layout)
? 'border-cyan-500 bg-cyan-500'
: 'border-gray-600'
}`}>
{selectedLayouts.includes(layout) && (
<svg className="w-2 h-2 text-white" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
)}
</div>
<span className="text-sm font-medium">{layout}</span>
</div>
</label>
))}
</div>
{selectedLayouts.length > 0 && (
<div className="mt-3 p-3 bg-gray-800/30 rounded-lg">
<div className="text-xs text-gray-400">
Selected layouts: <span className="text-cyan-400">{selectedLayouts.join(', ')}</span>
</div>
</div>
)}
</div>
{/* Quick Timeframe Testing */}
<div className="mb-6">
<label className="block text-xs font-medium text-gray-400 mb-3">Quick Timeframe Tests</label>
<div className="grid grid-cols-4 gap-2 mb-3">
{timeframes.map(tf => (
<button
key={tf.value}
onClick={() => quickTimeframeTest(tf.value)}
disabled={loading || selectedLayouts.length === 0}
className={`py-2 px-3 rounded-lg text-xs font-medium transition-all ${
timeframe === tf.value
? 'bg-cyan-500 text-white shadow-lg'
: loading
? 'bg-gray-700 text-gray-500 cursor-not-allowed'
: 'bg-gray-700 text-gray-300 hover:bg-gray-600 hover:text-white transform hover:scale-105'
}`}
>
{tf.label}
</button>
))}
</div>
<button
onClick={testAllTimeframes}
disabled={loading || selectedLayouts.length === 0 || !symbol}
className={`w-full py-2 px-4 rounded-lg text-sm font-medium transition-all ${
loading
? 'bg-gray-700 text-gray-500 cursor-not-allowed'
: 'bg-gradient-to-r from-purple-500 to-pink-500 text-white hover:from-purple-600 hover:to-pink-600 transform hover:scale-[1.02] active:scale-[0.98] shadow-lg'
}`}
>
{loading ? '🔄 Testing...' : '🧪 Test All Timeframes'}
</button>
</div>
{/* Analyze Button */}
<button
className={`w-full py-3 px-6 rounded-lg font-semibold transition-all duration-300 ${
loading
? 'bg-gray-700 text-gray-400 cursor-not-allowed'
: 'btn-primary transform hover:scale-[1.02] active:scale-[0.98]'
}`}
onClick={handleAnalyze}
disabled={loading}
>
{loading ? (
<div className="flex items-center justify-center space-x-2">
<div className="spinner"></div>
<span>Analyzing Chart...</span>
</div>
) : (
<div className="flex items-center justify-center space-x-2">
<span>🚀</span>
<span>Start AI Analysis</span>
</div>
)}
</button>
</div>
{/* Results Section */}
{error && (
<div className="mt-6 p-4 bg-red-500/10 border border-red-500/30 rounded-lg">
<div className="flex items-start space-x-3">
<div className="w-5 h-5 text-red-400 mt-0.5"></div>
<div>
<h4 className="text-red-400 font-medium text-sm">Analysis Error</h4>
<p className="text-red-300 text-xs mt-1 opacity-90">{error}</p>
</div>
</div>
</div>
)}
{loading && (
<div className="mt-6 p-4 bg-cyan-500/10 border border-cyan-500/30 rounded-lg">
<div className="flex items-center space-x-3">
<div className="spinner border-cyan-500"></div>
<div>
<h4 className="text-cyan-400 font-medium text-sm">AI Processing</h4>
<p className="text-cyan-300 text-xs mt-1 opacity-90">
Analyzing {symbol} on {timeframe} timeframe...
</p>
</div>
</div>
</div>
)}
{result && result.analysis && (
<div className="mt-6 space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-bold text-white flex items-center">
<span className="w-6 h-6 bg-gradient-to-br from-green-400 to-emerald-600 rounded-lg flex items-center justify-center mr-2 text-sm">
</span>
Analysis Complete
</h3>
{result.screenshots && (
<div className="text-xs text-gray-400">
Screenshots: {result.screenshots.length} captured
</div>
)}
</div>
<div className="grid gap-4">
{/* Summary */}
<div className="p-4 bg-gradient-to-r from-gray-800/50 to-gray-700/50 rounded-lg border border-gray-700">
<h4 className="text-sm font-semibold text-gray-300 mb-2 flex items-center">
<span className="w-4 h-4 bg-blue-500 rounded-full mr-2"></span>
Market Summary
</h4>
<p className="text-white text-sm leading-relaxed">{safeRender(result.analysis.summary)}</p>
</div>
{/* Key Metrics */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="p-4 bg-gradient-to-br from-green-500/10 to-emerald-500/10 border border-green-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-green-400 mb-2">Market Sentiment</h4>
<p className="text-white font-medium">{safeRender(result.analysis.marketSentiment)}</p>
</div>
<div className="p-4 bg-gradient-to-br from-blue-500/10 to-cyan-500/10 border border-blue-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-blue-400 mb-2">Recommendation</h4>
<p className="text-white font-medium">{safeRender(result.analysis.recommendation)}</p>
{result.analysis.confidence && (
<p className="text-cyan-300 text-xs mt-1">{safeRender(result.analysis.confidence)}% confidence</p>
)}
</div>
</div>
{/* Trading Levels */}
{result.analysis.keyLevels && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="p-4 bg-gradient-to-br from-red-500/10 to-rose-500/10 border border-red-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-red-400 mb-2">Resistance Levels</h4>
<p className="text-red-300 font-mono text-sm">
{result.analysis.keyLevels.resistance?.join(', ') || 'None identified'}
</p>
</div>
<div className="p-4 bg-gradient-to-br from-green-500/10 to-emerald-500/10 border border-green-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-green-400 mb-2">Support Levels</h4>
<p className="text-green-300 font-mono text-sm">
{result.analysis.keyLevels.support?.join(', ') || 'None identified'}
</p>
</div>
</div>
)}
{/* Trading Setup */}
{(result.analysis.entry || result.analysis.stopLoss || result.analysis.takeProfits) && (
<div className="p-4 bg-gradient-to-br from-purple-500/10 to-violet-500/10 border border-purple-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-purple-400 mb-3">Trading Setup</h4>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
{result.analysis.entry && (
<div>
<span className="text-xs text-gray-400">Entry Point</span>
<p className="text-yellow-300 font-mono font-semibold">
📍 ${safeRender(result.analysis.entry.price || result.analysis.entry)}
{result.analysis.entry.buffer && (
<span className="text-yellow-400 text-xs ml-1">{safeRender(result.analysis.entry.buffer)}</span>
)}
</p>
{result.analysis.entry.rationale && (
<p className="text-xs text-gray-300 mt-1">💡 {safeRender(result.analysis.entry.rationale)}</p>
)}
</div>
)}
{result.analysis.stopLoss && (
<div>
<span className="text-xs text-gray-400">Stop Loss</span>
<p className="text-red-300 font-mono font-semibold">
🛑 ${safeRender(result.analysis.stopLoss.price || result.analysis.stopLoss)}
</p>
{result.analysis.stopLoss.rationale && (
<p className="text-xs text-gray-300 mt-1">💡 {safeRender(result.analysis.stopLoss.rationale)}</p>
)}
</div>
)}
{result.analysis.takeProfits && (
<div>
<span className="text-xs text-gray-400">Take Profit Targets</span>
<div className="space-y-2 mt-2">
{result.analysis.takeProfits.tp1 && (
<div className="p-2 bg-green-500/5 rounded border border-green-500/20">
<div className="flex items-center gap-2">
<span className="text-yellow-400">🥉</span>
<span className="text-green-300 font-mono font-semibold">
TP1: ${typeof result.analysis.takeProfits.tp1.price !== 'undefined'
? result.analysis.takeProfits.tp1.price
: safeRender(result.analysis.takeProfits.tp1)}
</span>
</div>
{result.analysis.takeProfits.tp1.description && (
<p className="text-xs text-green-200 mt-1">
📋 {safeRender(result.analysis.takeProfits.tp1.description)}
</p>
)}
{result.analysis.takeProfits.tp1.rsiExpectation && (
<p className="text-xs text-blue-200 mt-1">
📊 RSI: {safeRender(result.analysis.takeProfits.tp1.rsiExpectation)}
</p>
)}
{result.analysis.takeProfits.tp1.obvExpectation && (
<p className="text-xs text-purple-200 mt-1">
📈 OBV: {safeRender(result.analysis.takeProfits.tp1.obvExpectation)}
</p>
)}
</div>
)}
{result.analysis.takeProfits.tp2 && (
<div className="p-2 bg-green-500/5 rounded border border-green-500/20">
<div className="flex items-center gap-2">
<span className="text-gray-300">🥈</span>
<span className="text-green-300 font-mono font-semibold">
TP2: ${typeof result.analysis.takeProfits.tp2.price !== 'undefined'
? result.analysis.takeProfits.tp2.price
: safeRender(result.analysis.takeProfits.tp2)}
</span>
</div>
{result.analysis.takeProfits.tp2.description && (
<p className="text-xs text-green-200 mt-1">
📋 {safeRender(result.analysis.takeProfits.tp2.description)}
</p>
)}
{result.analysis.takeProfits.tp2.rsiExpectation && (
<p className="text-xs text-blue-200 mt-1">
📊 RSI: {safeRender(result.analysis.takeProfits.tp2.rsiExpectation)}
</p>
)}
{result.analysis.takeProfits.tp2.obvExpectation && (
<p className="text-xs text-purple-200 mt-1">
📈 OBV: {safeRender(result.analysis.takeProfits.tp2.obvExpectation)}
</p>
)}
</div>
)}
{/* Fallback for simple take profit format */}
{!result.analysis.takeProfits.tp1 && !result.analysis.takeProfits.tp2 && (
<p className="text-green-300 font-mono font-semibold">
{typeof result.analysis.takeProfits === 'object'
? Object.values(result.analysis.takeProfits).map(tp => `$${safeRender(tp)}`).join(', ')
: `$${safeRender(result.analysis.takeProfits)}`}
</p>
)}
</div>
</div>
)}
</div>
</div>
)}
{/* Risk Management & Confirmation */}
{(result.analysis.riskToReward || result.analysis.confirmationTrigger) && (
<div className="p-4 bg-gradient-to-br from-amber-500/10 to-orange-500/10 border border-amber-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-amber-400 mb-3">Risk Management</h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
{result.analysis.riskToReward && (
<div>
<span className="text-xs text-amber-400">Risk/Reward Ratio</span>
<p className="text-amber-200 font-mono font-semibold"> {safeRender(result.analysis.riskToReward)}</p>
</div>
)}
{result.analysis.confirmationTrigger && (
<div>
<span className="text-xs text-amber-400">Confirmation Trigger</span>
<p className="text-amber-200 text-sm">🔔 {safeRender(result.analysis.confirmationTrigger)}</p>
</div>
)}
</div>
</div>
)}
{/* Timeframe Risk Assessment */}
{result.analysis.timeframeRisk && (
<div className="p-4 bg-gradient-to-br from-red-500/10 to-pink-500/10 border border-red-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-red-400 mb-3"> Timeframe Risk Assessment</h4>
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
{result.analysis.timeframeRisk.assessment && (
<div>
<span className="text-xs text-red-400">Risk Level</span>
<p className="text-red-200 font-semibold">📊 {safeRender(result.analysis.timeframeRisk.assessment)}</p>
</div>
)}
{result.analysis.timeframeRisk.positionSize && (
<div>
<span className="text-xs text-red-400">Position Size</span>
<p className="text-red-200 font-semibold">💼 {safeRender(result.analysis.timeframeRisk.positionSize)}</p>
</div>
)}
{result.analysis.timeframeRisk.leverageRecommendation && (
<div>
<span className="text-xs text-red-400">Leverage</span>
<p className="text-red-200 font-semibold">🎚 {safeRender(result.analysis.timeframeRisk.leverageRecommendation)}</p>
</div>
)}
</div>
</div>
)}
{/* Technical Indicators */}
{result.analysis.indicatorAnalysis && (
<div className="p-4 bg-gradient-to-br from-cyan-500/10 to-blue-500/10 border border-cyan-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-cyan-400 mb-3">📈 Technical Indicators</h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
{result.analysis.indicatorAnalysis.rsi && (
<div className="p-2 bg-cyan-500/5 rounded border border-cyan-500/20">
<span className="text-xs text-cyan-400 font-semibold">📊 RSI</span>
<p className="text-cyan-200 text-xs mt-1">{safeRender(result.analysis.indicatorAnalysis.rsi)}</p>
</div>
)}
{result.analysis.indicatorAnalysis.vwap && (
<div className="p-2 bg-blue-500/5 rounded border border-blue-500/20">
<span className="text-xs text-blue-400 font-semibold">📈 VWAP</span>
<p className="text-blue-200 text-xs mt-1">{safeRender(result.analysis.indicatorAnalysis.vwap)}</p>
</div>
)}
{result.analysis.indicatorAnalysis.obv && (
<div className="p-2 bg-purple-500/5 rounded border border-purple-500/20">
<span className="text-xs text-purple-400 font-semibold">📊 OBV</span>
<p className="text-purple-200 text-xs mt-1">{safeRender(result.analysis.indicatorAnalysis.obv)}</p>
</div>
)}
{result.analysis.indicatorAnalysis.macd && (
<div className="p-2 bg-indigo-500/5 rounded border border-indigo-500/20">
<span className="text-xs text-indigo-400 font-semibold">📉 MACD</span>
<p className="text-indigo-200 text-xs mt-1">{safeRender(result.analysis.indicatorAnalysis.macd)}</p>
</div>
)}
</div>
</div>
)}
{/* Alternatives */}
{result.analysis.alternatives && (
<div className="p-4 bg-gradient-to-br from-violet-500/10 to-purple-500/10 border border-violet-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-violet-400 mb-3">🔄 Alternative Strategies</h4>
<div className="space-y-2">
{result.analysis.alternatives.tigherStopOption && (
<div className="p-2 bg-violet-500/5 rounded border border-violet-500/20">
<span className="text-xs text-violet-400 font-semibold">🎯 Tighter Stop Option</span>
<p className="text-violet-200 text-xs mt-1">{safeRender(result.analysis.alternatives.tigherStopOption)}</p>
</div>
)}
{result.analysis.alternatives.scaledEntry && (
<div className="p-2 bg-purple-500/5 rounded border border-purple-500/20">
<span className="text-xs text-purple-400 font-semibold">📊 Scaled Entry</span>
<p className="text-purple-200 text-xs mt-1">{safeRender(result.analysis.alternatives.scaledEntry)}</p>
</div>
)}
{result.analysis.alternatives.invalidationScenario && (
<div className="p-2 bg-red-500/5 rounded border border-red-500/20">
<span className="text-xs text-red-400 font-semibold"> Invalidation Scenario</span>
<p className="text-red-200 text-xs mt-1">{safeRender(result.analysis.alternatives.invalidationScenario)}</p>
</div>
)}
</div>
</div>
)}
{/* Layout Comparison Section */}
{result.analysis.layoutComparison && (
<div className="p-4 bg-gradient-to-br from-indigo-500/10 to-blue-500/10 border border-indigo-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-indigo-400 mb-3">Multi-Layout Analysis</h4>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
{result.analysis.layoutComparison.aiLayout && (
<div className="p-3 bg-blue-500/5 rounded border border-blue-500/20">
<span className="text-xs text-blue-400 font-semibold">AI Layout Insights</span>
<p className="text-xs text-blue-200 mt-1">{result.analysis.layoutComparison.aiLayout}</p>
</div>
)}
{result.analysis.layoutComparison.diyLayout && (
<div className="p-3 bg-green-500/5 rounded border border-green-500/20">
<span className="text-xs text-green-400 font-semibold">DIY Layout Insights</span>
<p className="text-xs text-green-200 mt-1">{result.analysis.layoutComparison.diyLayout}</p>
</div>
)}
</div>
{result.analysis.layoutComparison.consensus && (
<div className="mt-3 p-3 bg-emerald-500/5 rounded border border-emerald-500/20">
<span className="text-xs text-emerald-400 font-semibold">Layout Consensus</span>
<p className="text-xs text-emerald-200 mt-1">{result.analysis.layoutComparison.consensus}</p>
</div>
)}
{result.analysis.layoutComparison.divergences && (
<div className="mt-3 p-3 bg-amber-500/5 rounded border border-amber-500/20">
<span className="text-xs text-amber-400 font-semibold">Layout Divergences</span>
<p className="text-xs text-amber-200 mt-1">{result.analysis.layoutComparison.divergences}</p>
</div>
)}
</div>
)}
{/* Enhanced Indicator Analysis */}
{result.analysis.indicatorAnalysis?.crossLayoutConsensus && (
<div className="p-4 bg-gradient-to-br from-violet-500/10 to-purple-500/10 border border-violet-500/30 rounded-lg">
<h4 className="text-sm font-semibold text-violet-400 mb-2">Cross-Layout Consensus</h4>
<p className="text-violet-200 text-sm">{result.analysis.indicatorAnalysis.crossLayoutConsensus}</p>
</div>
)}
</div>
</div>
)}
{result && !result.analysis && result.screenshots && (
<div className="mt-6 p-4 bg-yellow-500/10 border border-yellow-500/30 rounded-lg">
<h3 className="text-lg font-bold text-yellow-400 mb-2">Screenshots Captured</h3>
<p className="text-yellow-300 text-sm mb-2">
Screenshots were captured successfully, but AI analysis failed or was not requested.
</p>
<div className="text-xs text-gray-400">
Screenshots: {result.screenshots.length} captured
</div>
<div className="mt-2">
{result.screenshots.map((screenshot: string, index: number) => (
<div key={index} className="text-xs text-gray-500 font-mono">
{screenshot.split('/').pop()}
</div>
))}
</div>
</div>
)}
</div>
)
}