{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "upstash-queue-card",
  "title": "Upstash Queue Card",
  "description": "QStash message/task status card showing state, retries, scheduled time, and payload preview.",
  "dependencies": [
    "@upstash/qstash"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/blocks/upstash/upstash-queue-card/components/elements/upstash-queue-card.tsx",
      "content": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype QueueStatus = \"pending\" | \"processing\" | \"completed\" | \"failed\" | \"scheduled\";\n\ninterface UpstashQueueCardProps {\n  id: string;\n  status: QueueStatus;\n  payload?: string;\n  scheduledAt?: Date | string;\n  completedAt?: Date | string;\n  retries?: number;\n  maxRetries?: number;\n  error?: string;\n  className?: string;\n}\n\nfunction ClockIcon({ className }: { className?: string }) {\n  return (\n    <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <circle cx=\"12\" cy=\"12\" r=\"10\" />\n      <polyline points=\"12 6 12 12 16 14\" />\n    </svg>\n  );\n}\n\nfunction LoaderIcon({ className }: { className?: string }) {\n  return (\n    <svg className={cn(\"animate-spin\", className)} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M21 12a9 9 0 1 1-6.219-8.56\" />\n    </svg>\n  );\n}\n\nfunction CheckIcon({ className }: { className?: string }) {\n  return (\n    <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M20 6 9 17l-5-5\" />\n    </svg>\n  );\n}\n\nfunction XIcon({ className }: { className?: string }) {\n  return (\n    <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M18 6 6 18\" />\n      <path d=\"m6 6 12 12\" />\n    </svg>\n  );\n}\n\nfunction CalendarIcon({ className }: { className?: string }) {\n  return (\n    <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M8 2v4\" />\n      <path d=\"M16 2v4\" />\n      <rect width=\"18\" height=\"18\" x=\"3\" y=\"4\" rx=\"2\" />\n      <path d=\"M3 10h18\" />\n    </svg>\n  );\n}\n\nfunction RefreshIcon({ className }: { className?: string }) {\n  return (\n    <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n      <path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\" />\n      <path d=\"M21 3v5h-5\" />\n      <path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\" />\n      <path d=\"M8 16H3v5\" />\n    </svg>\n  );\n}\n\nconst STATUS_CONFIG: Record<QueueStatus, { icon: React.ComponentType<{ className?: string }>; color: string; bg: string; label: string }> = {\n  pending: { icon: ClockIcon, color: \"text-yellow-500\", bg: \"bg-yellow-500/10\", label: \"Pending\" },\n  processing: { icon: LoaderIcon, color: \"text-blue-500\", bg: \"bg-blue-500/10\", label: \"Processing\" },\n  completed: { icon: CheckIcon, color: \"text-green-500\", bg: \"bg-green-500/10\", label: \"Completed\" },\n  failed: { icon: XIcon, color: \"text-destructive\", bg: \"bg-destructive/10\", label: \"Failed\" },\n  scheduled: { icon: CalendarIcon, color: \"text-purple-500\", bg: \"bg-purple-500/10\", label: \"Scheduled\" },\n};\n\nfunction formatDate(date: Date | string): string {\n  const d = typeof date === \"string\" ? new Date(date) : date;\n  return d.toLocaleString(undefined, {\n    month: \"short\",\n    day: \"numeric\",\n    hour: \"2-digit\",\n    minute: \"2-digit\",\n  });\n}\n\nexport function UpstashQueueCard({\n  id,\n  status,\n  payload,\n  scheduledAt,\n  completedAt,\n  retries = 0,\n  maxRetries = 3,\n  error,\n  className,\n}: UpstashQueueCardProps) {\n  const config = STATUS_CONFIG[status];\n  const StatusIcon = config.icon;\n\n  return (\n    <div\n      data-slot=\"upstash-queue-card\"\n      className={cn(\n        \"rounded-lg border border-border bg-card p-4\",\n        \"flex flex-col gap-3\",\n        className\n      )}\n    >\n      <div className=\"flex items-center justify-between\">\n        <div className=\"flex items-center gap-2\">\n          <div className={cn(\"p-1.5 rounded-md\", config.bg)}>\n            <StatusIcon className={cn(\"w-4 h-4\", config.color)} />\n          </div>\n          <span className={cn(\"text-sm font-medium\", config.color)}>\n            {config.label}\n          </span>\n        </div>\n        <code className=\"text-xs text-muted-foreground font-mono\">\n          {id.slice(0, 8)}...\n        </code>\n      </div>\n\n      {payload && (\n        <div className=\"rounded-md bg-muted/50 p-2\">\n          <pre className=\"text-xs text-muted-foreground overflow-x-auto\">\n            {payload.length > 100 ? `${payload.slice(0, 100)}...` : payload}\n          </pre>\n        </div>\n      )}\n\n      <div className=\"flex flex-wrap items-center gap-4 text-xs text-muted-foreground\">\n        {scheduledAt && (\n          <div className=\"flex items-center gap-1\">\n            <CalendarIcon className=\"w-3 h-3\" />\n            <span>{formatDate(scheduledAt)}</span>\n          </div>\n        )}\n        {completedAt && status === \"completed\" && (\n          <div className=\"flex items-center gap-1\">\n            <CheckIcon className=\"w-3 h-3\" />\n            <span>{formatDate(completedAt)}</span>\n          </div>\n        )}\n        {retries > 0 && (\n          <div className=\"flex items-center gap-1\">\n            <RefreshIcon className=\"w-3 h-3\" />\n            <span>{retries}/{maxRetries} retries</span>\n          </div>\n        )}\n      </div>\n\n      {error && status === \"failed\" && (\n        <div className=\"rounded-md bg-destructive/10 p-2 text-xs text-destructive\">\n          {error}\n        </div>\n      )}\n    </div>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "docs": "Display QStash task status with visual badges for pending/processing/completed/failed states. Shows retry count, scheduled time, and error messages.",
  "categories": [
    "upstash"
  ],
  "type": "registry:block"
}