{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "post-poll",
  "type": "registry:block",
  "title": "Post Poll",
  "description": "A component for displaying and voting on polls within a post.",
  "files": [
    {
      "path": "src/components/deso/post-poll.tsx",
      "content": "'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport { cn } from '@/lib/utils/deso';\nimport { CheckCircle } from 'lucide-react';\nimport NumberFlow, { continuous } from '@number-flow/react'; // Import NumberFlow\n\nexport interface PollOption {\n  text: string;\n}\n\nexport interface PostPollProps {\n  options: PollOption[];\n  votes: number[];\n  totalVotes: number;\n  userVotedIndex: number | null;\n  onVote: (index: number) => void;\n}\n\nexport const PostPoll: React.FC<PostPollProps> = ({\n  options,\n  votes,\n  totalVotes,\n  userVotedIndex,\n  onVote,\n}) => {\n  const [animatedPercentages, setAnimatedPercentages] = useState<number[]>(\n    Array(options.length).fill(0)\n  );\n\n  useEffect(() => {\n    if (userVotedIndex !== null) {\n      const newPercentages = options.map((_, index) =>\n        totalVotes > 0 ? (votes[index] / totalVotes) * 100 : 0\n      );\n      // A timeout to ensure the transition is applied after the component has rendered.\n      const timer = setTimeout(() => {\n        setAnimatedPercentages(newPercentages);\n      }, 100);\n      return () => clearTimeout(timer);\n    }\n  }, [userVotedIndex, options, votes, totalVotes]);\n\n  const handleVote = (index: number) => {\n    if (userVotedIndex === null) {\n      onVote(index);\n    }\n  };\n\n  return (\n    <div className=\"mt-4 space-y-2\">\n      {options.map((option, index) => {\n        if (userVotedIndex !== null) {\n          // Voted state\n          const percentage =\n            totalVotes > 0 ? (votes[index] / totalVotes) * 100 : 0;\n          const isUserChoice = userVotedIndex === index;\n\n          return (\n            <div\n              key={index}\n              className=\"relative flex items-center justify-between overflow-hidden rounded-lg border border-border bg-background p-3 text-foreground\"\n            >\n              <div\n                className=\"absolute left-0 top-0 h-full bg-muted transition-all duration-700 ease-out\"\n                style={{ width: `${animatedPercentages[index] || 0}%` }}\n              />\n              <div className=\"relative z-10 flex w-full items-center justify-between\">\n                <div className=\"flex items-center gap-2\">\n                  <span>{option.text}</span>\n                  {isUserChoice && (\n                    <CheckCircle className=\"h-5 w-5 text-green-500\" />\n                  )}\n                </div>\n                <span className=\"font-semibold\">\n                  <NumberFlow value={Math.round(animatedPercentages[index])} plugins={[continuous]} />\n                  %\n                </span>\n              </div>\n            </div>\n          );\n        } else {\n          // Not voted state\n          return (\n            <button\n              key={index}\n              onClick={() => handleVote(index)}\n              className=\"w-full rounded-lg cursor-pointer border border-border p-3 text-left text-foreground hover:bg-accent focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"\n              disabled={userVotedIndex !== null}\n            >\n              {option.text}\n            </button>\n          );\n        }\n      })}\n      <div className=\"pt-2 text-sm text-muted-foreground\">\n        {totalVotes} total {totalVotes === 1 ? 'vote' : 'votes'}\n      </div>\n    </div>\n  );\n};",
      "type": "registry:component",
      "target": "src/components/deso-ui/post-poll.tsx"
    }
  ]
}