import React from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { ShoppingCart, Heart } from 'lucide-react';
import { formatPrice, formatDiscount } from '@/lib/currency';
import { Button } from './ui/button';
import { useShopSettings } from '@/hooks/useAppearanceSettings';
import { useWishlist } from '@/hooks/useWishlist';
import { useModules } from '@/hooks/useModules';
interface ProductCardProps {
product: {
id: number;
name: string;
slug: string;
price: string;
regular_price?: string;
sale_price?: string;
image?: string;
on_sale?: boolean;
stock_status?: string;
type?: string;
};
onAddToCart?: (product: any) => void;
}
export function ProductCard({ product, onAddToCart }: ProductCardProps) {
const navigate = useNavigate();
const { layout, elements, addToCart, saleBadge, isLoading } = useShopSettings();
const { isEnabled: wishlistEnabled, isInWishlist, toggleWishlist } = useWishlist();
const { isEnabled: isModuleEnabled } = useModules();
const showWishlist = isModuleEnabled('wishlist') && wishlistEnabled;
const inWishlist = showWishlist && isInWishlist(product.id);
const handleWishlistClick = async (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
await toggleWishlist(product.id);
};
// Aspect ratio classes
const aspectRatioClass = {
'square': 'aspect-square',
'portrait': 'aspect-[3/4]',
'landscape': 'aspect-[4/3]',
}[layout.aspect_ratio] || 'aspect-square';
const isVariable = product.type === 'variable';
const handleAddToCart = (e: React.MouseEvent) => {
e.preventDefault();
e.stopPropagation();
// Variable products need to go to product page for attribute selection
if (isVariable) {
navigate(`/product/${product.slug}`);
return;
}
onAddToCart?.(product);
};
// Calculate discount if on sale
const discount = product.on_sale && product.regular_price && product.sale_price
? formatDiscount(parseFloat(product.regular_price), parseFloat(product.sale_price))
: null;
// Show skeleton while settings are loading to prevent layout shift
if (isLoading) {
return (
);
}
// Determine button variant and position based on settings
const buttonVariant = addToCart.style === 'outline' ? 'outline' : addToCart.style === 'text' ? 'ghost' : 'default';
const showButtonOnHover = addToCart.position === 'overlay';
const isTextOnly = addToCart.style === 'text';
// Card style variations - adapt to column count
const gridCols = parseInt(layout.grid_columns) || 3;
// More columns = cleaner styling
const getCardClasses = () => {
const cardStyle = layout.card_style || 'card';
if (cardStyle === 'minimal') {
return gridCols >= 4
? 'overflow-hidden hover:opacity-90 transition-opacity'
: 'overflow-hidden hover:opacity-80 transition-opacity border-b border-border pb-4';
}
if (cardStyle === 'overlay') {
return gridCols >= 4
? 'relative overflow-hidden group-hover:shadow-lg transition-all rounded-md'
: 'relative overflow-hidden group-hover:shadow-xl transition-all rounded-lg bg-card';
}
// Default 'card' style
return gridCols >= 4
? 'border border-border rounded-md overflow-hidden hover:shadow-md transition-shadow bg-card'
: 'border border-border rounded-lg overflow-hidden hover:shadow-lg transition-shadow bg-card';
};
const cardClasses = getCardClasses();
// Text alignment class
const textAlignClass = {
'left': 'text-left',
'center': 'text-center',
'right': 'text-right',
}[layout.card_text_align || 'left'] || 'text-left';
// Unified card render — adapts via card_style (card / minimal / overlay) + shop settings
return (
{/* Image */}
{product.image ? (

) : (
No Image
)}
{/* Sale Badge */}
{elements.sale_badges && product.on_sale && discount && (
{discount}
)}
{/* Wishlist Button */}
{showWishlist && (
)}
{/* Hover/Overlay Button */}
{showButtonOnHover && (
)}
{/* Content */}
{product.name}
{/* Price */}
{product.on_sale && product.regular_price ? (
<>
{formatPrice(product.sale_price || product.price)}
{formatPrice(product.regular_price)}
>
) : (
{formatPrice(product.price)}
)}
{/* Add to Cart Button */}
{!showButtonOnHover && (
)}
);
}