{
  "name": "social-components-followbutton",
  "type": "registry:component",
  "dependencies": [
    "@radix-ui/react-icons",
    "bmap-api-types"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "components/social/components/FollowButton.tsx",
      "type": "registry:component",
      "content": "import { PersonIcon, PlusIcon } from \"@radix-ui/react-icons\";\nimport type { FollowTransaction, UnfollowTransaction } from \"bmap-api-types\";\nimport { useEffect, useState } from \"react\";\nimport { useBitcoinAuth } from \"../../../hooks/useBitcoinAuth.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport { Button } from \"../../ui/button.js\";\nimport {\n\tHoverCard,\n\tHoverCardContent,\n\tHoverCardTrigger,\n} from \"../../ui/hover-card.js\";\nimport { useFetchTransaction } from \"../hooks/useFetchTransaction.js\";\nimport { useToggleFollow } from \"../hooks/useFollowUser.js\";\nimport type { FollowButtonProps } from \"../types/social.js\";\n\nexport interface FollowButtonComponentProps extends FollowButtonProps {\n\t// Additional component-specific props\n\tfollowText?: string;\n\tunfollowText?: string;\n\tshowIcon?: boolean;\n\tshowTooltip?: boolean;\n\tusername?: string; // For display in tooltip\n}\n\nexport function FollowButton({\n\tidKey,\n\tisFollowing = false,\n\tfollowText = \"Follow\",\n\tunfollowText = \"Unfollow\",\n\tshowIcon = true,\n\tshowTooltip = true,\n\tusername,\n\tonFollow,\n\tonUnfollow,\n\tclassName,\n\tvariant = \"default\",\n\tsize = \"default\",\n\tdisabled,\n\tloading,\n\t...props\n}: FollowButtonComponentProps) {\n\tconst { user, isAuthenticated } = useBitcoinAuth();\n\tconst [pendingTxid, setPendingTxid] = useState<string | null>(null);\n\tconst [pendingAction, setPendingAction] = useState<\n\t\t\"follow\" | \"unfollow\" | null\n\t>(null);\n\n\t// Fetch the full transaction data when a transaction is pending\n\tconst { transaction } = useFetchTransaction({\n\t\ttxid: pendingTxid || \"\",\n\t\tenabled: !!pendingTxid,\n\t\ttype: pendingAction || \"auto\",\n\t});\n\n\tconst { toggle, isLoading, error } = useToggleFollow({\n\t\tonSuccess: (result) => {\n\t\t\tif (result.txid) {\n\t\t\t\tsetPendingTxid(result.txid);\n\t\t\t\tsetPendingAction(result.action);\n\n\t\t\t\t// Transaction will be fetched by useFetchTransaction hook\n\t\t\t\t// and handled in the useEffect below\n\t\t\t}\n\t\t},\n\t});\n\n\t// Handle fetched transaction data\n\tuseEffect(() => {\n\t\tif (transaction && pendingAction && pendingTxid) {\n\t\t\tif (pendingAction === \"follow\") {\n\t\t\t\tonFollow?.(transaction as FollowTransaction);\n\t\t\t} else if (pendingAction === \"unfollow\") {\n\t\t\t\tonUnfollow?.(transaction as UnfollowTransaction);\n\t\t\t}\n\n\t\t\t// Clear pending state after handling\n\t\t\tsetPendingTxid(null);\n\t\t\tsetPendingAction(null);\n\t\t}\n\t}, [transaction, pendingAction, pendingTxid, onFollow, onUnfollow]);\n\n\tconst handleToggle = () => {\n\t\tif (!isAuthenticated || disabled || isLoading) return;\n\n\t\t// Prevent self-following\n\t\tif (user?.idKey === idKey) return;\n\n\t\ttoggle(idKey, isFollowing);\n\t};\n\n\tconst buttonText = isFollowing ? unfollowText : followText;\n\tconst buttonVariant = isFollowing ? \"outline\" : variant;\n\tconst buttonColor = isFollowing ? \"gray\" : undefined;\n\tconst isButtonLoading = loading || isLoading;\n\n\t// Don't show follow button for self\n\tif (user?.idKey === idKey) {\n\t\treturn null;\n\t}\n\n\tconst FollowButtonContent = (\n\t\t<Button\n\t\t\tvariant={buttonVariant}\n\t\t\tsize={size}\n\t\t\tclassName={cn(\n\t\t\t\t!isFollowing &&\n\t\t\t\t\t\"bg-primary text-primary-foreground hover:bg-primary/90\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tdisabled={disabled || !isAuthenticated || isButtonLoading}\n\t\t\tonClick={handleToggle}\n\t\t\t{...props}\n\t\t>\n\t\t\t{showIcon &&\n\t\t\t\t(isFollowing ? (\n\t\t\t\t\t<PersonIcon className=\"h-4 w-4\" />\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<PersonIcon className=\"h-4 w-4\" />\n\t\t\t\t\t\t<PlusIcon className=\"h-3 w-3 -ml-1\" />\n\t\t\t\t\t</>\n\t\t\t\t))}\n\t\t\t{buttonText}\n\t\t</Button>\n\t);\n\n\t// Show tooltip if not authenticated or if username provided\n\tif (showTooltip && (!isAuthenticated || username || error)) {\n\t\treturn (\n\t\t\t<HoverCard>\n\t\t\t\t<HoverCardTrigger asChild>{FollowButtonContent}</HoverCardTrigger>\n\t\t\t\t<HoverCardContent className=\"w-auto p-2\">\n\t\t\t\t\t{!isAuthenticated ? (\n\t\t\t\t\t\t<p className=\"text-sm\">Sign in to follow users</p>\n\t\t\t\t\t) : error ? (\n\t\t\t\t\t\t<p className=\"text-sm text-destructive\">{error.message}</p>\n\t\t\t\t\t) : username ? (\n\t\t\t\t\t\t<p className=\"text-sm\">\n\t\t\t\t\t\t\t{isFollowing ? `Unfollow @${username}` : `Follow @${username}`}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<p className=\"text-sm\">\n\t\t\t\t\t\t\t{isFollowing ? \"Stop following this user\" : \"Follow this user\"}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</HoverCardContent>\n\t\t\t</HoverCard>\n\t\t);\n\t}\n\n\treturn FollowButtonContent;\n}\n\n// Simple follow button without tooltips\nexport function SimpleFollowButton(\n\tprops: Omit<FollowButtonComponentProps, \"showTooltip\">,\n) {\n\treturn <FollowButton {...props} showTooltip={false} />;\n}\n\n// Icon-only follow button\nexport function FollowIconButton(\n\tprops: Omit<\n\t\tFollowButtonComponentProps,\n\t\t\"followText\" | \"unfollowText\" | \"showIcon\"\n\t>,\n) {\n\treturn (\n\t\t<FollowButton\n\t\t\t{...props}\n\t\t\tfollowText=\"\"\n\t\t\tunfollowText=\"\"\n\t\t\tshowIcon={true}\n\t\t\tsize=\"default\"\n\t\t\tvariant=\"ghost\"\n\t\t/>\n\t);\n}\n",
      "target": "<%- config.aliases.components %>/followbutton.tsx"
    }
  ]
}