// -----------------------------------------------------------------------------
// Auto-Ka — Agrégateur de voitures usagées à vendre (province de Québec)
// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
// fiche/MarketCard.tsx : « Prix et marché » — KPI (prix demandé, médiane des
// comparables, fourchette 25–75 %), jauge de position (percentile), nuage
// prix / kilométrage des comparables (ce véhicule en orange), PDSF d'origine
// si connu, historique du prix demandé, méthodologie.
// -----------------------------------------------------------------------------
import { MarketAnalysis, VehicleDetail, fmtDate, fmtPrice } from "../api";
import { Ico } from "../components/Icons";
import { ComparaisonPrix } from "./synthese";
import { PriceCapsule } from "./VehicleHero";
import { Accordion, SectionCard, StatTile, NBSP } from "./ui";
function Scatter({ m, price, km }: { m: MarketAnalysis; price: number; km: number | null }) {
const pts = m.points;
if (pts.length < 5) return null;
const W = 520, H = 220, PAD = { t: 16, r: 14, b: 28, l: 52 };
const kms = pts.map((d) => d.km).concat(km != null ? [km] : []);
const ps = pts.map((d) => d.p).concat([price]);
const kMin = Math.min(...kms), kMax = Math.max(...kms), pMin = Math.min(...ps), pMax = Math.max(...ps);
const x = (v: number) => PAD.l + (kMax > kMin ? (v - kMin) / (kMax - kMin) : 0.5) * (W - PAD.l - PAD.r);
const y = (v: number) => H - PAD.b - (pMax > pMin ? (v - pMin) / (pMax - pMin) : 0.5) * (H - PAD.t - PAD.b);
const fmtK = (v: number) => `${Math.round(v / 1000)} k`;
return (
);
}
export default function MarketCard({ v, cmp }: { v: VehicleDetail; cmp: ComparaisonPrix | null }) {
if (v.price == null) return null;
const m = v.market;
const hist = (v.price_history ?? []).filter((h) => h.price != null);
const msrp = typeof v.details?.msrp === "number" ? (v.details.msrp as number) : null;
const jours = v.first_seen ? Math.max(0, Math.round((Date.now() / 1000 - v.first_seen) / 86400)) : null;
return (
Pas assez de {v.make} {v.model.split(" ")[0]} comparables en vente pour situer ce prix.
> )} {hist.length >= 2 && ( <>Comparables = véhicules de même marque et modèle, année ±1, en vente au Québec dans les sources Auto-Ka, doublons (même NIV) exclus. La médiane et la fourchette 25–75 % sont recalculées à chaque affichage ; le percentile indique la part des comparables affichés moins cher. L'état du véhicule, les options et l'historique d'entretien ne sont pas pris en compte : c'est un repère, pas une évaluation. Le PDSF provient de la fiche constructeur quand il est connu.