3 pages (market, PRINZIP drilldown, developers leaderboard) on top of existing v_developer_full_metrics + domrf_realization views. ECharts on the frontend, FastAPI router /api/v1/analytics on the backend.
65 lines
1.4 KiB
TypeScript
65 lines
1.4 KiB
TypeScript
interface Props {
|
|
label: string;
|
|
value: string;
|
|
unit?: string;
|
|
delta?: { value: string; positive?: boolean | null };
|
|
hint?: string;
|
|
}
|
|
|
|
export function KpiCard({ label, value, unit, delta, hint }: Props) {
|
|
const deltaColor =
|
|
delta?.positive === true
|
|
? "#0a7a3a"
|
|
: delta?.positive === false
|
|
? "#b3261e"
|
|
: "#5b6066";
|
|
|
|
return (
|
|
<div
|
|
style={{
|
|
background: "#fff",
|
|
border: "1px solid #e6e8ec",
|
|
borderRadius: 12,
|
|
padding: "16px 18px",
|
|
minWidth: 180,
|
|
flex: 1,
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
fontSize: 12,
|
|
textTransform: "uppercase",
|
|
color: "#5b6066",
|
|
letterSpacing: 0.4,
|
|
}}
|
|
>
|
|
{label}
|
|
</div>
|
|
<div
|
|
style={{
|
|
marginTop: 6,
|
|
display: "flex",
|
|
alignItems: "baseline",
|
|
gap: 6,
|
|
}}
|
|
>
|
|
<span style={{ fontSize: 28, fontWeight: 600, color: "#111" }}>
|
|
{value}
|
|
</span>
|
|
{unit ? (
|
|
<span style={{ color: "#5b6066", fontSize: 14 }}>{unit}</span>
|
|
) : null}
|
|
</div>
|
|
{delta ? (
|
|
<div style={{ marginTop: 4, fontSize: 13, color: deltaColor }}>
|
|
{delta.value}
|
|
</div>
|
|
) : null}
|
|
{hint ? (
|
|
<div style={{ marginTop: 6, fontSize: 12, color: "#73767e" }}>
|
|
{hint}
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|