Fix TradingReports syntax - functions before component
This commit is contained in:
@@ -2,164 +2,7 @@
|
|||||||
|
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
|
||||||
export function TradingReports() {
|
// Generate macro report
|
||||||
const [generatedReport, setGeneratedReport] = useState<string | null>(null)
|
|
||||||
const [loading, setLoading] = useState(false)
|
|
||||||
const [reportType, setReportType] = useState<'macro' | 'weekly' | 'trade'>('macro')
|
|
||||||
|
|
||||||
// Generate report in JavaScript
|
|
||||||
const generateReport = () => {
|
|
||||||
setLoading(true)
|
|
||||||
let report = ''
|
|
||||||
|
|
||||||
if (reportType === 'macro') {
|
|
||||||
report = generateMacroReport()
|
|
||||||
} else if (reportType === 'weekly') {
|
|
||||||
report = generateWeeklyReport()
|
|
||||||
} else {
|
|
||||||
report = generateTradeReport()
|
|
||||||
}
|
|
||||||
|
|
||||||
setGeneratedReport(report)
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
const generateMacroReport = () => `
|
|
||||||
|
|
||||||
const getSampleReport = () => `
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>The Macroverse — Late Business Cycle Analysis</title>
|
|
||||||
<style>
|
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
||||||
body { background: #0f0f12; color: #e0e0e0; font-family: system-ui, -apple-system, sans-serif; line-height: 1.6; }
|
|
||||||
.container { max-width: 900px; margin: 0 auto; padding: 20px; }
|
|
||||||
.hero { text-align: center; padding: 60px 20px; border-bottom: 1px solid #333; }
|
|
||||||
.hero h1 { font-size: 2.5rem; margin-bottom: 10px; background: linear-gradient(90deg, #667eea, #ff69b4); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
|
||||||
.assessment { background: #1a1a20; padding: 20px; border-radius: 10px; margin: 30px 0; border-left: 4px solid #ff6b6b; }
|
|
||||||
.live-data { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; padding: 20px; background: #151518; border-radius: 10px; margin: 20px 0; }
|
|
||||||
.live-data .item { background: #1e1e24; padding: 10px 15px; border-radius: 8px; text-align: center; }
|
|
||||||
.live-data .label { font-size: 0.7rem; color: #666; text-transform: uppercase; }
|
|
||||||
.live-data .value { font-size: 1.2rem; font-weight: bold; }
|
|
||||||
section { padding: 40px 0; border-bottom: 1px solid #222; }
|
|
||||||
h2 { font-size: 1.5rem; margin-bottom: 20px; color: #667eea; }
|
|
||||||
.timeline { display: flex; justify-content: space-between; align-items: center; padding: 20px; background: #151518; border-radius: 10px; overflow-x: auto; }
|
|
||||||
.timeline-step { text-align: center; min-width: 80px; }
|
|
||||||
.timeline-step.active { color: #ff69b4; }
|
|
||||||
.positioning { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px; }
|
|
||||||
.position-item { background: #151518; padding: 20px; border-radius: 10px; }
|
|
||||||
footer { padding: 40px 20px; text-align: center; color: #666; font-size: 0.9rem; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<div class="hero">
|
|
||||||
<h1>THE MACROVERSE</h1>
|
|
||||||
<p class="date">February 25, 2026</p>
|
|
||||||
<div class="assessment"><strong>⚠️ ASSESSMENT:</strong> LATE BUSINESS CYCLE — RECESSION WINDOW: 2026-2028</div>
|
|
||||||
</div>
|
|
||||||
<div class="live-data">
|
|
||||||
<div class="item"><div class="label">S&P 500</div><div class="value">6,909</div></div>
|
|
||||||
<div class="item"><div class="label">Initial Claims</div><div class="value">206K</div></div>
|
|
||||||
<div class="item"><div class="label">Unemployment</div><div class="value">4.1%</div></div>
|
|
||||||
<div class="item"><div class="label">Fed Funds</div><div class="value">4.5%</div></div>
|
|
||||||
<div class="item"><div class="label">Bitcoin</div><div class="value">$64,500</div></div>
|
|
||||||
</div>
|
|
||||||
<section>
|
|
||||||
<h2>01 — Where We Are in the Cycle</h2>
|
|
||||||
<div class="timeline">
|
|
||||||
<div class="timeline-step">Early Expansion</div>
|
|
||||||
<div class="timeline-step">Mid Cycle</div>
|
|
||||||
<div class="timeline-step active">Late Cycle ◀️</div>
|
|
||||||
<div class="timeline-step">Contraction</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>02 — Positioning</h2>
|
|
||||||
<div class="positioning">
|
|
||||||
<div class="position-item"><strong>✅ ENERGY</strong><p>Historically last to fall.</p></div>
|
|
||||||
<div class="position-item"><strong>✅ CASH</strong><p>Dry powder.</p></div>
|
|
||||||
<div class="position-item"><strong>⏳ BITCOIN</strong><p>Pricing weakness.</p></div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<footer><p>Generated by Thoth AI</p></footer>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>`
|
|
||||||
|
|
||||||
const downloadReport = () => {
|
|
||||||
if (!generatedReport) return
|
|
||||||
const blob = new Blob([generatedReport], { type: 'text/html' })
|
|
||||||
const url = URL.createObjectURL(blob)
|
|
||||||
const a = document.createElement('a')
|
|
||||||
a.href = url
|
|
||||||
a.download = `thoth-report-${reportType}-${new Date().toISOString().split('T')[0]}.html`
|
|
||||||
a.click()
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="border border-white/20 rounded-lg p-4 bg-white/5">
|
|
||||||
<h3 className="text-lg font-bold mb-2">📈 Trading Reports</h3>
|
|
||||||
<p className="text-white/60 text-sm mb-4">
|
|
||||||
Generate AI-powered trading and macro reports. Thoth creates them using the LLM.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* Report Type Selection */}
|
|
||||||
<div className="flex gap-2 mb-4">
|
|
||||||
<button
|
|
||||||
onClick={() => setReportType('macro')}
|
|
||||||
className={`px-3 py-1 rounded text-sm ${reportType === 'macro' ? 'bg-brand-pink' : 'bg-white/10'}`}
|
|
||||||
>
|
|
||||||
📊 Macro
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setReportType('weekly')}
|
|
||||||
className={`px-3 py-1 rounded text-sm ${reportType === 'weekly' ? 'bg-brand-pink' : 'bg-white/10'}`}
|
|
||||||
>
|
|
||||||
📅 Weekly
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setReportType('trade')}
|
|
||||||
className={`px-3 py-1 rounded text-sm ${reportType === 'trade' ? 'bg-brand-pink' : 'bg-white/10'}`}
|
|
||||||
>
|
|
||||||
🎯 Trade Setup
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={generateReport}
|
|
||||||
disabled={loading}
|
|
||||||
className="px-4 py-2 bg-brand-pink rounded-lg text-white font-medium hover:bg-brand-pink/80 disabled:opacity-50"
|
|
||||||
>
|
|
||||||
{loading ? '⏳ Thoth is generating...' : '🤖 Generate Report with Thoth'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{generatedReport && (
|
|
||||||
<div className="border border-white/20 rounded-lg p-4 bg-white/5">
|
|
||||||
<div className="flex justify-between items-center mb-4">
|
|
||||||
<h4 className="font-bold">🤖 AI Generated Report</h4>
|
|
||||||
<button
|
|
||||||
onClick={downloadReport}
|
|
||||||
className="px-3 py-1 bg-green-500 rounded text-sm hover:bg-green-600"
|
|
||||||
>
|
|
||||||
⬇️ Download HTML
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="bg-[#0f0f12] rounded-lg p-4 max-h-96 overflow-auto">
|
|
||||||
<div dangerouslySetInnerHTML={{ __html: generatedReport.slice(0, 3000) + '...' }} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateMacroReport() {
|
function generateMacroReport() {
|
||||||
const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
|
const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
|
||||||
return `<!DOCTYPE html>
|
return `<!DOCTYPE html>
|
||||||
@@ -186,10 +29,10 @@ body { background: #0f0f12; color: #e0e0e0; font-family: system-ui, -apple-syste
|
|||||||
.live-data .up { color: #4ade80; }
|
.live-data .up { color: #4ade80; }
|
||||||
.live-data .down { color: #f87171; }
|
.live-data .down { color: #f87171; }
|
||||||
section { padding: 50px 0; border-bottom: 1px solid #222; }
|
section { padding: 50px 0; border-bottom: 1px solid #222; }
|
||||||
section h2 { font-size: 1.6rem; margin-bottom: 25px; color: #667eea; display: flex; align-items: center; gap: 10px; }
|
section h2 { font-size: 1.6rem; margin-bottom: 25px; color: #667eea; }
|
||||||
section h2 .num { background: #667eea; color: #0f0f12; padding: 2px 10px; border-radius: 5px; font-size: 0.9rem; }
|
section h2 .num { background: #667eea; color: #0f0f12; padding: 2px 10px; border-radius: 5px; font-size: 0.9rem; }
|
||||||
.timeline { display: flex; justify-content: space-between; align-items: center; padding: 30px; background: #151518; border-radius: 15px; overflow-x: auto; gap: 20px; }
|
.timeline { display: flex; justify-content: space-between; align-items: center; padding: 30px; background: #151518; border-radius: 15px; overflow-x: auto; gap: 20px; }
|
||||||
.timeline-step { text-align: center; min-width: 90px; position: relative; }
|
.timeline-step { text-align: center; min-width: 90px; }
|
||||||
.timeline-step .dot { width: 16px; height: 16px; background: #333; border-radius: 50%; margin: 0 auto 12px; }
|
.timeline-step .dot { width: 16px; height: 16px; background: #333; border-radius: 50%; margin: 0 auto 12px; }
|
||||||
.timeline-step.active .dot { background: #ff69b4; box-shadow: 0 0 20px #ff69b4; }
|
.timeline-step.active .dot { background: #ff69b4; box-shadow: 0 0 20px #ff69b4; }
|
||||||
.timeline-step.active { color: #ff69b4; }
|
.timeline-step.active { color: #ff69b4; }
|
||||||
@@ -214,8 +57,8 @@ section h2 .num { background: #667eea; color: #0f0f12; padding: 2px 10px; border
|
|||||||
footer { padding: 50px 20px; text-align: center; color: #555; font-size: 0.85rem; }
|
footer { padding: 50px 20px; text-align: center; color: #555; font-size: 0.85rem; }
|
||||||
.sources { margin-top: 20px; padding: 20px; background: #151518; border-radius: 10px; }
|
.sources { margin-top: 20px; padding: 20px; background: #151518; border-radius: 10px; }
|
||||||
.disclaimer { margin-top: 20px; padding: 20px; background: #0a0a0c; border-radius: 10px; font-size: 0.75rem; color: #444; }
|
.disclaimer { margin-top: 20px; padding: 20px; background: #0a0a0c; border-radius: 10px; font-size: 0.75rem; color: #444; }
|
||||||
.progress-bar { position: fixed; top: 0; left: 0; height: 3px; background: linear-gradient(90deg, #667eea, #ff69b4); width: 0%; z-index: 1000; transition: width 0.1s; }
|
.progress-bar { position: fixed; top: 0; left: 0; height: 3px; background: linear-gradient(90deg, #667eea, #ff69b4); width: 0%; z-index: 1000; }
|
||||||
@media (max-width: 600px) { .hero h1 { font-size: 2rem; } .live-data { grid-template-columns: repeat(2, 1fr); } }
|
@media (max-width: 600px) { .hero h1 { font-size: 2rem; } }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -270,15 +113,15 @@ footer { padding: 50px 20px; text-align: center; color: #555; font-size: 0.85rem
|
|||||||
<section>
|
<section>
|
||||||
<h2><span class="num">04</span> Positioning</h2>
|
<h2><span class="num">04</span> Positioning</h2>
|
||||||
<div class="positioning">
|
<div class="positioning">
|
||||||
<div class="position-item positive"><div class="icon">✅</div><strong>ENERGY (XLE)</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Historically last to fall. Defensive late-cycle allocation.</p></div>
|
<div class="position-item positive"><div class="icon">✅</div><strong>ENERGY (XLE)</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Historically last to fall.</p></div>
|
||||||
<div class="position-item positive"><div class="icon">✅</div><strong>CASH</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Dry powder to buy near cycle bottom.</p></div>
|
<div class="position-item positive"><div class="icon">✅</div><strong>CASH</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Dry powder.</p></div>
|
||||||
<div class="position-item negative"><div class="icon">❌</div><strong>ALTCOINS</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Already in bear market since 2021.</p></div>
|
<div class="position-item negative"><div class="icon">❌</div><strong>ALTCOINS</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Already in bear market.</p></div>
|
||||||
<div class="position-item caution"><div class="icon">⏳</div><strong>BITCOIN</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Pricing late-cycle weakness.</p></div>
|
<div class="position-item caution"><div class="icon">⏳</div><strong>BITCOIN</strong><p style="margin-top:10px;color:#888;font-size:0.9rem;">Pricing weakness.</p></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<div class="sources"><strong>Data Sources:</strong> J.P. Morgan, RSM US, Deloitte, Fidelity, Bloomberg, Advisor Perspectives</div>
|
<div class="sources"><strong>Data Sources:</strong> J.P. Morgan, RSM US, Deloitte, Fidelity</div>
|
||||||
<div class="disclaimer"><strong>Disclaimer:</strong> This report is derived from macroeconomic analysis and does not constitute investment advice. Past cycle behavior is instructive but not deterministic. All views are the author's own. Do your own research.</div>
|
<div class="disclaimer"><strong>Disclaimer:</strong> Educational purposes only. Not investment advice.</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -293,29 +136,38 @@ window.addEventListener('scroll', () => {
|
|||||||
</html>`
|
</html>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate weekly report
|
||||||
function generateWeeklyReport() {
|
function generateWeeklyReport() {
|
||||||
const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
|
const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
|
||||||
return `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Weekly Report - ${date}</title><style>
|
return `<!DOCTYPE html>
|
||||||
|
<html><head><meta charset="UTF-8"><title>Weekly Report</title><style>
|
||||||
body{background:#0f0f12;color:#e0e0e0;font-family:system-ui;padding:40px;margin:0}
|
body{background:#0f0f12;color:#e0e0e0;font-family:system-ui;padding:40px;margin:0}
|
||||||
.container{max-width:800px;margin:0 auto}
|
.container{max-width:800px;margin:0 auto}
|
||||||
h1{background:linear-gradient(90deg,#667eea,#ff69b4);-webkit-background-clip:text;-webkit-text-fill-color:transparent;font-size:2.5rem}
|
h1{background:linear-gradient(90deg,#667eea,#ff69b4);-webkit-background-clip:text;-webkit-text-fill-color:transparent;font-size:2.5rem}
|
||||||
.card{background:#151518;padding:25px;border-radius:15px;margin:20px 0}
|
.card{background:#151518;padding:25px;border-radius:15px;margin:20px 0}
|
||||||
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:15px;margin:20px 0}
|
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:15px}
|
||||||
.stat{background:#1e1e24;padding:20px;border-radius:10px;text-align:center}
|
.stat{background:#1e1e24;padding:20px;border-radius:10px;text-align:center}
|
||||||
.stat .val{font-size:2rem;font-weight:700}
|
.stat .val{font-size:2rem;font-weight:700}
|
||||||
.stat .lbl{font-size:0.8rem;color:#666;text-transform:uppercase}
|
.stat .lbl{font-size:0.8rem;color:#666;text-transform:uppercase}
|
||||||
.positive{color:#4ade80}.negative{color:#f87171}
|
.positive{color:#4ade80}
|
||||||
</style></head><body><div class="container"><h1>📅 Weekly Trading Report</h1><p>${date}</p>
|
</style></head><body><div class="container">
|
||||||
|
<h1>📅 Weekly Trading Report</h1><p>${date}</p>
|
||||||
<div class="card"><h2>Performance Summary</h2><div class="grid">
|
<div class="card"><h2>Performance Summary</h2><div class="grid">
|
||||||
<div class="stat"><div class="val positive">+3.2%</div><div class="lbl">This Week</div></div>
|
<div class="stat"><div class="val positive">+3.2%</div><div class="lbl">This Week</div></div>
|
||||||
<div class="stat"><div class="val positive">+12.4%</div><div class="lbl">This Month</div></div>
|
<div class="stat"><div class="val positive">+12.4%</div><div class="lbl">This Month</div></div>
|
||||||
<div class="stat"><div class="val">8/12</div><div class="lbl">Win Rate</div></div>
|
<div class="stat"><div class="val">8/12</div><div class="lbl">Win Rate</div></div>
|
||||||
</div></div>
|
</div></div>
|
||||||
<div class="card"><h2>Trade Highlights</h2><p>✓ BTC Long — +5.2% — Hit TP2</p><p>✓ ETH Long — +2.1% — Closed</p><p>✗ SOL Short — -1.2% — Stop hit</p></div>
|
<div class="card"><h2>Trade Highlights</h2>
|
||||||
<div class="card"><h2>Next Week Watchlist</h2><p>• Fed Meeting — Watch for volatility</p><p>• BTC — $65K resistance</p><p>• EUR/USD — Key support at 1.08</p></div>
|
<p>✓ BTC Long — +5.2% — Hit TP2</p>
|
||||||
|
<p>✓ ETH Long — +2.1% — Closed</p>
|
||||||
|
<p>✗ SOL Short — -1.2% — Stop hit</p></div>
|
||||||
|
<div class="card"><h2>Next Week Watchlist</h2>
|
||||||
|
<p>• Fed Meeting — Watch volatility</p>
|
||||||
|
<p>• BTC — $65K resistance</p></div>
|
||||||
</div></body></html>`
|
</div></body></html>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate trade setup report
|
||||||
function generateTradeReport() {
|
function generateTradeReport() {
|
||||||
return `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Trade Setup</title><style>
|
return `<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Trade Setup</title><style>
|
||||||
body{background:#0f0f12;color:#e0e0e0;font-family:system-ui;padding:40px;margin:0}
|
body{background:#0f0f12;color:#e0e0e0;font-family:system-ui;padding:40px;margin:0}
|
||||||
@@ -325,7 +177,8 @@ h1{background:linear-gradient(90deg,#667eea,#ff69b4);-webkit-background-clip:tex
|
|||||||
.row{display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid #222}
|
.row{display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid #222}
|
||||||
.lbl{color:#888}.val{font-weight:700}
|
.lbl{color:#888}.val{font-weight:700}
|
||||||
.long{color:#4ade80}.short{color:#f87171}
|
.long{color:#4ade80}.short{color:#f87171}
|
||||||
</style></head><body><div class="container"><h1>🎯 Trade Setup</h1>
|
</style></head><body><div class="container">
|
||||||
|
<h1>🎯 Trade Setup</h1>
|
||||||
<div class="box"><h3>BTC/USD — LONG</h3>
|
<div class="box"><h3>BTC/USD — LONG</h3>
|
||||||
<div class="row"><span class="lbl">Entry</span><span class="val">$63,500</span></div>
|
<div class="row"><span class="lbl">Entry</span><span class="val">$63,500</span></div>
|
||||||
<div class="row"><span class="lbl">Stop Loss</span><span class="val short">$62,000</span></div>
|
<div class="row"><span class="lbl">Stop Loss</span><span class="val short">$62,000</span></div>
|
||||||
@@ -336,3 +189,93 @@ h1{background:linear-gradient(90deg,#667eea,#ff69b4);-webkit-background-clip:tex
|
|||||||
<div class="box"><h4>Rationale</h4><p>• Weekly structure breakout<br>• RSI oversold on 4H<br>• Volume increasing on up days</p></div>
|
<div class="box"><h4>Rationale</h4><p>• Weekly structure breakout<br>• RSI oversold on 4H<br>• Volume increasing on up days</p></div>
|
||||||
</div></body></html>`
|
</div></body></html>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function TradingReports() {
|
||||||
|
const [generatedReport, setGeneratedReport] = useState<string | null>(null)
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [reportType, setReportType] = useState<'macro' | 'weekly' | 'trade'>('macro')
|
||||||
|
|
||||||
|
const generateReport = () => {
|
||||||
|
setLoading(true)
|
||||||
|
let report = ''
|
||||||
|
|
||||||
|
if (reportType === 'macro') {
|
||||||
|
report = generateMacroReport()
|
||||||
|
} else if (reportType === 'weekly') {
|
||||||
|
report = generateWeeklyReport()
|
||||||
|
} else {
|
||||||
|
report = generateTradeReport()
|
||||||
|
}
|
||||||
|
|
||||||
|
setGeneratedReport(report)
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadReport = () => {
|
||||||
|
if (!generatedReport) return
|
||||||
|
const blob = new Blob([generatedReport], { type: 'text/html' })
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
a.download = `thoth-${reportType}-report-${new Date().toISOString().split('T')[0]}.html`
|
||||||
|
a.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="border border-white/20 rounded-lg p-4 bg-white/5">
|
||||||
|
<h3 className="text-lg font-bold mb-2">📈 Trading Reports</h3>
|
||||||
|
<p className="text-white/60 text-sm mb-4">
|
||||||
|
Generate AI-powered trading and macro reports.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex gap-2 mb-4">
|
||||||
|
<button
|
||||||
|
onClick={() => setReportType('macro')}
|
||||||
|
className={`px-3 py-1 rounded text-sm ${reportType === 'macro' ? 'bg-brand-pink' : 'bg-white/10'}`}
|
||||||
|
>
|
||||||
|
📊 Macro
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setReportType('weekly')}
|
||||||
|
className={`px-3 py-1 rounded text-sm ${reportType === 'weekly' ? 'bg-brand-pink' : 'bg-white/10'}`}
|
||||||
|
>
|
||||||
|
📅 Weekly
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setReportType('trade')}
|
||||||
|
className={`px-3 py-1 rounded text-sm ${reportType === 'trade' ? 'bg-brand-pink' : 'bg-white/10'}`}
|
||||||
|
>
|
||||||
|
🎯 Trade
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={generateReport}
|
||||||
|
disabled={loading}
|
||||||
|
className="px-4 py-2 bg-brand-pink rounded-lg text-white font-medium hover:bg-brand-pink/80 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{loading ? '⏳ Generating...' : '🤖 Generate Report'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{generatedReport && (
|
||||||
|
<div className="border border-white/20 rounded-lg p-4 bg-white/5">
|
||||||
|
<div className="flex justify-between items-center mb-4">
|
||||||
|
<h4 className="font-bold">Generated Report</h4>
|
||||||
|
<button
|
||||||
|
onClick={downloadReport}
|
||||||
|
className="px-3 py-1 bg-green-500 rounded text-sm hover:bg-green-600"
|
||||||
|
>
|
||||||
|
⬇️ Download
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-[#0f0f12] rounded-lg p-4 max-h-96 overflow-auto text-sm">
|
||||||
|
<pre className="whitespace-pre-wrap">{generatedReport.slice(0, 1500)}...</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user