// ----------------------------------------------------------------------------- // Immo-Ka — Agrégateur de propriétés à vendre (province de Québec) // Auteur : Simon-Pierre Boucher — contact@spboucher.ai // fiche/MarketPriceCard.tsx : « Prix et marché » — estimation Vrai-Prix // (valeur, fourchette, confiance) avec jauge SVG (fourchette, estimation, // prix demandé), écart en %, prix au pi², rôle d'évaluation foncière // (terrain + bâtiment, année, écart), historique du prix demandé observé par // Immo-Ka et temps sur le marché, méthodologie en accordéon. Toutes les // données arrivent avec l'annonce : aucun chargement différé. // ----------------------------------------------------------------------------- import { Listing, fmtDate, fmtPrice } from "../api"; import { Ico } from "../components/Icons"; import { PriceCapsule } from "./PropertyHero"; import { ComparaisonPrix, estLocation, evaluationMunicipale } from "./synthese"; import { Accordion, SectionCard, StatTile, NBSP } from "./ui"; const CONF: Record = { A: "Confiance élevée", B: "Confiance bonne", C: "Confiance moyenne", D: "Estimation indicative" }; function Gauge({ lo, hi, est, ask }: { lo: number; hi: number; est: number; ask: number | null }) { const W = 320, H = 54; const min = Math.min(lo, ask ?? lo) * 0.97, max = Math.max(hi, ask ?? hi) * 1.03; const x = (v: number) => 8 + ((Math.min(Math.max(v, min), max) - min) / (max - min)) * (W - 16); const anchor = (px: number) => (px < 56 ? "start" : px > W - 56 ? "end" : "middle"); return (
estimation {fmtPrice(est)} {ask != null && ( <> prix demandé {fmtPrice(ask)} )}
{fmtPrice(lo)}{fmtPrice(hi)}
); } export default function MarketPriceCard({ l, cmp }: { l: Listing; cmp: ComparaisonPrix | null }) { if (l.price == null) return null; const location = estLocation(l); const vp = l.vraiprix && l.vraiprix.value != null && !location ? l.vraiprix : null; const ev = evaluationMunicipale(l); const hist = (l.price_history ?? []).filter((h) => h.price != null); const pi2 = l.area_sqft != null && l.area_sqft > 200 && !location ? Math.round(l.price / l.area_sqft) : null; const evPct = ev && !location ? Math.round(((l.price - ev.total) / ev.total) * 100) : null; const jours = l.days_on_market ?? null; return ( } aside={cmp && }> {vp ? ( <>
{vp.low != null && vp.high != null && vp.high > vp.low && ( )} {!cmp && (

Prix demandé trop éloigné de l'estimation pour être comparé (type de bien ou annonce atypique).

)}
{(vp.confidence && CONF[vp.confidence]) || "Estimation automatisée"}{vp.confidence ? ` (${vp.confidence})` : ""} {pi2 != null && {pi2.toLocaleString("fr-CA")}{NBSP}$ par pi² habitable} {jours != null && jours > 0 && {jours} jour{jours > 1 ? "s" : ""} sur le marché (observé)}
) : ( <>
{pi2 != null && } {jours != null && jours > 0 && }
{!location &&

Pas d'estimation Vrai-Prix pour cette annonce (adresse non appariée au rôle ou type de bien non couvert).

} )} {ev && !location && (

Rôle d'évaluation foncière{ev.annee ? ` · ${ev.annee}` : ""}

{ev.terrain != null && } {ev.batiment != null && }
{evPct != null && Math.abs(evPct) <= 300 && (

Prix demandé {Math.abs(evPct)}{NBSP}% {evPct >= 0 ? "au-dessus" : "sous"} l'évaluation municipale — le rôle triennal reflète la valeur au 1ᵉʳ juillet de l'année de référence, pas le marché actuel.

)}
)} {hist.length >= 2 && ( <>

Historique du prix demandé

    {hist.slice(0, 6).map((h, i) => { const prev = hist[i + 1]; const cls = prev && prev.price != null ? (h.price! < prev.price ? "baisse" : "hausse") : ""; return (
  • {fmtDate(h.ts)} {prev && prev.price != null ? <>{h.price! < prev.price ? "Baissé" : "Monté"} de {fmtPrice(prev.price)} à {fmtPrice(h.price!)} : <>Premier prix observé : {fmtPrice(h.price!)}}
  • ); })}
)}

L'estimation Vrai-Prix (service Groupe KA) est produite par un modèle statistique fondé sur les ventes comparables récentes, les caractéristiques du bien et le rôle d'évaluation foncière ; la fourchette exprime l'incertitude du modèle et la lettre de confiance (A à D) sa fiabilité. Ce n'est pas une évaluation agréée. L'historique de prix et le temps sur le marché sont ceux observés par les synchronisations Immo-Ka (première observation, pas la date d'inscription à la source). {vp && <> Analyse détaillée sur Vrai-Prix ↗}

); }