Fix reports - generate real HTML in JavaScript
This commit is contained in:
@@ -7,36 +7,25 @@ export function TradingReports() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [reportType, setReportType] = useState<'macro' | 'weekly' | 'trade'>('macro')
|
||||
|
||||
const generateReport = async () => {
|
||||
// Generate report in JavaScript
|
||||
const generateReport = () => {
|
||||
setLoading(true)
|
||||
let report = ''
|
||||
|
||||
try {
|
||||
// Call our API to generate the report using MiniMax
|
||||
const response = await fetch('/api/ai/generate-report', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
type: reportType,
|
||||
date: new Date().toISOString().split('T')[0]
|
||||
})
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (data.report) {
|
||||
setGeneratedReport(data.report)
|
||||
} else {
|
||||
// Fallback sample if API not ready
|
||||
setGeneratedReport(getSampleReport())
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Generation failed:', error)
|
||||
setGeneratedReport(getSampleReport())
|
||||
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">
|
||||
@@ -170,3 +159,180 @@ footer { padding: 40px 20px; text-align: center; color: #666; font-size: 0.9rem;
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function generateMacroReport() {
|
||||
const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })
|
||||
return `<!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: 3rem; margin-bottom: 10px; background: linear-gradient(90deg, #667eea, #ff69b4); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
|
||||
.hero .subtitle { color: #888; font-size: 1.2rem; }
|
||||
.assessment { background: linear-gradient(135deg, #1a1520, #1a1525); padding: 25px; border-radius: 15px; margin: 30px 0; border-left: 4px solid #ff6b6b; }
|
||||
.assessment-title { color: #ff6b6b; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 10px; }
|
||||
.assessment strong { font-size: 1.3rem; }
|
||||
.live-data { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; padding: 25px; background: #151518; border-radius: 15px; margin: 20px 0; }
|
||||
.live-data .item { background: #1e1e24; padding: 15px; border-radius: 12px; text-align: center; }
|
||||
.live-data .label { font-size: 0.65rem; color: #666; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
|
||||
.live-data .value { font-size: 1.4rem; font-weight: 700; }
|
||||
.live-data .change { font-size: 0.75rem; margin-top: 5px; }
|
||||
.live-data .up { color: #4ade80; }
|
||||
.live-data .down { color: #f87171; }
|
||||
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 .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-step { text-align: center; min-width: 90px; position: relative; }
|
||||
.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 { color: #ff69b4; }
|
||||
.loop-container { background: #151518; padding: 30px; border-radius: 15px; }
|
||||
.loop-step { display: flex; align-items: center; gap: 15px; padding: 12px 0; font-size: 1.1rem; }
|
||||
.loop-step .arrow { color: #667eea; font-size: 1.3rem; }
|
||||
.loop-status { margin-top: 20px; padding: 15px; background: #1e1e24; border-radius: 10px; text-align: center; color: #fbbf24; font-weight: 600; }
|
||||
.risk-tiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 15px; }
|
||||
.tier { background: #151518; padding: 25px; border-radius: 15px; text-align: center; }
|
||||
.tier .icon { font-size: 2rem; margin-bottom: 10px; }
|
||||
.tier .status { font-size: 0.8rem; text-transform: uppercase; margin-top: 8px; }
|
||||
.tier.completed { border: 2px solid #4ade80; }
|
||||
.tier.in-progress { border: 2px solid #fbbf24; }
|
||||
.tier.approaching { border: 2px solid #667eea; }
|
||||
.tier.pending { border: 2px solid #555; }
|
||||
.positioning { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; }
|
||||
.position-item { background: #151518; padding: 25px; border-radius: 15px; }
|
||||
.position-item .icon { font-size: 1.8rem; margin-bottom: 10px; }
|
||||
.position-item.positive { border-left: 4px solid #4ade80; }
|
||||
.position-item.negative { border-left: 4px solid #f87171; }
|
||||
.position-item.caution { border-left: 4px solid #fbbf24; }
|
||||
footer { padding: 50px 20px; text-align: center; color: #555; font-size: 0.85rem; }
|
||||
.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; }
|
||||
.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; }
|
||||
@media (max-width: 600px) { .hero h1 { font-size: 2rem; } .live-data { grid-template-columns: repeat(2, 1fr); } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="progress-bar" id="progress"></div>
|
||||
<div class="container">
|
||||
<div class="hero">
|
||||
<h1>THE MACROVERSE</h1>
|
||||
<p class="subtitle">${date}</p>
|
||||
<div class="assessment">
|
||||
<div class="assessment-title">⚠️ Assessment Alert</div>
|
||||
<strong>LATE BUSINESS CYCLE ENVIRONMENT CONFIRMED</strong><br>
|
||||
<span style="color: #888;">Recession Window: 2026-2028 | Initial Claims: 206K (Watch: 300K)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="live-data">
|
||||
<div class="item"><div class="label">S&P 500</div><div class="value">6,909</div><div class="change up">▲ 0.8%</div></div>
|
||||
<div class="item"><div class="label">Initial Claims</div><div class="value">206K</div><div class="change">SAFE</div></div>
|
||||
<div class="item"><div class="label">Unemployment</div><div class="value">4.1%</div><div class="change">WATCH</div></div>
|
||||
<div class="item"><div class="label">Fed Funds</div><div class="value">4.5%</div><div class="change down">▼</div></div>
|
||||
<div class="item"><div class="label">Bitcoin</div><div class="value">$64,500</div><div class="change down">▼ 49% ATH</div></div>
|
||||
<div class="item"><div class="label">Gold</div><div class="value">$2,940</div><div class="change up">▲</div></div>
|
||||
</div>
|
||||
<section>
|
||||
<h2><span class="num">01</span> Where We Are in the Cycle</h2>
|
||||
<div class="timeline">
|
||||
<div class="timeline-step"><div class="dot"></div>Early<br>Expansion</div>
|
||||
<div class="timeline-step"><div class="dot"></div>Mid<br>Cycle</div>
|
||||
<div class="timeline-step active"><div class="dot"></div>Late<br>Cycle ◀️</div>
|
||||
<div class="timeline-step"><div class="dot"></div>Con<br>traction</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2><span class="num">02</span> The Negative Feedback Loop</h2>
|
||||
<div class="loop-container">
|
||||
<div class="loop-step">1. Stock Market Drops <span class="arrow">→</span></div>
|
||||
<div class="loop-step">2. Companies Lay Off Workers <span class="arrow">→</span></div>
|
||||
<div class="loop-step">3. Job Openings Low <span class="arrow">→</span></div>
|
||||
<div class="loop-step">4. Consumer Spending Drops <span class="arrow">→</span></div>
|
||||
<div class="loop-step">5. Non-Linear Unemployment Rise <span class="arrow">→</span></div>
|
||||
<div class="loop-status">⚠️ STATUS: NOT YET TRIGGERED</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2><span class="num">03</span> The Risk Cascade</h2>
|
||||
<div class="risk-tiers">
|
||||
<div class="tier completed"><div class="icon">●</div><div>COMPLETED</div><div class="status">Altcoins</div></div>
|
||||
<div class="tier in-progress"><div class="icon">●</div><div>IN PROGRESS</div><div class="status">Bitcoin</div></div>
|
||||
<div class="tier approaching"><div class="icon">◉</div><div>APPROACHING</div><div class="status">Equities</div></div>
|
||||
<div class="tier pending"><div class="icon">○</div><div>PENDING</div><div class="status">Energy/Metals</div></div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h2><span class="num">04</span> Positioning</h2>
|
||||
<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>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 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 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>
|
||||
</section>
|
||||
<footer>
|
||||
<div class="sources"><strong>Data Sources:</strong> J.P. Morgan, RSM US, Deloitte, Fidelity, Bloomberg, Advisor Perspectives</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>
|
||||
</footer>
|
||||
</div>
|
||||
<script>
|
||||
window.addEventListener('scroll', () => {
|
||||
const winScroll = document.body.scrollTop || document.documentElement.scrollTop;
|
||||
const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
|
||||
const scrolled = (winScroll / height) * 100;
|
||||
document.getElementById('progress').style.width = scrolled + '%';
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>`
|
||||
}
|
||||
|
||||
function generateWeeklyReport() {
|
||||
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>
|
||||
body{background:#0f0f12;color:#e0e0e0;font-family:system-ui;padding:40px;margin:0}
|
||||
.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}
|
||||
.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}
|
||||
.stat{background:#1e1e24;padding:20px;border-radius:10px;text-align:center}
|
||||
.stat .val{font-size:2rem;font-weight:700}
|
||||
.stat .lbl{font-size:0.8rem;color:#666;text-transform:uppercase}
|
||||
.positive{color:#4ade80}.negative{color:#f87171}
|
||||
</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="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">8/12</div><div class="lbl">Win Rate</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>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>
|
||||
</div></body></html>`
|
||||
}
|
||||
|
||||
function generateTradeReport() {
|
||||
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}
|
||||
.container{max-width:700px;margin:0 auto}
|
||||
h1{background:linear-gradient(90deg,#667eea,#ff69b4);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
||||
.box{background:#151518;padding:25px;border-radius:15px;margin:20px 0}
|
||||
.row{display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid #222}
|
||||
.lbl{color:#888}.val{font-weight:700}
|
||||
.long{color:#4ade80}.short{color:#f87171}
|
||||
</style></head><body><div class="container"><h1>🎯 Trade Setup</h1>
|
||||
<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">Stop Loss</span><span class="val short">$62,000</span></div>
|
||||
<div class="row"><span class="lbl">Take Profit 1</span><span class="val long">$65,000</span></div>
|
||||
<div class="row"><span class="lbl">Take Profit 2</span><span class="val long">$67,000</span></div>
|
||||
<div class="row"><span class="lbl">Risk:Reward</span><span class="val">1:3</span></div>
|
||||
</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>`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user