{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "product-card",
  "title": "Product Card",
  "author": "AlgorizeTech",
  "description": "A reusable, prop-driven E-commerce Product Card supporting color swatches, badges, ratings, quick view, and action buttons.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "src/components/custom/blocks/ProductCardBlock.tsx",
      "content": "\"use client\";\n\nimport React, { useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  Heart,\n  ShoppingCart,\n  Star,\n  Zap,\n  CheckCircle2,\n  Plus,\n  Eye,\n} from \"lucide-react\";\n\nexport type ProductCardVariant = \"standard\" | \"compact\" | \"horizontal\";\n\nexport interface ProductColorOption {\n  name: string;\n  value: string; // Tailwind color class or hex string (e.g. 'bg-indigo-600')\n}\n\nexport interface ProductCardProps {\n  className?: string;\n  variant?: ProductCardVariant;\n  title: string;\n  subtitle?: string;\n  description?: string;\n  price: string;\n  originalPrice?: string;\n  rating?: number;\n  reviewsCount?: number;\n  badge?: string;\n  badgeVariant?: \"emerald\" | \"rose\" | \"indigo\" | \"amber\" | \"zinc\";\n  inStock?: boolean;\n  image?: React.ReactNode;\n  colors?: ProductColorOption[];\n  defaultColorIndex?: number;\n  onColorChange?: (color: ProductColorOption, index: number) => void;\n  onAddToCart?: () => void;\n  onBuyNow?: () => void;\n  onQuickView?: () => void;\n  onFavoriteToggle?: (isLiked: boolean) => void;\n  interactive?: boolean;\n}\n\nconst badgeColorStyles: Record<string, string> = {\n  emerald: \"bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border-emerald-500/20\",\n  rose: \"bg-rose-500/15 text-rose-600 dark:text-rose-400 border-rose-500/20\",\n  indigo: \"bg-indigo-500/15 text-indigo-600 dark:text-indigo-400 border-indigo-500/20\",\n  amber: \"bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-500/20\",\n  zinc: \"bg-zinc-500/15 text-zinc-700 dark:text-zinc-300 border-zinc-500/20\",\n};\n\nexport function ProductCard({\n  className,\n  variant = \"standard\",\n  title,\n  subtitle,\n  description,\n  price,\n  originalPrice,\n  rating,\n  reviewsCount,\n  badge,\n  badgeVariant = \"emerald\",\n  inStock = true,\n  image,\n  colors,\n  defaultColorIndex = 0,\n  onColorChange,\n  onAddToCart,\n  onBuyNow,\n  onQuickView,\n  onFavoriteToggle,\n  interactive = false,\n}: ProductCardProps) {\n  const [liked, setLiked] = useState(false);\n  const [selectedColorIdx, setSelectedColorIdx] = useState(defaultColorIndex);\n\n  const handleFavoriteClick = (e: React.MouseEvent) => {\n    e.stopPropagation();\n    const newLiked = !liked;\n    setLiked(newLiked);\n    onFavoriteToggle?.(newLiked);\n  };\n\n  const handleColorSelect = (color: ProductColorOption, idx: number, e: React.MouseEvent) => {\n    e.stopPropagation();\n    setSelectedColorIdx(idx);\n    onColorChange?.(color, idx);\n  };\n\n  if (variant === \"horizontal\") {\n    return (\n      <article\n        className={cn(\n          \"w-full rounded-2xl bg-primary/[0.008] border border-primary/20 p-4 flex flex-col sm:flex-row items-center gap-4 text-foreground transition-all duration-200\",\n          interactive && \"hover:shadow-md hover:border-primary/50 hover:-translate-y-0.5\",\n          className\n        )}\n      >\n        {/* Thumbnail Image */}\n        <div className=\"size-24 rounded-2xl bg-primary/10 border border-primary/20 shrink-0 flex items-center justify-center overflow-hidden\">\n          {image || <span className=\"text-3xl font-bold\">🛍️</span>}\n        </div>\n\n        {/* Content */}\n        <div className=\"flex-1 space-y-1 text-center sm:text-left min-w-0\">\n          <div className=\"flex items-center justify-center sm:justify-start gap-2 flex-wrap\">\n            {badge && (\n              <span\n                className={cn(\n                  \"px-2 py-0.5 rounded-md text-[10px] font-extrabold uppercase border\",\n                  badgeColorStyles[badgeVariant] || badgeColorStyles.emerald\n                )}\n              >\n                {badge}\n              </span>\n            )}\n            {rating !== undefined && (\n              <span className=\"text-xs font-semibold text-amber-500 flex items-center gap-1\">\n                <Star className=\"size-3 fill-amber-500\" /> {rating}\n              </span>\n            )}\n          </div>\n          <h4 className=\"text-base font-extrabold text-foreground line-clamp-1\">{title}</h4>\n          {description && (\n            <p className=\"text-xs text-muted-foreground line-clamp-1\">{description}</p>\n          )}\n        </div>\n\n        {/* Price & Action */}\n        <div className=\"flex items-center gap-4 shrink-0 border-t sm:border-t-0 sm:border-l border-border/60 pt-3 sm:pt-0 sm:pl-4 w-full sm:w-auto justify-between sm:justify-end\">\n          <div className=\"text-left sm:text-right\">\n            <span className=\"text-lg font-bold text-foreground\">{price}</span>\n            {originalPrice && (\n              <p className=\"text-xs text-muted-foreground line-through\">{originalPrice}</p>\n            )}\n          </div>\n          {onAddToCart && (\n            <button\n              type=\"button\"\n              onClick={onAddToCart}\n              className=\"size-10 rounded-xl bg-primary text-primary-foreground flex items-center justify-center hover:opacity-90 transition-opacity active:scale-95 shadow-xs\"\n            >\n              <Plus className=\"size-5\" />\n            </button>\n          )}\n        </div>\n      </article>\n    );\n  }\n\n  return (\n    <article\n      className={cn(\n        \"w-full rounded-2xl bg-primary/[0.008] border border-primary/20 overflow-hidden flex flex-col justify-between text-foreground transition-all duration-200 group\",\n        interactive && \"hover:shadow-lg hover:border-primary/50 hover:-translate-y-1\",\n        className\n      )}\n    >\n      {/* Image Preview Area */}\n      <div className=\"relative aspect-4/3 w-full bg-gradient-to-br from-primary/10 via-primary/5 to-transparent flex items-center justify-center p-0 overflow-hidden\">\n        {badge && (\n          <span\n            className={cn(\n              \"absolute top-3 left-3 px-2.5 py-1 rounded-full text-[10px] font-extrabold uppercase tracking-wider border z-20\",\n              badgeColorStyles[badgeVariant] || badgeColorStyles.emerald\n            )}\n          >\n            {badge}\n          </span>\n        )}\n\n        {inStock !== undefined && (\n          <div className=\"absolute top-3 right-3 flex items-center gap-1 px-2 py-0.5 rounded-md bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 text-[10px] font-extrabold z-20\">\n            <CheckCircle2 className=\"size-3\" /> {inStock ? \"In Stock\" : \"Out of Stock\"}\n          </div>\n        )}\n\n        {onFavoriteToggle && (\n          <button\n            type=\"button\"\n            onClick={handleFavoriteClick}\n            className={cn(\n              \"absolute right-3 p-2 rounded-full bg-background/80 backdrop-blur-xs border border-border text-muted-foreground hover:text-rose-500 transition-colors shadow-2xs z-20\",\n              inStock !== undefined ? \"top-10\" : \"top-3\"\n            )}\n          >\n            <Heart className={cn(\"size-4\", liked && \"fill-rose-500 text-rose-500\")} />\n          </button>\n        )}\n\n        {/* Product Visual */}\n        <div className=\"w-full h-full flex items-center justify-center group-hover:scale-105 transition-transform duration-300\">\n          {image || <span className=\"text-4xl font-bold\">📦</span>}\n        </div>\n      </div>\n\n      {/* Body Content */}\n      <div className=\"p-4 pb-2 flex-1 flex flex-col justify-between\">\n        <div className=\"space-y-1\">\n          <div className=\"flex items-center justify-between text-xs text-muted-foreground mb-1\">\n            {subtitle && <span className=\"font-semibold text-primary\">{subtitle}</span>}\n            {rating !== undefined && (\n              <span className=\"flex items-center gap-1 font-semibold text-amber-500 ml-auto\">\n                <Star className=\"size-3.5 fill-amber-500\" /> {rating}\n                {reviewsCount !== undefined && (\n                  <span className=\"text-muted-foreground font-normal\">({reviewsCount})</span>\n                )}\n              </span>\n            )}\n          </div>\n\n          <h3 className=\"text-base font-extrabold text-foreground line-clamp-1\">{title}</h3>\n          {description && (\n            <p className=\"text-xs text-muted-foreground line-clamp-2\">{description}</p>\n          )}\n        </div>\n\n        {/* Color Options Swatches */}\n        {colors && colors.length > 0 && (\n          <div className=\"flex items-center justify-between pt-3 mt-2 border-t border-border/40\">\n            <span className=\"text-[11px] font-semibold text-muted-foreground\">Color</span>\n            <div className=\"flex items-center gap-1.5\">\n              {colors.map((col, idx) => (\n                <button\n                  key={col.name || idx}\n                  type=\"button\"\n                  title={col.name}\n                  onClick={(e) => handleColorSelect(col, idx, e)}\n                  className={cn(\n                    \"size-3.5 rounded-full border transition-all\",\n                    col.value,\n                    selectedColorIdx === idx\n                      ? \"ring-2 ring-primary/30 ring-offset-1 scale-110\"\n                      : \"opacity-75 hover:opacity-100\"\n                  )}\n                />\n              ))}\n            </div>\n          </div>\n        )}\n      </div>\n\n      {/* Footer / Actions */}\n      <div className=\"p-4 pt-2 flex items-center justify-between border-t border-border/40 mt-1\">\n        <div>\n          <span className=\"text-lg font-bold text-foreground\">{price}</span>\n          {originalPrice && (\n            <span className=\"text-xs text-muted-foreground line-through ml-2\">\n              {originalPrice}\n            </span>\n          )}\n        </div>\n\n        <div className=\"flex items-center gap-2\">\n          {onQuickView && (\n            <button\n              type=\"button\"\n              onClick={onQuickView}\n              className=\"px-3 py-2 rounded-xl border border-primary/30 bg-background hover:bg-primary/10 hover:text-primary hover:border-primary/50 text-foreground text-xs font-semibold flex items-center gap-1.5 transition-colors active:scale-95 cursor-pointer\"\n            >\n              <Eye className=\"size-3.5\" /> Quick View\n            </button>\n          )}\n\n          {onAddToCart && (\n            <button\n              type=\"button\"\n              onClick={onAddToCart}\n              className=\"px-3.5 py-2 rounded-xl bg-primary text-primary-foreground text-xs font-semibold flex items-center gap-1.5 hover:opacity-90 transition-opacity active:scale-95 shadow-xs\"\n            >\n              <ShoppingCart className=\"size-3.5\" /> Add\n            </button>\n          )}\n\n          {onBuyNow && (\n            <button\n              type=\"button\"\n              onClick={onBuyNow}\n              className=\"px-3.5 py-2 rounded-xl bg-primary text-primary-foreground text-xs font-semibold flex items-center gap-1.5 hover:opacity-90 transition-opacity active:scale-95 shadow-xs\"\n            >\n              <Zap className=\"size-3.5\" /> Buy Now\n            </button>\n          )}\n        </div>\n      </div>\n    </article>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/custom/blocks/ProductCardBlock.tsx"
    }
  ],
  "docs": "Supports variant=('standard' | 'compact' | 'horizontal'), title, price, colors, badge, rating, onAddToCart, onBuyNow, and onQuickView.",
  "categories": [
    "data-display",
    "commerce"
  ],
  "type": "registry:component"
}
