// --------------------------------------------------------------------------- // Fabri-Ka — Agrégateur de produits fabriqués au Québec // Auteur : Simon-Pierre Boucher — contact@spboucher.ai // fiche/ContextCards.tsx : « La boutique » (logo, lieu, origine, liens), // « Aussi chez la boutique » (cartes produit), « Dossier de la fiche », // « Sources et méthodologie ». // --------------------------------------------------------------------------- import { Link } from 'react-router-dom' import { CATEGORY_LABELS, ProductDetail, categorySlug, formatRelativeDate, hostnameOf } from '../api' import { Ico } from '../components/KaIcons' import OriginBadge from '../components/OriginBadge' import ProductCard from '../components/ProductCard' import StoreLogo from '../components/StoreLogo' import { Accordion, SectionCard } from './ui' import { origineLabel } from './synthese' export function StoreCard({ p }: { p: ProductDetail }) { return ( }>
{p.store_name}
{[p.store_city, p.store_region].filter(Boolean).join(', ') || 'Québec'}
Tous ses produits {p.store_url && {hostnameOf(p.store_url)} }

{origineLabel(p)} — classe d'origine attribuée par Fabri-Ka à la boutique d'après ses pages « à propos », ses certifications et ses mentions de fabrication ; elle s'applique à l'ensemble de la boutique, pas à ce produit en particulier.

) } export function RelatedCard({ p }: { p: ProductDetail }) { if (!p.related || p.related.length === 0) return null return ( }>
{p.related.slice(0, 6).map((x) => )}
{p.category && (

Voir toute la catégorie {CATEGORY_LABELS[p.category] ?? p.category} →

)}
) } export function Dossier({ p }: { p: ProductDetail }) { const det = p.details ?? {} return ( } sub="Ce que Fabri-Ka observe réellement : boutique, suivi, identifiants"> Suivi Fabri-Ka} meta={p.listing_status === 'published' ? 'publié' : p.listing_status || undefined}>
{det.created_at &&
Créé par la boutique{new Date(det.created_at).toLocaleDateString('fr-CA')}
} {det.updated_at &&
Modifié par la boutique{formatRelativeDate(det.updated_at) ?? det.updated_at}
}
Statut{p.available ? 'Disponible' : 'Non disponible'}{p.listing_status && p.listing_status !== 'published' ? ` · ${p.listing_status}` : ''}

Synchronisé plusieurs fois par jour depuis la boutique ; les dates ci-dessus sont celles publiées par la plateforme marchande.

Identifiants} meta={det.sku || p.uid.slice(0, 8)}>
{det.sku &&
SKU{det.sku}
} {det.gtin &&
GTIN / MPN{det.gtin}
}
Identifiant Fabri-Ka{p.uid}
Fiche originale{hostnameOf(p.url)} ↗
) } export function Sources({ p, onShare }: { p: ProductDetail; onShare: () => void }) { const srcs = [ { n: p.store_name, r: 'Titre, prix, images, options, description et disponibilité (source originale)', href: p.url }, { n: 'Fabri-Ka', r: 'Classe d\'origine de la boutique, catégorie canonique, déduplication — calculs maison, indicatifs' }, ] return ( } sub="Chaque donnée de cette fiche renvoie à sa source ; les calculs Fabri-Ka sont indicatifs et documentés">
Boutiques d'iciToutes les boutiques Fabri-Ka Signaler une erreurPrix, image, origine… Classes d'origineA · B · C · D · E expliquées

Les prix et disponibilités sont ceux affichés par la boutique — chaque fiche renvoie à la page produit originale. Fabri-Ka est un agrégateur indépendant.

) }