chore: initial import
This commit is contained in:
52
frontend/components/ProductCard.js
Normal file
52
frontend/components/ProductCard.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { useCart } from '../context/CartContext';
|
||||
|
||||
const FALLBACK_IMAGE =
|
||||
'https://images.unsplash.com/photo-1608198093002-ad4e005484ec?auto=format&fit=crop&w=1200&q=80';
|
||||
|
||||
export default function ProductCard({ product }) {
|
||||
const { addItem } = useCart();
|
||||
|
||||
const imageUrl = product?.imageUrl || product?.hero_image || FALLBACK_IMAGE;
|
||||
const price = Number(product?.price || 0).toFixed(2);
|
||||
const canPurchase = Boolean(product?.id) && !product?.isSample;
|
||||
const hasDetail = Boolean(product?.slug) && !product?.isSample;
|
||||
|
||||
return (
|
||||
<article className="product-card">
|
||||
<div className="product-card__image">
|
||||
<img src={imageUrl} alt={product?.name || 'Bakehouse item'} loading="lazy" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>{product?.name || 'Menu item'}</h3>
|
||||
{product?.short_description ? <p>{product.short_description}</p> : null}
|
||||
</div>
|
||||
|
||||
<div className="product-card__meta">
|
||||
<span>${price}</span>
|
||||
<span>{product?.inventory_quantity ?? '—'} available</span>
|
||||
</div>
|
||||
|
||||
<div className="product-card__tags">
|
||||
<span>Max {product?.max_per_order ?? '—'} / order</span>
|
||||
{product?.allergens ? <span>{product.allergens}</span> : null}
|
||||
</div>
|
||||
|
||||
<div className="product-card__actions">
|
||||
{canPurchase ? (
|
||||
<button type="button" className="btn btn-outline" onClick={() => addItem(product)}>
|
||||
Add to cart
|
||||
</button>
|
||||
) : (
|
||||
<span className="sample-tag">Sample listing</span>
|
||||
)}
|
||||
|
||||
{hasDetail ? (
|
||||
<Link href={`/products/${product.slug}`}>View details</Link>
|
||||
) : null}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user