{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "product-qa-community",
  "title": "Product Qa Community",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-svelte/blocks/product-qa-community/ProductQaCommunity.svelte",
      "content": "<script lang=\"ts\" module>\n  export interface AnswerItem {\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  export 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: AnswerItem[]\n  }\n\n  export interface ProductQaProps {\n    productName?: string\n    questions?: QuestionItem[]\n    className?: string\n  }\n\n  const 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</script>\n\n<script lang=\"ts\">\n  import { CheckCircle, HelpCircle, MessageSquare, Plus, Search, Send, ShieldCheck, ThumbsUp } from '@lucide/svelte'\n  import { Badge } from '$lib/components/ui/badge'\n  import { Button } from '$lib/components/ui/button'\n  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '$lib/components/ui/card'\n  import { Input } from '$lib/components/ui/input'\n  import { Textarea } from '$lib/components/ui/textarea'\n  import { cn } from '$lib/utils'\n\n  let {\n    productName = 'Apex Pro Reference Studio Monitor Headphones',\n    questions,\n    className,\n  }: ProductQaProps = $props()\n\n  let localQuestions = $state<QuestionItem[]>(JSON.parse(JSON.stringify(questions ?? defaultQuestions)))\n  let searchQuery = $state('')\n  let selectedCategory = $state<'all' | 'compatibility' | 'sound' | 'comfort' | 'cables' | 'shipping'>('all')\n\n  let isAsking = $state(false)\n  let newQuestionText = $state('')\n  let newQuestionCategory = $state<'compatibility' | 'sound' | 'comfort' | 'cables' | 'shipping'>('compatibility')\n\n  const 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\n  const filteredQuestions = $derived.by(() => {\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  })\n\n  function 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\n  function toggleVoteAnswer(ans: AnswerItem) {\n    if (ans.hasUpvoted) {\n      ans.helpfulCount--\n      ans.hasUpvoted = false\n    } else {\n      ans.helpfulCount++\n      ans.hasUpvoted = true\n    }\n  }\n\n  function submitNewQuestion() {\n    if (!newQuestionText.trim()) return\n    localQuestions.unshift({\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    newQuestionText = ''\n    isAsking = false\n  }\n</script>\n\n<Card data-slot=\"product-qa-community\" class={cn('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\" onclick={() => (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        {#each categories as cat (cat.id)}\n          <button\n            type=\"button\"\n            class={cn(\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            onclick={() => (selectedCategory = cat.id as typeof selectedCategory)}\n          >\n            {cat.label}\n          </button>\n        {/each}\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 bind:value={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    {#if isAsking}\n      <div 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          bind:value={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              bind:value={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\" onclick={() => (isAsking = false)}> Cancel </Button>\n            <Button size=\"sm\" class=\"h-7 gap-1.5 text-xs shadow-2xs\" onclick={submitNewQuestion}>\n              <Send class=\"size-3\" />\n              <span>Submit Question</span>\n            </Button>\n          </div>\n        </div>\n      </div>\n    {/if}\n\n    <!-- Question List -->\n    <div class=\"divide-border space-y-5 divide-y\">\n      {#each filteredQuestions as q (q.id)}\n        <div 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={cn(\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              onclick={() => 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            {#each q.answers as ans (ans.id)}\n              <div\n                class={cn(\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                    {#if ans.role === 'staff'}\n                      <Badge variant=\"default\" class=\"bg-success h-4.5 gap-1 px-1.5 text-xs font-semibold text-white\">\n                        <ShieldCheck class=\"size-2.5\" />\n                        Staff Expert\n                      </Badge>\n                    {:else if ans.role === 'verified_buyer'}\n                      <Badge variant=\"secondary\" class=\"text-foreground h-4.5 gap-1 px-1.5 text-xs font-semibold\">\n                        <CheckCircle class=\"text-success size-2.5\" />\n                        Verified Owner\n                      </Badge>\n                    {/if}\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={cn(\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                    onclick={() => 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            {/each}\n\n            {#if q.answers.length === 0}\n              <div class=\"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            {/if}\n          </div>\n        </div>\n      {/each}\n\n      {#if filteredQuestions.length === 0}\n        <div 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      {/if}\n    </div>\n  </CardContent>\n</Card>\n",
      "type": "registry:block",
      "target": "~/src/lib/components/blocks/product-qa-community/ProductQaCommunity.svelte"
    }
  ],
  "dependencies": [
    "@lucide/svelte"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/svelte/badge.json",
    "https://uipkge.dev/r/svelte/button.json",
    "https://uipkge.dev/r/svelte/card.json",
    "https://uipkge.dev/r/svelte/input.json",
    "https://uipkge.dev/r/svelte/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"
  ]
}