SPB Git

spb/fabri-ka Public

Agrégateur de produits québécois — www.fabri-ka.com

HTML 57% Python 19.9% TypeScript 15.3% CSS 7.7%
1.9 KB · 59 lines tsx
Raw Blame History
1import { useState } from 'react'2import { Link } from 'react-router-dom'3import { formatPrice, Product } from '../api'4import { IconLeaf } from './Icons'5import OriginBadge from './OriginBadge'67export default function ProductCard({ product }: { product: Product }) {8  const [imageFailed, setImageFailed] = useState(false)9  const image = product.images.length > 0 ? product.images[0] : null10  const showImage = image !== null && !imageFailed1112  return (13    <Link14      to={`/produits/${encodeURIComponent(product.uid)}`}15      className="card product-card"16    >17      <div className="product-card-media">18        {showImage ? (19          <img20            src={image}21            alt={product.title}22            loading="lazy"23            decoding="async"24            onError={() => setImageFailed(true)}25          />26        ) : (27          <div className="image-placeholder" aria-hidden="true">28            <IconLeaf size={30} />29          </div>30        )}31        <span className="product-card-badge">32          <OriginBadge origin={product.origin_class} />33        </span>34      </div>35      <div className="product-card-body">36        <h3 className="product-card-title">{product.title}</h3>37        <div className="product-card-price">38          {product.price !== null ? (39            <span className="price-chip">{formatPrice(product.price)}</span>40          ) : (41            <span className="price-chip price-chip-muted">Prix variable</span>42          )}43          {product.compare_at_price !== null &&44            product.price !== null &&45            product.compare_at_price > product.price && (46              <s className="price-compare">47                {formatPrice(product.compare_at_price)}48              </s>49            )}50        </div>51        <p className="product-card-store">52          {product.store_name}53          {product.store_region ? ` · ${product.store_region}` : ''}54        </p>55      </div>56    </Link>57  )58}59