{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "metrics-grid",
  "title": "Metrics Grid",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/metrics-grid/MetricsGrid.tsx",
      "content": "'use client'\n\n// Six-tile KPI grid. Each tile renders a labeled KPI header (title +\n// big number / percentage / count) above a small chart -- pie or\n// horizontal bar -- that gives the breakdown.\n//\n// Per the registry's primitive-vs-block rule: tile shapes are spelled\n// out inline as siblings. Different tiles use different chart types\n// (donut, full pie, horizontal bar) -- those differences are the whole\n// point of the layout, so they don't hide behind a wrapper.\nimport { PieChart, BarChart } from '@/components/ui/charts'\n\n// --- KPI 1: status pie (e.g. successful / partially / error) ---\nconst totalRuns = 770\nconst runsByStatus = [\n  { name: 'Successful', value: 638 },\n  { name: 'Partial', value: 0 },\n  { name: 'Error / Skipped', value: 132 },\n]\n\n// --- KPI 2: disposition split ---\nconst totalProcessed = 638\nconst dispositionSplit = [\n  { name: 'Non-disputable', value: 168 },\n  { name: 'Disputable', value: 470 },\n]\n\n// --- KPI 3: classification breakdown ---\nconst totalClassified = 638\nconst classification = [\n  { name: 'Type A', value: 525 },\n  { name: 'Type B', value: 113 },\n]\n\n// --- KPI 4: top reasons (horizontal bar) ---\nconst skipReasons = [\n  { reason: 'CREDIT_NOTE', count: 11 },\n  { reason: 'CUSTOMS_INSPECT', count: 5 },\n  { reason: 'NEGATIVE_COST', count: 8 },\n]\nconst totalSkipped = skipReasons.reduce((a, r) => a + r.count, 0)\n\n// --- KPI 5: error reasons (horizontal bar) ---\nconst errorReasons = [\n  { reason: 'INVALID_CUTOFF', count: 3 },\n  { reason: 'NO_SHIPMENT_DATA', count: 20 },\n  { reason: 'SELF_BILLING', count: 42 },\n  { reason: 'MISSING_OBLIGATORY_FIELD', count: 2 },\n  { reason: 'MISSING_OBLIGATORY_TIME', count: 4 },\n  { reason: 'UNABLE_TO_CLASSIFY', count: 40 },\n]\nconst totalErrors = errorReasons.reduce((a, r) => a + r.count, 0)\n\n// --- KPI 6: workflow status ---\nconst openShare = 0.7602\nconst workflowStatus = [\n  { name: 'Open', value: 485 },\n  { name: 'Pending', value: 151 },\n  { name: 'Closed', value: 2 },\n]\n\nconst pieOption = {\n  legend: { show: false },\n  series: [\n    {\n      radius: ['0%', '70%'],\n      label: {\n        show: true,\n        formatter: (p: any) => `${p.value}\\n(${p.percent}%)`,\n        fontSize: 11,\n        color: '#fff',\n        fontWeight: 600,\n      },\n      labelLine: { show: false },\n    },\n  ],\n}\n\nconst donutOption = {\n  legend: { show: false },\n  series: [\n    {\n      radius: ['40%', '70%'],\n      label: {\n        show: true,\n        formatter: (p: any) => `${p.value}\\n(${p.percent}%)`,\n        fontSize: 11,\n        color: '#fff',\n        fontWeight: 600,\n      },\n      labelLine: { show: false },\n    },\n  ],\n}\n\nconst horizontalBarOption = {\n  legend: { show: false },\n  xAxis: { type: 'value' as const, axisLabel: { fontSize: 10 } },\n  yAxis: { type: 'category' as const, axisLabel: { fontSize: 10 } },\n  grid: { left: 16, right: 16, top: 8, bottom: 24, containLabel: true },\n  series: [\n    {\n      type: 'bar' as const,\n      barMaxWidth: 18,\n      itemStyle: { borderRadius: [0, 3, 3, 0] },\n    },\n  ],\n}\n\nexport function MetricsGrid() {\n  return (\n    <div className=\"space-y-4\">\n      <h2 className=\"text-primary text-[15px] font-semibold tracking-tight\">Results Overview</h2>\n\n      <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n        {/* Tile 1: Runs by status (pie) */}\n        <article className=\"bg-card border-border rounded-lg border p-4\">\n          <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Runs by status</h3>\n          <div className=\"text-primary mt-1 mb-2 text-2xl font-semibold\">{totalRuns} runs</div>\n          <div className=\"text-muted-foreground mb-3 flex items-center gap-3 text-[11px]\">\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-1)' }} />\n              Successful\n            </span>\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-4)' }} />\n              Error / Skipped\n            </span>\n          </div>\n          <PieChart data={runsByStatus} option={pieOption} height=\"220\" />\n        </article>\n\n        {/* Tile 2: Disposition split (pie) */}\n        <article className=\"bg-card border-border rounded-lg border p-4\">\n          <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Disposition split</h3>\n          <div className=\"text-primary mt-1 mb-2 text-2xl font-semibold\">{totalProcessed} processed</div>\n          <div className=\"text-muted-foreground mb-3 flex items-center gap-3 text-[11px]\">\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-1)' }} />\n              Non-disputable\n            </span>\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-3)' }} />\n              Disputable\n            </span>\n          </div>\n          <PieChart data={dispositionSplit} option={pieOption} height=\"220\" />\n        </article>\n\n        {/* Tile 3: Classification (pie) */}\n        <article className=\"bg-card border-border rounded-lg border p-4\">\n          <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Classification</h3>\n          <div className=\"text-primary mt-1 mb-2 text-2xl font-semibold\">{totalClassified} classified</div>\n          <div className=\"text-muted-foreground mb-3 flex items-center gap-3 text-[11px]\">\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-1)' }} />\n              Type A\n            </span>\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-3)' }} />\n              Type B\n            </span>\n          </div>\n          <PieChart data={classification} option={pieOption} height=\"220\" />\n        </article>\n\n        {/* Tile 4: Skip reasons (horizontal bar) */}\n        <article className=\"bg-card border-border rounded-lg border p-4\">\n          <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Top skip reasons</h3>\n          <div className=\"text-primary mt-1 mb-2 text-2xl font-semibold\">{totalSkipped} skipped</div>\n          <div className=\"text-muted-foreground mb-3 text-[11px]\">By trigger</div>\n          <BarChart data={skipReasons} xField=\"reason\" yField=\"count\" option={horizontalBarOption} height=\"220\" />\n        </article>\n\n        {/* Tile 5: Error reasons (horizontal bar) */}\n        <article className=\"bg-card border-border rounded-lg border p-4\">\n          <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Top error reasons</h3>\n          <div className=\"text-primary mt-1 mb-2 text-2xl font-semibold\">{totalErrors} errors</div>\n          <div className=\"text-muted-foreground mb-3 text-[11px]\">By failure mode</div>\n          <BarChart data={errorReasons} xField=\"reason\" yField=\"count\" option={horizontalBarOption} height=\"220\" />\n        </article>\n\n        {/* Tile 6: Workflow status (donut + highlight) */}\n        <article className=\"bg-card border-border rounded-lg border p-4\">\n          <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">Workflow status</h3>\n          <div className=\"text-primary mt-1 mb-2 text-2xl font-semibold\">{(openShare * 100).toFixed(2)}% open</div>\n          <div className=\"text-muted-foreground mb-3 flex items-center gap-3 text-[11px]\">\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-1)' }} />\n              Open\n            </span>\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-5)' }} />\n              Pending\n            </span>\n            <span className=\"inline-flex items-center gap-1.5\">\n              <span className=\"size-2 rounded-full\" style={{ background: 'var(--chart-3)' }} />\n              Closed\n            </span>\n          </div>\n          <PieChart data={workflowStatus} option={donutOption} donut height=\"220\" />\n        </article>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/MetricsGrid.tsx"
    }
  ],
  "dependencies": [
    "echarts",
    "echarts-for-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/pie-chart.json",
    "https://uipkge.dev/r/react/bar-chart.json"
  ],
  "description": "Six-tile KPI status grid. Each tile pairs a stat header (count / percentage) with a small pie or horizontal bar chart that breaks the metric down. Different tiles use different chart types so each KPI reads at a glance.",
  "categories": [
    "dashboard",
    "analytics"
  ]
}