2026-06-12 12:07:15 +08:00

33 lines
1.4 KiB
JavaScript

import { formatNumber, formatPercent } from "../utils/format.js";
import { MiniStat } from "./MiniStat.jsx";
import { Panel } from "./Panel.jsx";
export function FunnelPanel({ funnel, loading = false, sideMetrics }) {
return (
<Panel title="付费转化漏斗">
<div className={["funnel-layout", loading ? "skeleton-panel" : ""].filter(Boolean).join(" ")} aria-busy={loading || undefined}>
<div className="funnel-stack">
{loading
? Array.from({ length: 3 }).map((_, index) => <span className={`skeleton-block skeleton-funnel-stage skeleton-funnel-stage--${index + 1}`} key={index} />)
: funnel.map((item, index) => (
<div className="funnel-stage-row" key={item.name}>
<div className={`funnel-stage funnel-stage--${index + 1}`}>
<span>{item.name}</span>
<strong>{formatNumber(item.value)}</strong>
</div>
<b>{formatPercent(item.rate)}</b>
</div>
))}
</div>
<div className="side-metrics">
{loading
? Array.from({ length: 3 }).map((_, index) => <span className="skeleton-block skeleton-mini-stat" key={index} />)
: sideMetrics.map((item) => (
<MiniStat key={item.label} item={item} />
))}
</div>
</div>
</Panel>
);
}