Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>CryptoSentinel AI</title> | |
<script src="/static/htmx.min.js"></script> | |
<style> | |
body { font-family: system-ui, sans-serif; margin: 2rem; } | |
.price { font-size: 2rem; margin: .5rem 0; } | |
</style> | |
</head> | |
<body> | |
<h1>🛡️ CryptoSentinel AI</h1> | |
<section id="prices" hx-get="/prices" hx-trigger="load, every 10s" hx-swap="innerHTML"> | |
<!-- Populated by HTMX --> | |
</section> | |
<hr> | |
<h2>Sentiment Lab</h2> | |
<input id="text" placeholder="Type something…" style="width:60%"> | |
<button hx-post="/sentiment" hx-vals='js:{"text": document.getElementById("text").value}' | |
hx-swap="none">Analyze</button> | |
<pre id="sentiment-output">Waiting…</pre> | |
<script> | |
// EventSource for live sentiment push | |
const es = new EventSource("/sentiment/stream"); | |
es.onmessage = e => { | |
const data = JSON.parse(e.data); | |
document.getElementById("sentiment-output").textContent = | |
JSON.stringify(data, null, 2); | |
}; | |
</script> | |
<script> | |
// Template for price section (client-side rendering) | |
document.addEventListener("htmx:afterOnLoad", function(evt){ | |
if (evt.detail.path === "/prices"){ | |
const p = evt.detail.xhr.response; | |
const json = JSON.parse(p); | |
let html = ''; | |
for (const [k,v] of Object.entries(json)){ | |
html += `<div class="price">${k.toUpperCase()}: $${v}</div>`; | |
} | |
evt.detail.elt.innerHTML = html; | |
} | |
}); | |
</script> | |
</body> | |
</html> | |