{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "site-card",
  "title": "Site card",
  "description": "Pre-made card for displaying site information within SitecoreAI.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "https://blok.sitecore.com/r/theme.json",
    "https://blok.sitecore.com/r/button.json",
    "https://blok.sitecore.com/r/label.json",
    "https://blok.sitecore.com/r/input.json",
    "https://blok.sitecore.com/r/card.json",
    "https://blok.sitecore.com/r/dropdown-menu.json",
    "https://blok.sitecore.com/r/dialog.json"
  ],
  "files": [
    {
      "path": "src/components/bloks/site-card.tsx",
      "content": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Card, CardContent, CardFooter } from \"@/components/ui/card\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { MoreVertical, PinOff } from \"lucide-react\";\nimport type { ComponentProps } from \"react\";\nimport { useState } from \"react\";\n\ninterface SiteData {\n  id: string;\n  name: string;\n  displayName: string;\n  collectionName?: string;\n  thumbnail: {\n    url: string;\n  };\n  permissions: {\n    canRename?: boolean;\n    canCreate?: boolean;\n  };\n  hosts: Array<{\n    targetHostname?: string;\n  }>;\n  collectionId: string;\n}\n\ninterface FooterButton {\n  icon: React.ReactNode;\n  label: string;\n  onClick: () => void;\n}\n\ninterface DropdownAction {\n  icon: React.ReactNode;\n  label: string;\n  onClick: () => void;\n  show?: boolean;\n}\n\ninterface PinnedSiteCardProps<T extends SiteData> {\n  site: T;\n  isDisabled?: boolean;\n  onUnpin?: (siteId: string) => void;\n  showPinOverlay?: boolean;\n  showDropdownMenu?: boolean;\n  footerButtons?: FooterButton[];\n  dropdownActions?: DropdownAction[];\n}\n\nexport function SiteCard<T extends SiteData>({\n  site,\n  isDisabled = false,\n  onUnpin,\n  showPinOverlay = true,\n  showDropdownMenu = true,\n  footerButtons = [],\n  dropdownActions = [],\n  ...props\n}: PinnedSiteCardProps<T> & ComponentProps<\"div\">) {\n  const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n\n  const handleCardClick = (_e: React.MouseEvent) => {\n    if (!isDisabled) {\n      console.log(\n        `Navigate to /collection/${site.collectionId}/sites/${site.id}/overview`,\n      );\n    }\n  };\n\n  const handleMenuClick = (e: React.MouseEvent) => {\n    e.preventDefault();\n    e.stopPropagation();\n  };\n\n  // Filter dropdown actions based on show property\n  const visibleDropdownActions = dropdownActions.filter(\n    (action) => action.show !== false,\n  );\n\n  return (\n    <Card\n      {...props}\n      elevation=\"sm\"\n      style=\"outline\"\n      className={`group relative w-full cursor-pointer transition-all overflow-hidden p-0 gap-0 h-[226px] flex flex-col${\n        isDisabled ? \" opacity-40 pointer-events-none\" : \"\"\n      }`}\n      onClick={handleCardClick}\n    >\n      <CardContent\n        className={`p-0 flex-1 min-h-0 transition-all duration-200 ease-in-out ${\n          site.collectionName ? \"group-hover:flex-[0.6]\" : \"\"\n        }`}\n      >\n        <div className=\"relative w-full h-full bg-muted\">\n          <img\n            src={site.thumbnail.url}\n            alt={site.name}\n            className=\"absolute inset-0 w-full h-full object-cover\"\n            draggable={false}\n            onError={(e) => {\n              const target = e.target as HTMLImageElement;\n              target.src =\n                \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='160'%3E%3Crect width='320' height='160' fill='%23f0f0f0'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' fill='%23999' font-family='sans-serif' font-size='16'%3ENo Image%3C/text%3E%3C/svg%3E\";\n            }}\n          />\n        </div>\n      </CardContent>\n      <CardFooter\n        className={`relative flex-col px-4 border-t overflow-hidden transition-[height,padding-top,padding-bottom,justify-content,gap] duration-200 ease-in-out ${\n          isDropdownOpen\n            ? \"h-[102px] pt-3 pb-3 items-start justify-start gap-2\"\n            : site.collectionName\n              ? \"h-[68px] pt-3 pb-3 items-start justify-center gap-0 group-hover:h-[102px] group-hover:justify-start group-hover:gap-2 group-hover:flex-[0.4]\"\n              : \"h-[68px] pt-3 pb-3 items-start justify-center gap-0 group-hover:h-[102px] group-hover:justify-start group-hover:gap-2\"\n        }`}\n      >\n        {/* Site Title */}\n        <div className=\"w-full space-y-0.5\">\n          <h2\n            className=\"text-sm font-semibold truncate leading-tight\"\n            title={site.displayName || site.name}\n          >\n            {site.displayName || site.name}\n          </h2>\n          {site.collectionName && (\n            <p\n              className=\"text-xs text-muted-foreground truncate leading-tight\"\n              title={site.collectionName}\n            >\n              {site.collectionName}\n            </p>\n          )}\n        </div>\n\n        {/* Action Buttons - Slides up on hover */}\n        <div\n          className={`flex items-center gap-2 w-full transition-opacity duration-150 ease-in-out ${\n            isDropdownOpen\n              ? \"opacity-100 visible\"\n              : \"opacity-0 invisible group-hover:opacity-100 group-hover:visible\"\n          }`}\n          onClick={handleMenuClick}\n        >\n          {footerButtons.map((button, index) => (\n            <Button\n              key={index}\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"flex-1 justify-center gap-1.5 h-8\"\n              onClick={(e) => {\n                e.stopPropagation();\n                button.onClick();\n              }}\n            >\n              {button.icon}\n              <span className=\"text-xs\">{button.label}</span>\n            </Button>\n          ))}\n\n          {showDropdownMenu && visibleDropdownActions.length > 0 && (\n            <DropdownMenu onOpenChange={setIsDropdownOpen}>\n              <DropdownMenuTrigger asChild>\n                <Button\n                  variant=\"ghost\"\n                  size=\"icon\"\n                  className=\"h-8 w-8 flex-shrink-0\"\n                >\n                  <MoreVertical className=\"h-4 w-4\" />\n                </Button>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent align=\"end\">\n                {visibleDropdownActions.map((action, index) => (\n                  <DropdownMenuItem key={index} onClick={action.onClick}>\n                    {action.icon}\n                    <span>{action.label}</span>\n                  </DropdownMenuItem>\n                ))}\n              </DropdownMenuContent>\n            </DropdownMenu>\n          )}\n        </div>\n      </CardFooter>\n\n      {!isDisabled && onUnpin && showPinOverlay && (\n        <div className=\"absolute top-1.5 right-1.5\">\n          <Button\n            variant=\"outline\"\n            size=\"icon\"\n            className=\"opacity-0 group-hover:opacity-100 h-8 w-8 bg-card hover:bg-accent\"\n            onClick={(e) => {\n              e.preventDefault();\n              e.stopPropagation();\n              onUnpin(site.id);\n            }}\n            title=\"Unpin site\"\n          >\n            <PinOff size={10} strokeWidth={0.9} absoluteStrokeWidth />\n          </Button>\n        </div>\n      )}\n    </Card>\n  );\n}\n",
      "type": "registry:ui",
      "target": "src/components/bloks/site-card.tsx"
    }
  ],
  "type": "registry:block"
}