import { For, Show, type JSX } from "solid-js";
// Shared building blocks: StatCard, EmptyState, Badge, SignalBar, Skeleton.
export function StatCard(props: { title: string; value: string; sub?: string; children?: JSX.Element }) {
return (
{props.title}
{props.value}
{props.sub}
{props.children}
);
}
export function EmptyState(props: { icon: string; title: string; hint?: string; action?: JSX.Element }) {
return (
{props.icon}
{props.title}
{props.hint}
{props.action}
);
}
export function Skeleton(props: { rows?: number }) {
const n = props.rows ?? 3;
return (
);
}
export function RecBadge(props: { rec: string }) {
const cls = props.rec === "BUY" ? "buy" : props.rec === "HOLD" ? "hold" : "avoid";
return {props.rec};
}
// SignalBar renders one -100..+100 signal as a labeled bar.
export function SignalBar(props: { label: string; value: number }) {
const v = Math.max(-100, Math.min(100, props.value));
const left = v < 0 ? `${50 + v / 2}%` : "50%";
const width = `${Math.abs(v) / 2}%`;
const cls = v < 0 ? "neg" : v > 0 ? "pos" : "";
return (
{props.label}
{v}
);
}
// BreakdownBars renders a screen/report signal breakdown map as bars.
// Unknown numeric fields are shown; booleans/strings are skipped except flags.
export function BreakdownBars(props: { breakdown: Record }) {
const entries = () =>
Object.entries(props.breakdown || {}).filter(([, v]) => typeof v === "number") as [string, number][];
return (
no signals}>
{([k, v]) => }
);
}