{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "product-qa-community",
  "title": "Product Qa Community",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/product-qa-community/ProductQaCommunity.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { HelpCircle, MessageSquare, Search, ThumbsUp, ShieldCheck, CheckCircle, Plus, Send } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Textarea } from '@/components/ui/textarea'\n\nexport interface QuestionItem {\n  id: string\n  question: string\n  askedBy: string\n  askedDate: string\n  category: 'compatibility' | 'sound' | 'comfort' | 'cables' | 'shipping'\n  upvotes: number\n  hasVoted?: boolean\n  answers: {\n    id: string\n    answer: string\n    answeredBy: string\n    answeredDate: string\n    role: 'staff' | 'verified_buyer' | 'community'\n    helpfulCount: number\n    hasUpvoted?: boolean\n  }[]\n}\n\nexport interface ProductQaProps {\n  productName?: string\n  questions?: QuestionItem[]\n  className?: string\n}\n\nconst defaultQuestions: QuestionItem[] = [\n  {\n    id: 'q1',\n    question:\n      'Can these 32-ohm planar drivers be driven directly from a MacBook Pro headphone jack without an external DAC/AMP?',\n    askedBy: 'Julian R. (Audio Engineer)',\n    askedDate: '3 days ago',\n    category: 'compatibility',\n    upvotes: 42,\n    answers: [\n      {\n        id: 'a1',\n        answer:\n          'Yes! Thanks to our high-sensitivity 106 dB/mW planar trace design and flat 32Ω impedance curve, modern high-power laptops (such as Apple Silicon M-series MacBook Pros) drive them with pristine headroom. However, for 192kHz/24-bit studio mastering, pairing with a dedicated balanced 4.4mm DAC/AMP will unlock their full dynamic staging.',\n        answeredBy: 'Marcus Sterling · Lead Acoustic Engineer (Apex)',\n        answeredDate: '2 days ago',\n        role: 'staff',\n        helpfulCount: 38,\n      },\n    ],\n  },\n  {\n    id: 'q2',\n    question: 'Are the lambskin earpads user-replaceable if they wear down over time?',\n    askedBy: 'Elena K.',\n    askedDate: '1 week ago',\n    category: 'comfort',\n    upvotes: 19,\n    answers: [\n      {\n        id: 'a2',\n        answer:\n          'The earpads utilize our magnetic snap-lock mounting system. You can easily remove and swap them in seconds without adhesive. We also offer perforated vegan suede and cooling velour pads in our accessories catalog.',\n        answeredBy: 'Apex Support Team',\n        answeredDate: '6 days ago',\n        role: 'staff',\n        helpfulCount: 22,\n      },\n      {\n        id: 'a3',\n        answer:\n          'Verified buyer here — swapped mine to the cooling velour for long 6-hour mixing sessions. Magnetic snaps are rock solid!',\n        answeredBy: 'Devon T. (Verified Studio Buyer)',\n        answeredDate: '5 days ago',\n        role: 'verified_buyer',\n        helpfulCount: 14,\n      },\n    ],\n  },\n  {\n    id: 'q3',\n    question:\n      'Does the included balanced 4.4mm cable work with Sony DAP walkmans and standard desktop audio interfaces?',\n    askedBy: 'Kenji S.',\n    askedDate: '2 weeks ago',\n    category: 'cables',\n    upvotes: 15,\n    answers: [\n      {\n        id: 'a4',\n        answer:\n          'Yes, the native 4.4mm TRRRS Pentaconn termination matches Sony, FiiO, Astell&Kern, and modern studio DAC balanced outputs. The package also includes a gold-plated 6.35mm (1/4\") TRS screw-on adapter for standard rack equipment.',\n        answeredBy: 'David L. · Product Specialist',\n        answeredDate: '2 weeks ago',\n        role: 'staff',\n        helpfulCount: 16,\n      },\n    ],\n  },\n]\n\nconst categories = [\n  { id: 'all', label: 'All Questions' },\n  { id: 'compatibility', label: 'Compatibility & DACs' },\n  { id: 'sound', label: 'Sound Signature' },\n  { id: 'comfort', label: 'Fit & Ergonomics' },\n  { id: 'cables', label: 'Cables & Hardware' },\n  { id: 'shipping', label: 'Warranty & Shipping' },\n]\n\nexport function ProductQaCommunity({\n  productName = 'Apex Pro Reference Studio Monitor Headphones',\n  questions = defaultQuestions,\n  className,\n}: ProductQaProps) {\n  const [localQuestions, setLocalQuestions] = React.useState<QuestionItem[]>(questions)\n  const [searchQuery, setSearchQuery] = React.useState('')\n  const [selectedCategory, setSelectedCategory] = React.useState<string>('all')\n\n  const [isAsking, setIsAsking] = React.useState(false)\n  const [newQuestionText, setNewQuestionText] = React.useState('')\n  const [newQuestionCategory, setNewQuestionCategory] = React.useState<\n    'compatibility' | 'sound' | 'comfort' | 'cables' | 'shipping'\n  >('compatibility')\n\n  const filteredQuestions = React.useMemo(() => {\n    return localQuestions.filter((q) => {\n      const matchesCat = selectedCategory === 'all' || q.category === selectedCategory\n      const matchesSearch =\n        searchQuery.trim() === '' ||\n        q.question.toLowerCase().includes(searchQuery.toLowerCase()) ||\n        q.answers.some((a) => a.answer.toLowerCase().includes(searchQuery.toLowerCase()))\n      return matchesCat && matchesSearch\n    })\n  }, [localQuestions, selectedCategory, searchQuery])\n\n  function toggleVoteQuestion(qId: string) {\n    setLocalQuestions((prev) =>\n      prev.map((q) => {\n        if (q.id !== qId) return q\n        return {\n          ...q,\n          upvotes: q.hasVoted ? q.upvotes - 1 : q.upvotes + 1,\n          hasVoted: !q.hasVoted,\n        }\n      }),\n    )\n  }\n\n  function toggleVoteAnswer(qId: string, aId: string) {\n    setLocalQuestions((prev) =>\n      prev.map((q) => {\n        if (q.id !== qId) return q\n        return {\n          ...q,\n          answers: q.answers.map((a) => {\n            if (a.id !== aId) return a\n            return {\n              ...a,\n              helpfulCount: a.hasUpvoted ? a.helpfulCount - 1 : a.helpfulCount + 1,\n              hasUpvoted: !a.hasUpvoted,\n            }\n          }),\n        }\n      }),\n    )\n  }\n\n  function submitNewQuestion() {\n    if (!newQuestionText.trim()) return\n    const newQ: QuestionItem = {\n      id: `q-${Date.now()}`,\n      question: newQuestionText.trim(),\n      askedBy: 'You (Guest User)',\n      askedDate: 'Just now',\n      category: newQuestionCategory,\n      upvotes: 1,\n      hasVoted: true,\n      answers: [],\n    }\n    setLocalQuestions([newQ, ...localQuestions])\n    setNewQuestionText('')\n    setIsAsking(false)\n  }\n\n  return (\n    <Card data-slot=\"product-qa-community\" className={`border-border w-full shadow-xs ${className ?? ''}`}>\n      <CardHeader className=\"border-border bg-muted/20 border-b pb-4\">\n        <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n          <div>\n            <div className=\"flex items-center gap-2\">\n              <span className=\"border-border bg-background flex size-6 items-center justify-center rounded-md border shadow-2xs\">\n                <HelpCircle className=\"text-primary size-3.5\" />\n              </span>\n              <span className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                Customer & Engineering Community\n              </span>\n            </div>\n            <CardTitle className=\"text-foreground mt-1 text-lg font-semibold tracking-tight sm:text-xl\">\n              Questions & Answers\n            </CardTitle>\n            <CardDescription className=\"text-xs\">\n              Have questions about {productName}? Search community inquiries or ask our acoustic engineering team.\n            </CardDescription>\n          </div>\n\n          <Button\n            size=\"sm\"\n            className=\"gap-1.5 self-start text-xs shadow-xs sm:self-auto\"\n            onClick={() => setIsAsking(!isAsking)}\n          >\n            <Plus className=\"size-3.5\" />\n            <span>Ask a Question</span>\n          </Button>\n        </div>\n\n        {/* Controls: Category Chips & Search Input */}\n        <div className=\"mt-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n          <div className=\"flex flex-wrap items-center gap-1.5\">\n            {categories.map((cat) => (\n              <button\n                key={cat.id}\n                type=\"button\"\n                className={`rounded-md px-2.5 py-1 text-xs font-medium transition-colors ${\n                  selectedCategory === cat.id\n                    ? 'bg-foreground text-background shadow-2xs'\n                    : 'bg-muted/60 text-muted-foreground hover:bg-muted hover:text-foreground border border-transparent'\n                }`}\n                onClick={() => setSelectedCategory(cat.id)}\n              >\n                {cat.label}\n              </button>\n            ))}\n          </div>\n\n          <div className=\"relative w-full sm:w-64\">\n            <Search className=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n            <Input\n              value={searchQuery}\n              onChange={(e) => setSearchQuery(e.target.value)}\n              placeholder=\"Search answered Q&A...\"\n              className=\"h-8 pl-8 text-xs\"\n            />\n          </div>\n        </div>\n      </CardHeader>\n\n      <CardContent className=\"space-y-6 p-4 sm:p-6\">\n        {/* Ask Question Form Accordion */}\n        {isAsking && (\n          <div className=\"border-primary/40 bg-primary/5 space-y-3 rounded-lg border p-4 shadow-xs\">\n            <div className=\"flex items-center justify-between\">\n              <div className=\"flex items-center gap-2\">\n                <MessageSquare className=\"text-primary size-4\" />\n                <span className=\"text-foreground text-xs font-semibold\">\n                  Post a Question to Engineering & Community\n                </span>\n              </div>\n              <span className=\"text-muted-foreground text-xs\">Staff answers typically arrive within 4 hours</span>\n            </div>\n\n            <Textarea\n              value={newQuestionText}\n              onValueChange={(v) => setNewQuestionText(v)}\n              rows={3}\n              placeholder=\"e.g. Does the headband clamping force loosen up after 20 hours of break-in?\"\n              className=\"text-xs\"\n            />\n\n            <div className=\"flex flex-wrap items-center justify-between gap-2\">\n              <div className=\"flex items-center gap-2 text-xs\">\n                <span className=\"text-muted-foreground\">Topic:</span>\n                <select\n                  value={newQuestionCategory}\n                  onChange={(e) => setNewQuestionCategory(e.target.value as any)}\n                  className=\"border-border bg-background text-foreground h-7 rounded-md border px-2 text-xs focus:outline-hidden\"\n                >\n                  <option value=\"compatibility\">Compatibility & DACs</option>\n                  <option value=\"sound\">Sound Signature</option>\n                  <option value=\"comfort\">Fit & Ergonomics</option>\n                  <option value=\"cables\">Cables & Hardware</option>\n                  <option value=\"shipping\">Warranty & Shipping</option>\n                </select>\n              </div>\n\n              <div className=\"flex items-center gap-2\">\n                <Button variant=\"ghost\" size=\"sm\" className=\"h-7 text-xs\" onClick={() => setIsAsking(false)}>\n                  Cancel\n                </Button>\n                <Button size=\"sm\" className=\"h-7 gap-1.5 text-xs shadow-2xs\" onClick={submitNewQuestion}>\n                  <Send className=\"size-3\" />\n                  <span>Submit Question</span>\n                </Button>\n              </div>\n            </div>\n          </div>\n        )}\n\n        {/* Question List */}\n        <div className=\"divide-border space-y-5 divide-y\">\n          {filteredQuestions.map((q) => (\n            <div key={q.id} className=\"space-y-3 pt-5 first:pt-0\">\n              {/* Question Header Row */}\n              <div className=\"flex items-start justify-between gap-3\">\n                <div className=\"flex items-start gap-3\">\n                  <div className=\"bg-muted text-muted-foreground flex size-6 shrink-0 items-center justify-center rounded-full text-xs font-bold\">\n                    Q\n                  </div>\n                  <div className=\"space-y-1\">\n                    <h4 className=\"text-foreground text-sm leading-snug font-semibold\">{q.question}</h4>\n                    <div className=\"text-muted-foreground flex flex-wrap items-center gap-2 text-xs\">\n                      <span>Asked by {q.askedBy}</span>\n                      <span>·</span>\n                      <span>{q.askedDate}</span>\n                      <Badge variant=\"outline\" className=\"h-4.5 font-mono text-xs uppercase\">\n                        {q.category}\n                      </Badge>\n                    </div>\n                  </div>\n                </div>\n\n                {/* Upvote Question Button */}\n                <button\n                  type=\"button\"\n                  className={`flex shrink-0 items-center gap-1.5 rounded-md border px-2.5 py-1 text-xs font-medium shadow-2xs transition-colors ${\n                    q.hasVoted\n                      ? 'border-primary bg-primary/10 text-primary'\n                      : 'border-border bg-card text-muted-foreground hover:bg-muted hover:text-foreground'\n                  }`}\n                  onClick={() => toggleVoteQuestion(q.id)}\n                >\n                  <ThumbsUp className=\"size-3\" />\n                  <span>{q.upvotes}</span>\n                </button>\n              </div>\n\n              {/* Answers Section */}\n              <div className=\"ml-9 space-y-3\">\n                {q.answers.map((ans) => (\n                  <div\n                    key={ans.id}\n                    className={`space-y-2 rounded-lg border p-3.5 text-xs ${\n                      ans.role === 'staff' ? 'border-success/30 bg-success/5' : 'border-border bg-muted/30'\n                    }`}\n                  >\n                    {/* Answer Meta Bar */}\n                    <div className=\"flex flex-wrap items-center justify-between gap-2\">\n                      <div className=\"flex items-center gap-2\">\n                        {ans.role === 'staff' && (\n                          <Badge\n                            variant=\"default\"\n                            className=\"bg-success h-4.5 gap-1 px-1.5 text-xs font-semibold text-white\"\n                          >\n                            <ShieldCheck className=\"size-2.5\" />\n                            Staff Expert\n                          </Badge>\n                        )}\n                        {ans.role === 'verified_buyer' && (\n                          <Badge\n                            variant=\"secondary\"\n                            className=\"text-foreground h-4.5 gap-1 px-1.5 text-xs font-semibold\"\n                          >\n                            <CheckCircle className=\"text-success size-2.5\" />\n                            Verified Owner\n                          </Badge>\n                        )}\n\n                        <span className=\"text-foreground font-semibold\">{ans.answeredBy}</span>\n                        <span className=\"text-muted-foreground\">· {ans.answeredDate}</span>\n                      </div>\n\n                      <button\n                        type=\"button\"\n                        className={`flex items-center gap-1 text-xs font-medium transition-colors ${\n                          ans.hasUpvoted ? 'text-primary font-bold' : 'text-muted-foreground hover:text-foreground'\n                        }`}\n                        onClick={() => toggleVoteAnswer(q.id, ans.id)}\n                      >\n                        <ThumbsUp className=\"size-3\" />\n                        <span>Helpful ({ans.helpfulCount})</span>\n                      </button>\n                    </div>\n\n                    {/* Answer Body Text */}\n                    <p className=\"text-foreground leading-relaxed\">{ans.answer}</p>\n                  </div>\n                ))}\n\n                {q.answers.length === 0 && (\n                  <div className=\"border-border text-muted-foreground rounded-lg border border-dashed p-3 text-xs\">\n                    Awaiting answer from engineering team. You will be notified when responded.\n                  </div>\n                )}\n              </div>\n            </div>\n          ))}\n\n          {filteredQuestions.length === 0 && (\n            <div className=\"text-muted-foreground py-12 text-center text-xs\">\n              No questions found matching your search. Be the first to ask!\n            </div>\n          )}\n        </div>\n      </CardContent>\n    </Card>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/product-qa-community/ProductQaCommunity.tsx"
    },
    {
      "path": "packages/registry-react/blocks/product-qa-community/index.ts",
      "content": "export { ProductQaCommunity } from './ProductQaCommunity'\nexport type { QuestionItem, ProductQaProps } from './ProductQaCommunity'\n",
      "type": "registry:block",
      "target": "~/components/blocks/product-qa-community/index.ts"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/textarea.json"
  ],
  "description": "Searchable customer and engineering Q&A community forum with staff answer badges, question upvoting, category filters, and live ask modal.",
  "categories": [
    "ecommerce",
    "marketing"
  ]
}