'use client'; import React, { useState } from 'react'; import Link from 'next/link'; import { useShopifyCart } from '@/hooks/use-shopify-cart'; import { truncate } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Loader } from '@/app/components/ui/loader'; interface ProductImage { url: string; altText?: string; } interface ProductPrice { amount: string; currencyCode: string; } interface ProductVariant { id: string; title: string; price: ProductPrice; availableForSale: boolean; } interface Product { id: string; title: string; description?: string; handle: string; images: { edges: Array<{ node: ProductImage; }>; }; priceRange: { minVariantPrice: ProductPrice; }; compareAtPriceRange?: { minVariantPrice: ProductPrice; }; variants: { edges: Array<{ node: ProductVariant; }>; }; } interface ProductCardProps { product: Product; onAddToCart?: (product: Product) => void; } const ProductCard: React.FC = ({ product, onAddToCart }) => { const { addItem, openCart } = useShopifyCart(); const [isAdding, setIsAdding] = useState(false); const firstImage = product.images.edges[0]?.node; const price = product.priceRange.minVariantPrice; const compareAtPrice = product.compareAtPriceRange?.minVariantPrice; const hasDiscount = compareAtPrice && parseFloat(compareAtPrice.amount) > parseFloat(price.amount); const firstVariant = product.variants.edges[0]?.node; const isAvailable = firstVariant?.availableForSale || false; const formatPrice = (amount: string) => { return `$${parseFloat(amount).toFixed(2)}`; }; const handleAddToCart = async (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); if (!firstVariant || !isAvailable || isAdding) return; try { setIsAdding(true); await addItem(firstVariant.id, 1); openCart(); if (onAddToCart) onAddToCart(product); } catch (err) { console.error('Failed to add item to cart:', err); } finally { setIsAdding(false); } }; return (
{/* Product Image */}
{firstImage ? ( {firstImage.altText ) : (
)} {/* Badges */} {hasDiscount && compareAtPrice && ( SALE )} {!isAvailable && (
SOLD OUT
)}
{/* Product Info */}

{truncate(product.title, 65)}

{formatPrice(price.amount)} {hasDiscount && compareAtPrice && ( {formatPrice(compareAtPrice.amount)} )}
{isAvailable && ( )}
); }; export default ProductCard;