Blum / frontend /components /SignalTable.tsx
Italianhype's picture
Upload folder using huggingface_hub
2deb2c5 verified
import Link from "next/link";
import { Signal } from "@/lib/types";
import { formatPercent, formatPrice, formatVolume } from "./MarketSnapshotStrip";
import { StatusBadge } from "./StatusBadge";
export function SignalTable({ signals }: { signals: Signal[] }) {
if (!signals.length) return <div className="empty-state">No signal snapshots are available yet. Run the full intelligence pipeline and review pipeline readiness for price, news and provider diagnostics.</div>;
return (
<div className="table-shell">
<table className="intel-table">
<thead>
<tr>
<th>Asset</th>
<th>Market</th>
<th>Score</th>
<th>Classification</th>
<th>Risk</th>
<th>Momentum</th>
<th>Trend</th>
<th>Sentiment</th>
<th>Why it surfaced</th>
</tr>
</thead>
<tbody>
{signals.map((signal) => (
<tr key={`${signal.ticker}-${signal.created_at}`}>
<td>
<Link href={`/assets/${signal.ticker}`} className="asset-link">{signal.ticker}</Link>
<span>{signal.asset?.name ?? "Name pending"}</span>
<span>{signal.asset?.asset_type ?? "Asset"} | {signal.asset?.sector ?? "Sector pending"} | {signal.asset?.exchange ?? "Exchange n/a"}</span>
</td>
<td>
<strong>{formatPrice(signal.market_snapshot?.price, signal.market_snapshot?.currency)}</strong>
<span>{formatPercent(signal.market_snapshot?.perf_1d)} 1D | {formatPercent(signal.market_snapshot?.perf_5d)} 5D</span>
<span>{signal.market_snapshot?.provider ?? "provider n/a"} | vol {formatVolume(signal.market_snapshot?.volume)}</span>
</td>
<td><strong className="score-number">{signal.blum_score.toFixed(1)}</strong></td>
<td><StatusBadge label={signal.classification} /></td>
<td>{signal.risk_level}</td>
<td>{metric(signal, "momentum_score")}</td>
<td>{metric(signal, "trend_score")}</td>
<td>{metric(signal, "sentiment_score")}</td>
<td className="why">{signal.explanation}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
function metric(signal: Signal, key: string) {
const value = signal.score_breakdown?.[key] ?? 0;
return <span className="metric-pill">{Number(value).toFixed(0)}</span>;
}