{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "live-status-table",
  "title": "Live Status Indicators",
  "description": "A service-health table whose status and latency columns update on their own on a timer, with a pulsing indicator for actively-monitored states and a Live/Paused toggle.",
  "dependencies": [
    "@tanstack/react-table"
  ],
  "registryDependencies": [
    "table"
  ],
  "files": [
    {
      "path": "src/components/live-status/status-indicator.tsx",
      "content": "'use client'\n\nimport { cn } from '#/lib/utils.ts'\nimport type { ServiceStatus } from './columns'\n\nconst STATUS_CONFIG: Record<\n  ServiceStatus,\n  { label: string; dot: string; pulse: boolean }\n> = {\n  operational: { label: 'Operational', dot: 'bg-emerald-500', pulse: true },\n  degraded: { label: 'Degraded', dot: 'bg-amber-500', pulse: true },\n  down: { label: 'Down', dot: 'bg-red-500', pulse: false },\n}\n\nexport function StatusIndicator({ status }: { status: ServiceStatus }) {\n  const config = STATUS_CONFIG[status]\n\n  return (\n    <span className=\"inline-flex items-center gap-2 text-sm\">\n      <span className=\"relative flex size-2.5\">\n        {config.pulse && (\n          <span\n            className={cn(\n              'absolute inline-flex h-full w-full animate-ping rounded-full opacity-75',\n              config.dot,\n            )}\n          />\n        )}\n        <span\n          className={cn('relative inline-flex size-2.5 rounded-full', config.dot)}\n        />\n      </span>\n      {config.label}\n    </span>\n  )\n}\n",
      "type": "registry:component",
      "target": "@components/tables/live-status-table/status-indicator.tsx"
    },
    {
      "path": "src/components/live-status/columns.tsx",
      "content": "'use client'\n\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { StatusIndicator } from './status-indicator'\n\nexport type ServiceStatus = 'operational' | 'degraded' | 'down'\n\nexport type Service = {\n  id: string\n  name: string\n  region: string\n  status: ServiceStatus\n  latencyMs: number\n  uptime: number\n}\n\nexport const columns: ColumnDef<Service>[] = [\n  {\n    accessorKey: 'name',\n    header: 'Service',\n    cell: ({ row }) => (\n      <div>\n        <div className=\"font-medium\">{row.original.name}</div>\n        <div className=\"text-xs text-muted-foreground\">\n          {row.original.region}\n        </div>\n      </div>\n    ),\n  },\n  {\n    accessorKey: 'status',\n    header: 'Status',\n    cell: ({ row }) => <StatusIndicator status={row.original.status} />,\n  },\n  {\n    accessorKey: 'latencyMs',\n    header: 'Latency',\n    cell: ({ row }) =>\n      row.original.status === 'down' ? (\n        <span className=\"text-muted-foreground\">—</span>\n      ) : (\n        <span className=\"tabular-nums\">{row.original.latencyMs}ms</span>\n      ),\n  },\n  {\n    accessorKey: 'uptime',\n    header: 'Uptime (30d)',\n    cell: ({ row }) => (\n      <span className=\"tabular-nums\">{row.original.uptime.toFixed(2)}%</span>\n    ),\n  },\n]\n",
      "type": "registry:component",
      "target": "@components/tables/live-status-table/columns.tsx"
    },
    {
      "path": "src/components/live-status/data-table.tsx",
      "content": "'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport {\n  flexRender,\n  getCoreRowModel,\n  useReactTable,\n} from '@tanstack/react-table'\n\nimport {\n  Table,\n  TableBody,\n  TableCell,\n  TableHead,\n  TableHeader,\n  TableRow,\n} from '#/components/ui/table'\nimport { cn } from '#/lib/utils.ts'\nimport { columns } from './columns'\nimport type { Service, ServiceStatus } from './columns'\n\nconst TRANSITIONS: Record<ServiceStatus, ServiceStatus[]> = {\n  operational: ['operational', 'operational', 'operational', 'degraded'],\n  degraded: ['operational', 'operational', 'degraded', 'down'],\n  down: ['degraded', 'down', 'down'],\n}\n\nfunction nextStatus(status: ServiceStatus): ServiceStatus {\n  const options = TRANSITIONS[status]\n  return options[Math.floor(Math.random() * options.length)]\n}\n\nfunction jitterLatency(latencyMs: number, status: ServiceStatus) {\n  if (status === 'down') return 0\n  const drift = status === 'degraded' ? 40 : 12\n  const next = latencyMs + Math.round((Math.random() - 0.5) * drift)\n  return Math.max(1, next)\n}\n\ninterface LiveStatusTableProps {\n  data: Service[]\n  onDataChange: (updater: (prev: Service[]) => Service[]) => void\n}\n\nexport function LiveStatusTable({ data, onDataChange }: LiveStatusTableProps) {\n  const [isLive, setIsLive] = useState(true)\n  const cursor = useRef(0)\n\n  useEffect(() => {\n    if (!isLive) return\n\n    const interval = window.setInterval(() => {\n      onDataChange((prev) => {\n        const index = cursor.current % prev.length\n        cursor.current += 1\n        return prev.map((service, i) => {\n          if (i !== index) return service\n          const status = nextStatus(service.status)\n          return {\n            ...service,\n            status,\n            latencyMs: jitterLatency(service.latencyMs, status),\n          }\n        })\n      })\n    }, 1800)\n\n    return () => window.clearInterval(interval)\n  }, [isLive, onDataChange])\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n  })\n\n  return (\n    <div>\n      <div className=\"mb-3 flex items-center justify-between\">\n        <button\n          type=\"button\"\n          onClick={() => setIsLive((v) => !v)}\n          className=\"inline-flex items-center gap-2 rounded-full border px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground\"\n        >\n          <span className=\"relative flex size-2\">\n            {isLive && (\n              <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-500 opacity-75\" />\n            )}\n            <span\n              className={cn(\n                'relative inline-flex size-2 rounded-full',\n                isLive ? 'bg-emerald-500' : 'bg-muted-foreground',\n              )}\n            />\n          </span>\n          {isLive ? 'Live' : 'Paused'}\n        </button>\n      </div>\n\n      <div className=\"overflow-hidden rounded-md border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => (\n                  <TableHead key={header.id}>\n                    {header.isPlaceholder\n                      ? null\n                      : flexRender(\n                          header.column.columnDef.header,\n                          header.getContext(),\n                        )}\n                  </TableHead>\n                ))}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {table.getRowModel().rows.map((row) => (\n              <TableRow key={row.id}>\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell key={cell.id}>\n                    {flexRender(\n                      cell.column.columnDef.cell,\n                      cell.getContext(),\n                    )}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))}\n          </TableBody>\n        </Table>\n      </div>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "@components/tables/live-status-table/data-table.tsx"
    },
    {
      "path": "src/components/live-status/index.tsx",
      "content": "import { useState } from 'react'\n\nimport { LiveStatusTable } from './data-table'\nimport type { Service } from './columns'\n\nconst initialData: Service[] = [\n  { id: '1', name: 'api-gateway', region: 'us-east-1', status: 'operational', latencyMs: 42, uptime: 99.98 },\n  { id: '2', name: 'auth-service', region: 'us-east-1', status: 'operational', latencyMs: 61, uptime: 99.95 },\n  { id: '3', name: 'payments-service', region: 'eu-west-1', status: 'degraded', latencyMs: 180, uptime: 99.72 },\n  { id: '4', name: 'search-index', region: 'us-west-2', status: 'operational', latencyMs: 35, uptime: 99.99 },\n  { id: '5', name: 'notifications-worker', region: 'ap-southeast-1', status: 'operational', latencyMs: 88, uptime: 99.9 },\n  { id: '6', name: 'billing-cron', region: 'eu-west-1', status: 'down', latencyMs: 0, uptime: 98.41 },\n]\n\nexport function LiveStatusTableDemo() {\n  const [data, setData] = useState(initialData)\n\n  return <LiveStatusTable data={data} onDataChange={setData} />\n}\n",
      "type": "registry:component",
      "target": "@components/tables/live-status-table/index.tsx"
    }
  ],
  "type": "registry:block"
}