// ----------------------------------------------------------------------------- // Immo-Ka — Agrégateur de propriétés à vendre (province de Québec) // Auteur : Simon-Pierre Boucher — contact@spboucher.ai // fiche/PropertyDossier.tsx : « Dossier de l'annonce » — ce qu'Immo-Ka observe // réellement, en accordéons compacts : suivi Immo-Ka (première observation, // jours en ligne, variations de prix), autres publications de la même // propriété (doublons rattachés par la déduplication), courtier et agence, // identifiants de la source. Chaque volet a un état vide propre. // ----------------------------------------------------------------------------- import { Listing, fmtDate, fmtPrice, sourceName } from "../api"; import { Ico } from "../components/Icons"; import { Accordion, SectionCard, StatTile, StatusBadge, NBSP } from "./ui"; function Vide({ children }: { children: React.ReactNode }) { return

{children}

; } export default function PropertyDossier({ l }: { l: Listing }) { const hist = (l.price_history ?? []).filter((h) => h.price != null); const jours = l.days_on_market ?? (l.first_seen ? Math.max(0, Math.round((Date.now() / 1000 - l.first_seen) / 86400)) : null); const variation = hist.length >= 2 ? (hist[0].price! - hist[hist.length - 1].price!) / hist[hist.length - 1].price! : null; const dups = l.duplicates ?? []; const d = l.details ?? {}; const listedAt = typeof d.listed_at === "string" ? d.listed_at : null; const origin = typeof d.listing_origin_url === "string" ? d.listing_origin_url : null; return ( } sub="Ce qu'Immo-Ka observe réellement : suivi, publications, courtier, source"> Suivi Immo-Ka} meta={jours != null ? (jours === 0 ? "publiée aujourd'hui" : `${jours}${NBSP}j en ligne`) : undefined}>
{variation != null && variation !== 0 && (

Prix initial observé {fmtPrice(hist[hist.length - 1].price!)} → {fmtPrice(hist[0].price!)}{" "} {variation > 0 ? "+" : "−"}{Math.abs(Math.round(variation * 100))}{NBSP}%

)} {listedAt &&

Date d'inscription indiquée par la source : {listedAt}.

}

Première observation, jours en ligne et variations sont mesurés par les synchronisations Immo-Ka (plusieurs fois par jour) — ils ne remplacent pas la date d'inscription officielle Centris.

Aussi publiée sur} meta={dups.length ? `${dups.length} plateforme${dups.length > 1 ? "s" : ""}` : "aucune"}> {dups.length === 0 ? ( Aucune autre publication de cette propriété repérée parmi les sources Immo-Ka. ) : ( <>

Cette propriété a été repérée sur {dups.length} autre{dups.length > 1 ? "s" : ""} plateforme{dups.length > 1 ? "s" : ""} — Immo-Ka affiche la version la plus complète.

    {dups.map((x) => (
  • {sourceName(x.source)}
    {x.broker_name || x.agency || x.price_label || ""}
  • ))}
)}
Courtier et agence} meta={l.broker_name || sourceName(l.source)}>

{l.broker_name || "Courtier non précisé"} {l.agency ? <> — {l.agency} : null}

Annonce publiée par {sourceName(l.source)} {l.broker_phone && <> · {l.broker_phone}}.

Immo-Ka est un agrégateur indépendant : la relation contractuelle se fait avec le courtier ou l'agence de l'annonce originale. Consultez le registre de l'OACIQ pour vérifier un permis de courtier.

Identifiants et source} meta={l.mls || l.external_id}>
{l.mls &&
Nº Centris / MLS{l.mls}
}
Identifiant source{l.external_id}
Identifiant Immo-Ka{l.uid}
Annonce originale{sourceName(l.source)} ↗
{origin && origin !== l.url &&
Fiche d'origineOuvrir ↗
}
); }