{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "product-qa-community",
  "title": "Product Qa Community",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-vue/blocks/product-qa-community/ProductQaCommunity.vue",
      "content": "<script setup lang=\"ts\">\nimport { ref, computed } from 'vue'\nimport { HelpCircle, MessageSquare, Search, ThumbsUp, ShieldCheck, CheckCircle, Plus, Send } from 'lucide-vue-next'\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 props = withDefaults(defineProps<ProductQaProps>(), {\n  productName: 'Apex Pro Reference Studio Monitor Headphones',\n})\n\nconst localQuestions = ref<QuestionItem[]>(JSON.parse(JSON.stringify(props.questions ?? defaultQuestions)))\nconst searchQuery = ref('')\nconst selectedCategory = ref<'all' | 'compatibility' | 'sound' | 'comfort' | 'cables' | 'shipping'>('all')\n\nconst isAsking = ref(false)\nconst newQuestionText = ref('')\nconst newQuestionCategory = ref<'compatibility' | 'sound' | 'comfort' | 'cables' | 'shipping'>('compatibility')\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\nconst filteredQuestions = computed(() => {\n  return localQuestions.value.filter((q) => {\n    const matchesCat = selectedCategory.value === 'all' || q.category === selectedCategory.value\n    const matchesSearch =\n      searchQuery.value.trim() === '' ||\n      q.question.toLowerCase().includes(searchQuery.value.toLowerCase()) ||\n      q.answers.some((a) => a.answer.toLowerCase().includes(searchQuery.value.toLowerCase()))\n    return matchesCat && matchesSearch\n  })\n})\n\nfunction toggleVoteQuestion(q: QuestionItem) {\n  if (q.hasVoted) {\n    q.upvotes--\n    q.hasVoted = false\n  } else {\n    q.upvotes++\n    q.hasVoted = true\n  }\n}\n\nfunction toggleVoteAnswer(ans: QuestionItem['answers'][0]) {\n  if (ans.hasUpvoted) {\n    ans.helpfulCount--\n    ans.hasUpvoted = false\n  } else {\n    ans.helpfulCount++\n    ans.hasUpvoted = true\n  }\n}\n\nfunction submitNewQuestion() {\n  if (!newQuestionText.value.trim()) return\n  localQuestions.value.unshift({\n    id: `q-${Date.now()}`,\n    question: newQuestionText.value.trim(),\n    askedBy: 'You (Guest User)',\n    askedDate: 'Just now',\n    category: newQuestionCategory.value,\n    upvotes: 1,\n    hasVoted: true,\n    answers: [],\n  })\n  newQuestionText.value = ''\n  isAsking.value = false\n}\n</script>\n\n<template>\n  <Card data-slot=\"product-qa-community\" :class=\"['border-border w-full shadow-xs', className]\">\n    <CardHeader class=\"border-border bg-muted/20 border-b pb-4\">\n      <div class=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div>\n          <div class=\"flex items-center gap-2\">\n            <span\n              class=\"border-border bg-background flex size-6 items-center justify-center rounded-md border shadow-2xs\"\n            >\n              <HelpCircle class=\"text-primary size-3.5\" />\n            </span>\n            <span class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n              Customer & Engineering Community\n            </span>\n          </div>\n          <CardTitle class=\"text-foreground mt-1 text-lg font-semibold tracking-tight sm:text-xl\">\n            Questions & Answers\n          </CardTitle>\n          <CardDescription class=\"text-xs\">\n            Have questions about {{ productName }}? Search community inquiries or ask our acoustic engineering team.\n          </CardDescription>\n        </div>\n\n        <Button size=\"sm\" class=\"gap-1.5 self-start text-xs shadow-xs sm:self-auto\" @click=\"isAsking = !isAsking\">\n          <Plus class=\"size-3.5\" />\n          <span>Ask a Question</span>\n        </Button>\n      </div>\n\n      <!-- Controls: Category Chips & Search Input -->\n      <div class=\"mt-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n        <div class=\"flex flex-wrap items-center gap-1.5\">\n          <button\n            v-for=\"cat in categories\"\n            :key=\"cat.id\"\n            type=\"button\"\n            :class=\"[\n              '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            @click=\"selectedCategory = cat.id as any\"\n          >\n            {{ cat.label }}\n          </button>\n        </div>\n\n        <div class=\"relative w-full sm:w-64\">\n          <Search class=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n          <Input v-model=\"searchQuery\" placeholder=\"Search answered Q&A...\" class=\"h-8 pl-8 text-xs\" />\n        </div>\n      </div>\n    </CardHeader>\n\n    <CardContent class=\"space-y-6 p-4 sm:p-6\">\n      <!-- Ask Question Form Accordion -->\n      <div v-if=\"isAsking\" class=\"border-primary/40 bg-primary/5 space-y-3 rounded-lg border p-4 shadow-xs\">\n        <div class=\"flex items-center justify-between\">\n          <div class=\"flex items-center gap-2\">\n            <MessageSquare class=\"text-primary size-4\" />\n            <span class=\"text-foreground text-xs font-semibold\">Post a Question to Engineering & Community</span>\n          </div>\n          <span class=\"text-muted-foreground text-xs\">Staff answers typically arrive within 4 hours</span>\n        </div>\n\n        <Textarea\n          v-model=\"newQuestionText\"\n          rows=\"3\"\n          placeholder=\"e.g. Does the headband clamping force loosen up after 20 hours of break-in?\"\n          class=\"text-xs\"\n        />\n\n        <div class=\"flex flex-wrap items-center justify-between gap-2\">\n          <div class=\"flex items-center gap-2 text-xs\">\n            <span class=\"text-muted-foreground\">Topic:</span>\n            <select\n              v-model=\"newQuestionCategory\"\n              class=\"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 class=\"flex items-center gap-2\">\n            <Button variant=\"ghost\" size=\"sm\" class=\"h-7 text-xs\" @click=\"isAsking = false\"> Cancel </Button>\n            <Button size=\"sm\" class=\"h-7 gap-1.5 text-xs shadow-2xs\" @click=\"submitNewQuestion\">\n              <Send class=\"size-3\" />\n              <span>Submit Question</span>\n            </Button>\n          </div>\n        </div>\n      </div>\n\n      <!-- Question List -->\n      <div class=\"divide-border space-y-5 divide-y\">\n        <div v-for=\"q in filteredQuestions\" :key=\"q.id\" class=\"space-y-3 pt-5 first:pt-0\">\n          <!-- Question Header Row -->\n          <div class=\"flex items-start justify-between gap-3\">\n            <div class=\"flex items-start gap-3\">\n              <div\n                class=\"bg-muted text-muted-foreground flex size-6 shrink-0 items-center justify-center rounded-full text-xs font-bold\"\n              >\n                Q\n              </div>\n              <div class=\"space-y-1\">\n                <h4 class=\"text-foreground text-sm leading-snug font-semibold\">\n                  {{ q.question }}\n                </h4>\n                <div class=\"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\" class=\"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              :class=\"[\n                '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              @click=\"toggleVoteQuestion(q)\"\n            >\n              <ThumbsUp class=\"size-3\" />\n              <span>{{ q.upvotes }}</span>\n            </button>\n          </div>\n\n          <!-- Answers Section -->\n          <div class=\"ml-9 space-y-3\">\n            <div\n              v-for=\"ans in q.answers\"\n              :key=\"ans.id\"\n              :class=\"[\n                '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 class=\"flex flex-wrap items-center justify-between gap-2\">\n                <div class=\"flex items-center gap-2\">\n                  <Badge\n                    v-if=\"ans.role === 'staff'\"\n                    variant=\"default\"\n                    class=\"bg-success h-4.5 gap-1 px-1.5 text-xs font-semibold text-white\"\n                  >\n                    <ShieldCheck class=\"size-2.5\" />\n                    Staff Expert\n                  </Badge>\n                  <Badge\n                    v-else-if=\"ans.role === 'verified_buyer'\"\n                    variant=\"secondary\"\n                    class=\"text-foreground h-4.5 gap-1 px-1.5 text-xs font-semibold\"\n                  >\n                    <CheckCircle class=\"text-success size-2.5\" />\n                    Verified Owner\n                  </Badge>\n\n                  <span class=\"text-foreground font-semibold\">{{ ans.answeredBy }}</span>\n                  <span class=\"text-muted-foreground\">· {{ ans.answeredDate }}</span>\n                </div>\n\n                <button\n                  type=\"button\"\n                  :class=\"[\n                    '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                  @click=\"toggleVoteAnswer(ans)\"\n                >\n                  <ThumbsUp class=\"size-3\" />\n                  <span>Helpful ({{ ans.helpfulCount }})</span>\n                </button>\n              </div>\n\n              <!-- Answer Body Text -->\n              <p class=\"text-foreground leading-relaxed\">\n                {{ ans.answer }}\n              </p>\n            </div>\n\n            <div\n              v-if=\"q.answers.length === 0\"\n              class=\"border-border text-muted-foreground rounded-lg border border-dashed p-3 text-xs\"\n            >\n              Awaiting answer from engineering team. You will be notified when responded.\n            </div>\n          </div>\n        </div>\n\n        <div v-if=\"filteredQuestions.length === 0\" class=\"text-muted-foreground py-12 text-center text-xs\">\n          No questions found matching your search. Be the first to ask!\n        </div>\n      </div>\n    </CardContent>\n  </Card>\n</template>\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/product-qa-community/ProductQaCommunity.vue"
    },
    {
      "path": "packages/registry-vue/blocks/product-qa-community/index.ts",
      "content": "export { default as ProductQaCommunity } from './ProductQaCommunity.vue'\nexport type { QuestionItem, ProductQaProps } from './ProductQaCommunity.vue'\n",
      "type": "registry:block",
      "target": "~/app/components/blocks/product-qa-community/index.ts"
    }
  ],
  "dependencies": [
    "lucide-vue-next"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/vue/badge.json",
    "https://uipkge.dev/r/vue/button.json",
    "https://uipkge.dev/r/vue/card.json",
    "https://uipkge.dev/r/vue/input.json",
    "https://uipkge.dev/r/vue/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"
  ]
}