{"path":"src/components/ProductCard.tsx","size":10469,"locked":false,"binary":false,"truncated":false,"content":"\"use client\";\n\nimport { useState } from \"react\";\nimport Image from \"next/image\";\nimport Link from \"next/link\";\nimport {\n  ExternalLink,\n  MessageCircle,\n  X,\n  Sparkles,\n  Wallet,\n  Glasses,\n  Watch,\n  Copy,\n  Star,\n  ChevronLeft,\n  ChevronRight,\n} from \"lucide-react\";\n\nconst iconLibrary: Record<string, any> = {\n  sparkles: Sparkles,\n  wallet: Wallet,\n  glasses: Glasses,\n  watch: Watch,\n};\n\ninterface Props {\n  product: any;\n  chat: {\n    whatsapp?: string;\n    telegram?: string;\n    discord?: string;\n    viber?: string;\n  };\n  preferredChat?: string;\n  ratingStats?: Record<string, { average: number; count: number }>;\n}\n\nexport function ProductCard({ product, chat, preferredChat, ratingStats }: Props) {\n  const [modalOpen, setModalOpen] = useState(false);\n  const [copied, setCopied] = useState(false);\n  const [currentImageIndex, setCurrentImageIndex] = useState(0);\n  const IconComponent = iconLibrary[product.icon] || Sparkles;\n\n  // Bullet‑proof image list: clean the images array, fallback to single image, default to empty\n  const rawImages = Array.isArray(product?.images) ? product.images : [];\n  const cleanImages = rawImages.filter((u: any) => typeof u === \"string\" && u.trim().length > 0);\n  const allImages: string[] = cleanImages.length > 0\n    ? cleanImages\n    : product?.image\n    ? [product.image]\n    : [];\n\n  const nextImage = (e: React.MouseEvent) => {\n    e.preventDefault();\n    if (allImages.length > 1) {\n      setCurrentImageIndex((prev) => (prev + 1) % allImages.length);\n    }\n  };\n\n  const prevImage = (e: React.MouseEvent) => {\n    e.preventDefault();\n    if (allImages.length > 1) {\n      setCurrentImageIndex((prev) => (prev - 1 + allImages.length) % allImages.length);\n    }\n  };\n\n  const inquiryMessage = `Hi, I'm interested in: ${product.name} ($${product.price}) – is it available?`;\n\n  const buildChatLinks = () => {\n    const message = encodeURIComponent(inquiryMessage);\n    const links: { label: string; url: string; canPrefill: boolean }[] = [];\n    if (chat.whatsapp) {\n      links.push({\n        label: \"WhatsApp\",\n        url: `https://wa.me/${chat.whatsapp.replace(/[^0-9]/g, \"\")}?text=${message}`,\n        canPrefill: true,\n      });\n    }\n    if (chat.telegram) {\n      const username = chat.telegram.replace(\"@\", \"\");\n      links.push({\n        label: \"Telegram\",\n        url: `https://t.me/${username}?text=${message}`,\n        canPrefill: true,\n      });\n    }\n    if (chat.discord) {\n      links.push({ label: \"Discord\", url: chat.discord, canPrefill: false });\n    }\n    if (chat.viber) {\n      const cleanNumber = chat.viber.replace(/[^0-9]/g, \"\");\n      links.push({ label: \"Viber\", url: `viber://chat?number=${cleanNumber}`, canPrefill: false });\n    }\n    if (preferredChat) {\n      links.sort((a, b) => {\n        if (a.label.toLowerCase() === preferredChat.toLowerCase()) return -1;\n        if (b.label.toLowerCase() === preferredChat.toLowerCase()) return 1;\n        return 0;\n      });\n    }\n    return links;\n  };\n\n  const chatLinks = buildChatLinks();\n\n  const handleBookNow = () => {\n    if (chatLinks.length > 0) setModalOpen(true);\n  };\n\n  const handleCopyInquiry = () => {\n    navigator.clipboard.writeText(inquiryMessage);\n    setCopied(true);\n    setTimeout(() => setCopied(false), 2000);\n  };\n\n  const stats = ratingStats?.[product.id];\n  const averageRating = stats ? Math.round(stats.average * 10) / 10 : 0;\n  const reviewCount = stats?.count || 0;\n\n  return (\n    <>\n      <div className=\"group relative grid grid-rows-[auto_1fr_auto] bg-white border border-neutral-100 p-3 transition-all duration-500 hover:shadow-[0_20px_50px_rgba(0,0,0,0.05)] rounded-sm\">\n        {/* Image container with arrows + dots */}\n        <div className=\"relative aspect-square w-full bg-[#f4f4f4] overflow-hidden rounded-sm\">\n          {allImages.length > 0 ? (\n            <>\n              <Image\n                src={allImages[currentImageIndex]}\n                alt={product.name}\n                fill\n                className=\"object-cover transform transition-transform duration-[1.5s] ease-out group-hover:scale-110\"\n              />\n              {allImages.length > 1 && (\n                <>\n                  <button\n                    onClick={prevImage}\n                    className=\"absolute left-2 top-1/2 -translate-y-1/2 z-10 bg-white/80 rounded-full p-1 shadow hover:bg-white transition\"\n                  >\n                    <ChevronLeft className=\"w-4 h-4\" />\n                  </button>\n                  <button\n                    onClick={nextImage}\n                    className=\"absolute right-2 top-1/2 -translate-y-1/2 z-10 bg-white/80 rounded-full p-1 shadow hover:bg-white transition\"\n                  >\n                    <ChevronRight className=\"w-4 h-4\" />\n                  </button>\n                  <div className=\"absolute bottom-2 left-1/2 -translate-x-1/2 flex gap-1.5 z-10\">\n                    {allImages.map((_, idx) => (\n                      <span\n                        key={idx}\n                        className={`block w-2 h-2 rounded-full ${\n                          idx === currentImageIndex ? \"bg-black\" : \"bg-white/70\"\n                        }`}\n                      />\n                    ))}\n                  </div>\n                </>\n              )}\n            </>\n          ) : (\n            <div className=\"absolute inset-0 flex items-center justify-center text-neutral-400 transform transition-transform duration-[1.5s] ease-out group-hover:scale-110\">\n              <IconComponent className=\"w-10 h-10 md:w-12 md:h-12 stroke-[0.75]\" />\n            </div>\n          )}\n          {product.badge && (\n            <div className=\"absolute top-3 left-3 bg-black text-white px-2 py-0.5 text-[9px] uppercase tracking-widest font-medium z-10\">\n              {product.badge}\n            </div>\n          )}\n        </div>\n\n        {/* Text & rating */}\n        <div className=\"mt-4 md:mt-5 space-y-1 self-start\">\n          <div className=\"flex justify-between items-baseline gap-2\">\n            <h3 className=\"font-serif text-sm md:text-[14px] font-medium tracking-wider text-neutral-900 line-clamp-1\">\n              {product.name}\n            </h3>\n            <span className=\"text-xs md:text-[13px] font-medium text-neutral-600 font-sans\">\n              ${product.price}\n            </span>\n          </div>\n          <p className=\"text-[10px] md:text-[11px] tracking-wide text-neutral-400 font-light uppercase\">\n            {product.description}\n          </p>\n\n          {reviewCount > 0 ? (\n            <Link\n              href={`/product/${product.id}/reviews`}\n              className=\"inline-flex items-center gap-1 mt-1 text-[10px] md:text-[11px] text-neutral-500 hover:text-black transition\"\n            >\n              <span className=\"flex items-center text-yellow-500\">\n                {Array.from({ length: 5 }, (_, i) => (\n                  <Star\n                    key={i}\n                    className={`w-3 h-3 ${\n                      i < Math.round(averageRating)\n                        ? \"fill-current stroke-none\"\n                        : \"stroke-[1.5] fill-none text-neutral-300\"\n                    }`}\n                  />\n                ))}\n              </span>\n              <span className=\"text-neutral-500 font-medium ml-1\">\n                {averageRating.toFixed(1)} ({reviewCount})\n              </span>\n            </Link>\n          ) : (\n            <Link\n              href={`/product/${product.id}/reviews`}\n              className=\"inline-block mt-1 text-[10px] md:text-[11px] text-neutral-400 hover:text-black transition font-medium\"\n            >\n              Be the first to review\n            </Link>\n          )}\n        </div>\n\n        {/* Order via Chat button */}\n        <div className=\"mt-5 md:mt-6 pt-3 border-t border-neutral-100\">\n          <button\n            onClick={handleBookNow}\n            disabled={chatLinks.length === 0}\n            className=\"block w-full bg-black text-white text-[10px] md:text-[11px] uppercase tracking-[0.15em] font-medium py-3 md:py-3.5 hover:bg-neutral-800 transition-colors duration-300 text-center rounded-sm disabled:opacity-50 disabled:cursor-not-allowed\"\n          >\n            Order via Chat\n          </button>\n        </div>\n      </div>\n\n      {/* Chat modal (unchanged) */}\n      {modalOpen && (\n        <div className=\"fixed inset-0 z-50 bg-black/40 backdrop-blur-sm flex items-center justify-center p-4\">\n          <div className=\"bg-white max-w-sm w-full rounded-sm border border-neutral-200 shadow-xl p-6 space-y-4\">\n            <div className=\"flex items-center justify-between\">\n              <h3 className=\"font-serif text-sm font-medium tracking-wider uppercase\">Contact Us</h3>\n              <button onClick={() => setModalOpen(false)} className=\"text-neutral-400 hover:text-black\">\n                <X className=\"w-4 h-4\" />\n              </button>\n            </div>\n            <p className=\"text-[11px] text-neutral-500\">\n              Choose your preferred chat app to ask about this product:\n            </p>\n            <div className=\"space-y-2\">\n              {chatLinks.map((link) => (\n                <a\n                  key={link.label}\n                  href={link.url}\n                  target=\"_blank\"\n                  rel=\"noopener noreferrer\"\n                  className=\"flex items-center justify-between bg-[#f4f4f4] px-4 py-3 rounded-sm text-xs uppercase tracking-wider font-medium hover:bg-neutral-200 transition\"\n                >\n                  <span className=\"flex items-center gap-2\">\n                    <MessageCircle className=\"w-4 h-4\" />\n                    {link.label}\n                    {!link.canPrefill && (\n                      <span className=\"text-[9px] text-neutral-400 font-normal normal-case\">(no auto‑fill)</span>\n                    )}\n                  </span>\n                  <ExternalLink className=\"w-3 h-3\" />\n                </a>\n              ))}\n            </div>\n            <div className=\"pt-2 border-t border-neutral-100\">\n              <button\n                onClick={handleCopyInquiry}\n                className=\"flex items-center gap-2 text-[10px] uppercase tracking-wider text-neutral-500 hover:text-black transition font-medium\"\n              >\n                <Copy className=\"w-3 h-3\" />\n                {copied ? \"Copied!\" : \"Copy inquiry message\"}\n              </button>\n            </div>\n          </div>\n        </div>\n      )}\n    </>\n  );\n        }\n"}