// ----------------------------------------------------------------------------- // Auto-Ka — Agrégateur de voitures usagées à vendre (province de Québec) // Auteur : Simon-Pierre Boucher — contact@spboucher.ai // fiche/ContextCards.tsx : cartes de contexte — // · RecallsCard : rappels Transports Canada (3 visibles + « Voir les N ») ; // · OffersCard : le même véhicule (même NIV) chez d'autres sources ; // · LocationCard : carte OpenStreetMap (position approximative du vendeur) ; // · SimilarCard : véhicules similaires (cartes de la grille) ; // · Dossier : suivi Auto-Ka, concessionnaire, identifiants ; // · Sources : sources et méthodologie + rangée d'actions. // ----------------------------------------------------------------------------- import { useMemo, useState } from "react"; import { Recall, VehicleDetail, fmtDate, fmtPrice, sourceName } from "../api"; import { Ico } from "../components/Icons"; import VehicleCard from "../components/VehicleCard"; import { Accordion, ErrorState, MoreButton, SectionCard, SkeletonLines, SourceLine, StatTile, StatusBadge, relTime } from "./ui"; import { Res } from "./useFicheData"; export function RecallsCard({ v, r, onRetry }: { v: VehicleDetail; r: Res; onRetry: () => void }) { const [all, setAll] = useState(false); if (r.status === "na" || r.status === "idle") return null; const items = r.status === "ok" ? r.data : null; return ( } aside={items && {items.length ? `${items.length} rappel${items.length > 1 ? "s" : ""}` : "Aucun rappel"}}> {r.status === "loading" && } {r.status === "error" && Base des rappels temporairement indisponible.} {items && items.length === 0 &&

Aucun rappel de sécurité répertorié pour {v.make} {v.model}{v.year ? ` ${v.year}` : ""}.

} {items && items.length > 0 && ( <>

Rappels visant {v.make} {v.model}{v.year ? ` ${v.year}` : ""} — un rappel concerne le modèle, pas forcément cet exemplaire ; vérifiez auprès du concessionnaire qu'ils ont été effectués.

{(all ? items : items.slice(0, 3)).map((x) => ( {x.date}{x.component}}>

{x.description}

Rappel nº {x.recall_number}{x.units_affected ? ` · ${x.units_affected.toLocaleString("fr-CA")} unités visées` : ""}

))} {items.length > 3 && setAll(!all)} expanded={all}>{all ? "Réduire" : `Voir les ${items.length} rappels`}} )}
); } export function OffersCard({ v }: { v: VehicleDetail }) { const offers = v.dup_sources ?? []; if (offers.length === 0) return null; return ( } sub={`Même NIV repéré sur ${offers.length} autre${offers.length > 1 ? "s" : ""} site${offers.length > 1 ? "s" : ""} (dédoublonnage Auto-Ka)`}> ); } export function LocationCard({ v }: { v: VehicleDetail }) { const src = useMemo(() => { if (v.lat == null || v.lng == null) return null; const d = 0.02; const bbox = [v.lng - d, v.lat - d, v.lng + d, v.lat + d].join(","); return `https://www.openstreetmap.org/export/embed.html?bbox=${bbox}&layer=mapnik&marker=${v.lat},${v.lng}`; }, [v.lat, v.lng]); if (!src) return null; return ( } sub={`${[v.dealer_name, v.city, v.region].filter(Boolean).join(" · ")} — position approximative (ville du vendeur)`}>