spb/food-ka Public
Food-Ka — agrégateur de produits d'épicerie du Québec — www.food-ka.com
Python 57.7%
TypeScript 24.9%
CSS 16.7%
HTML 0.6%
1// -----------------------------------------------------------------------------2// Food-Ka — Agrégateur de produits d'épicerie (province de Québec)3// Auteur : Simon-Pierre Boucher — contact@spboucher.ai4// components/ProductCard.tsx : carte produit (grille de résultats)5// Prix courant + prix régulier barré et badge « -XX % » quand en solde,6// prix unitaire comparable, bannière d'origine.7// -----------------------------------------------------------------------------8import { Link } from "react-router-dom";9import { Product, discountPct, fmtPrice } from "../api";10import SourceLogo from "./SourceLogo";1112export default function ProductCard({ p }: { p: Product }) {13 const img = p.images && p.images.length > 0 ? p.images[0] : null;14 const pct = discountPct(p);15 return (16 <Link to={`/produit/${encodeURIComponent(p.uid)}`} className="card">17 <div className="card-img packshot">18 {img ? (19 <img src={img} alt={p.name} loading="lazy" />20 ) : (21 <div className="noimg">🛒</div>22 )}23 {p.on_sale && (24 <span className="badge sale">{pct != null ? `−${pct} %` : "En solde"}</span>25 )}26 {p.in_stock === false && <span className="badge right">Rupture</span>}27 </div>28 <div className="card-body">29 <div className="card-price">30 {fmtPrice(p.price, p.price_label)}31 {p.on_sale && p.regular_price != null && (32 <s className="price-old">{fmtPrice(p.regular_price)}</s>33 )}34 </div>35 {p.unit_price_label && (36 <div className="card-unit">{p.unit_price_label}</div>37 )}38 <div className="card-title">{p.name}</div>39 <div className="card-meta">40 {p.brand && <span>{p.brand}</span>}41 {p.brand && p.size_label && <span className="sep" />}42 {p.size_label && <span>{p.size_label}</span>}43 </div>44 <div className="card-foot">45 <SourceLogo source={p.source} size={20} name="short" />46 {p.category && <span className="avail">{p.category}</span>}47 </div>48 </div>49 </Link>50 );51}52