{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "stats-widget",
  "title": "Stats Widgets",
  "description": "Statistics and metrics widgets for displaying data, comparisons, and progress with liquid glass styling.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "https://ui.eindev.ir/r/base-widget.json"
  ],
  "files": [
    {
      "path": "registry/widgets/stats-widget.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  TrendingUp,\n  TrendingDown,\n  ArrowUp,\n  ArrowDown,\n  Minus,\n} from \"lucide-react\";\nimport { GlassWidgetBase } from \"./base-widget\";\n\ninterface StatCardProps {\n  title: string;\n  value: string | number;\n  change?: {\n    value: number;\n    type: \"increase\" | \"decrease\" | \"neutral\";\n  };\n  icon?: React.ReactNode;\n  glowColor?: \"cyan\" | \"purple\" | \"blue\" | \"pink\" | \"green\" | \"amber\" | \"red\";\n  className?: string;\n}\n\nfunction StatCard({\n  title,\n  value,\n  change,\n  icon,\n  glowColor = \"cyan\",\n  className,\n}: StatCardProps) {\n  const changeColors = {\n    increase: \"text-emerald-400\",\n    decrease: \"text-red-400\",\n    neutral: \"text-white/50\",\n  };\n\n  const ChangeIcon = change?.type === \"increase\" ? ArrowUp : change?.type === \"decrease\" ? ArrowDown : Minus;\n\n  return (\n    <GlassWidgetBase\n      className={cn(\"min-w-48\", className)}\n      size=\"md\"\n      glowColor={glowColor}\n    >\n      <div className=\"flex items-start justify-between mb-3\">\n        <div className=\"text-white/60 text-sm\">{title}</div>\n        {icon && <div className=\"text-white/40\">{icon}</div>}\n      </div>\n      <div className=\"text-3xl font-light text-white mb-2\">{value}</div>\n      {change && (\n        <div className={cn(\"flex items-center gap-1 text-xs\", changeColors[change.type])}>\n          <ChangeIcon className=\"w-3 h-3\" />\n          <span>{Math.abs(change.value)}%</span>\n          <span className=\"text-white/50\">vs last period</span>\n        </div>\n      )}\n    </GlassWidgetBase>\n  );\n}\n\ninterface MetricStatProps {\n  label: string;\n  value: number;\n  max?: number;\n  unit?: string;\n  icon?: React.ReactNode;\n  glowColor?: \"cyan\" | \"purple\" | \"blue\" | \"pink\" | \"green\" | \"amber\" | \"red\";\n  className?: string;\n}\n\nfunction MetricStat({\n  label,\n  value,\n  max = 100,\n  unit = \"\",\n  icon,\n  glowColor = \"blue\",\n  className,\n}: MetricStatProps) {\n  const percentage = Math.min((value / max) * 100, 100);\n\n  return (\n    <GlassWidgetBase\n      className={cn(\"min-w-56\", className)}\n      size=\"md\"\n      glowColor={glowColor}\n    >\n      <div className=\"flex items-center justify-between mb-3\">\n        <div className=\"flex items-center gap-2\">\n          {icon && <div className=\"text-white/60\">{icon}</div>}\n          <div className=\"text-white/60 text-sm\">{label}</div>\n        </div>\n        <div className=\"text-white font-medium\">\n          {value}\n          {unit && <span className=\"text-white/60 text-sm ml-1\">{unit}</span>}\n        </div>\n      </div>\n      <div className=\"relative h-2 bg-white/10 rounded-full overflow-hidden\">\n        <div\n          className={cn(\n            \"h-full rounded-full transition-all duration-500\",\n            glowColor === \"cyan\" && \"bg-linear-to-r from-cyan-500 to-blue-500\",\n            glowColor === \"purple\" && \"bg-linear-to-r from-purple-500 to-pink-500\",\n            glowColor === \"blue\" && \"bg-linear-to-r from-blue-500 to-indigo-500\",\n            glowColor === \"pink\" && \"bg-linear-to-r from-pink-500 to-rose-500\",\n            glowColor === \"green\" && \"bg-linear-to-r from-emerald-500 to-teal-500\",\n            glowColor === \"amber\" && \"bg-linear-to-r from-amber-500 to-orange-500\",\n            glowColor === \"red\" && \"bg-linear-to-r from-red-500 to-rose-500\"\n          )}\n          style={{ width: `${percentage}%` }}\n        />\n      </div>\n      <div className=\"text-white/40 text-xs mt-2\">\n        {percentage.toFixed(0)}% of {max}\n        {unit}\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\ninterface ComparisonStatProps {\n  title: string;\n  current: number;\n  previous: number;\n  format?: (value: number) => string;\n  icon?: React.ReactNode;\n  glowColor?: \"cyan\" | \"purple\" | \"blue\" | \"pink\" | \"green\" | \"amber\" | \"red\";\n  className?: string;\n}\n\nfunction ComparisonStat({\n  title,\n  current,\n  previous,\n  format = (v) => v.toString(),\n  icon,\n  glowColor = \"green\",\n  className,\n}: ComparisonStatProps) {\n  // Handle division by zero: if previous is 0, calculate change differently\n  let change: number;\n  let isNew = false;\n  let isZero = false;\n\n  if (previous === 0) {\n    if (current === 0) {\n      change = 0;\n      isZero = true;\n    } else if (current > 0) {\n      // Going from 0 to positive value - treat as \"new\"\n      change = 0;\n      isNew = true;\n    } else {\n      // Going from 0 to negative value - treat as decrease\n      change = -100;\n    }\n  } else {\n    change = ((current - previous) / previous) * 100;\n  }\n\n  const isIncrease = change > 0;\n  const isDecrease = change < 0;\n\n  return (\n    <GlassWidgetBase\n      className={cn(\"min-w-52\", className)}\n      size=\"md\"\n      glowColor={glowColor}\n    >\n      <div className=\"flex items-center justify-between mb-4\">\n        <div className=\"text-white/60 text-sm\">{title}</div>\n        {icon && <div className=\"text-white/40\">{icon}</div>}\n      </div>\n      <div className=\"text-4xl font-light text-white mb-2\">{format(current)}</div>\n      <div className=\"flex items-center gap-2\">\n        {isIncrease ? (\n          <TrendingUp className=\"w-4 h-4 text-emerald-400\" />\n        ) : isDecrease ? (\n          <TrendingDown className=\"w-4 h-4 text-red-400\" />\n        ) : (\n          <Minus className=\"w-4 h-4 text-white/50\" />\n        )}\n        <span\n          className={cn(\n            \"text-sm\",\n            isIncrease && \"text-emerald-400\",\n            isDecrease && \"text-red-400\",\n            !isIncrease && !isDecrease && \"text-white/50\"\n          )}\n        >\n          {isNew ? (\n            \"New\"\n          ) : isZero ? (\n            \"0%\"\n          ) : (\n            <>\n              {isIncrease ? \"+\" : \"\"}\n              {change.toFixed(1)}%\n            </>\n          )}\n        </span>\n        <span className=\"text-white/40 text-xs\">from {format(previous)}</span>\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\ninterface StatsGridProps {\n  stats: Array<{\n    title: string;\n    value: string | number;\n    change?: {\n      value: number;\n      type: \"increase\" | \"decrease\" | \"neutral\";\n    };\n    icon?: React.ReactNode;\n    glowColor?: \"cyan\" | \"purple\" | \"blue\" | \"pink\" | \"green\" | \"amber\" | \"red\";\n  }>;\n  className?: string;\n}\n\nfunction StatsGrid({ stats, className }: StatsGridProps) {\n  return (\n    <div className={cn(\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\", className)}>\n      {stats.map((stat, i) => (\n        <StatCard key={i} {...stat} />\n      ))}\n    </div>\n  );\n}\n\ninterface CircularProgressStatProps {\n  label: string;\n  value: number;\n  max?: number;\n  unit?: string;\n  icon?: React.ReactNode;\n  glowColor?: \"cyan\" | \"purple\" | \"blue\" | \"pink\" | \"green\" | \"amber\" | \"red\";\n  size?: \"sm\" | \"md\" | \"lg\";\n  className?: string;\n}\n\nfunction CircularProgressStat({\n  label,\n  value,\n  max = 100,\n  unit = \"\",\n  icon,\n  glowColor = \"cyan\",\n  size = \"md\",\n  className,\n}: CircularProgressStatProps) {\n  const percentage = Math.min((value / max) * 100, 100);\n  const radius = size === \"lg\" ? 50 : size === \"md\" ? 42 : 36;\n  const circumference = 2 * Math.PI * radius;\n  const offset = circumference - (percentage / 100) * circumference;\n\n  const sizeConfig = {\n    sm: { container: \"w-32 h-32\", text: \"text-2xl\", label: \"text-xs\" },\n    md: { container: \"w-40 h-40\", text: \"text-3xl\", label: \"text-sm\" },\n    lg: { container: \"w-48 h-48\", text: \"text-4xl\", label: \"text-base\" },\n  };\n\n  const config = sizeConfig[size];\n\n  const strokeColors = {\n    cyan: \"#06b6d4\",\n    purple: \"#a855f7\",\n    blue: \"#3b82f6\",\n    pink: \"#ec4899\",\n    green: \"#10b981\",\n    amber: \"#f59e0b\",\n    red: \"#ef4444\",\n  };\n\n  return (\n    <GlassWidgetBase\n      className={cn(\"flex flex-col items-center justify-center\", className)}\n      size=\"md\"\n      glowColor={glowColor}\n    >\n      <div className={cn(\"relative\", config.container)}>\n        <svg className=\"w-full h-full -rotate-90\">\n          <circle\n            cx=\"50%\"\n            cy=\"50%\"\n            r={radius}\n            stroke=\"rgba(255,255,255,0.1)\"\n            strokeWidth=\"6\"\n            fill=\"none\"\n          />\n          <circle\n            cx=\"50%\"\n            cy=\"50%\"\n            r={radius}\n            stroke={strokeColors[glowColor]}\n            strokeWidth=\"6\"\n            fill=\"none\"\n            strokeLinecap=\"round\"\n            strokeDasharray={circumference}\n            strokeDashoffset={offset}\n            className=\"transition-all duration-1000\"\n          />\n        </svg>\n        <div className=\"absolute inset-0 flex flex-col items-center justify-center\">\n          {icon && <div className=\"text-white/60 mb-1\">{icon}</div>}\n          <div className={cn(\"font-light text-white\", config.text)}>\n            {value}\n            {unit && <span className=\"text-white/60 text-lg ml-1\">{unit}</span>}\n          </div>\n          <div className={cn(\"text-white/50 mt-1\", config.label)}>{label}</div>\n        </div>\n      </div>\n    </GlassWidgetBase>\n  );\n}\n\nexport {\n  StatCard,\n  MetricStat,\n  ComparisonStat,\n  StatsGrid,\n  CircularProgressStat,\n};\n\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}