// ----------------------------------------------------------------------------- // Immo-Ka — Agrégateur de propriétés à vendre (province de Québec) // Auteur : Simon-Pierre Boucher — contact@spboucher.ai // pages/Taux.tsx : /taux-hypothecaires — Mortgage Intelligence. // Vue marché (meilleur/médian/variations), comparateur par banque avec // nature du taux (affiché vs spécial) et fraîcheur, historique, taux // préférentiels, santé des sources. Aucun taux inventé : tout vient des // pages officielles des institutions, avec provenance. // ----------------------------------------------------------------------------- import { useEffect, useState } from "react"; import { MortgageBest, MortgageIntelligence, MortgageProviderHealth, fetchMortgageBest, fetchMortgageIntelligence, fetchMortgageProviders, fmtRate, } from "../api"; import TauxHistorique from "../components/TauxHistorique"; const TERMES: [number, string][] = [ [12, "1 an"], [24, "2 ans"], [36, "3 ans"], [48, "4 ans"], [60, "5 ans"], [84, "7 ans"], [120, "10 ans"], ]; const KIND_FR: Record = { posted: "affiché", special: "offre spéciale" }; const INSURED_FR: Record = { insured: "assuré", insurable: "assurable", uninsured: "non assuré", unknown: "", }; const termeLabel = (m: number) => TERMES.find(([t]) => t === m)?.[1] ?? `${m} mois`; const freshness = (min: number) => min < 60 ? `il y a ${min} min` : min < 48 * 60 ? `il y a ${Math.round(min / 60)} h` : `il y a ${Math.round(min / 1440)} j`; const varTxt = (v: number | null) => v == null ? "—" : v === 0 ? "stable" : `${v > 0 ? "▲ +" : "▼ "}${v.toFixed(2).replace(".", ",")} pt`; export default function TauxPage() { const [intel, setIntel] = useState(null); const [rateType, setRateType] = useState<"fixed" | "variable">("fixed"); const [term, setTerm] = useState(60); const [best, setBest] = useState(null); const [health, setHealth] = useState([]); useEffect(() => { document.title = "Taux hypothécaires au Canada — comparateur en direct | Immo-Ka"; fetchMortgageIntelligence().then(setIntel).catch(() => setIntel(null)); fetchMortgageProviders().then((r) => setHealth(r.providers)).catch(() => {}); }, []); useEffect(() => { setBest(null); fetchMortgageBest(rateType, term).then(setBest).catch(() => setBest(null)); }, [rateType, term]); return (

Taux hypothécaires en direct

Les taux réellement publiés par les grandes institutions canadiennes (banques, Desjardins, prêteurs virtuels et monolines), collectés en continu par Immo-Ka. Chaque taux indique sa nature (affiché ou offre spéciale), sa source officielle et sa fraîcheur — jamais de taux inventé ni périmé sans avertissement.

{intel && intel.products.length > 0 && (

Vue d'ensemble du marché

{intel.products.map((p) => ( ))}
{intel.prime_rates.length > 0 && (

Taux préférentiels :{" "} {intel.prime_rates.map((p, i) => ( {i > 0 && " · "} {p.institution} {fmtRate(p.rate)} ))}

)}
)}

Comparer les institutions

{best == null ? (

Aucun taux courant pour ce produit — essayez un autre terme.

) : ( <>
{best.per_institution.map((r, i) => ( ))}
InstitutionProduitTauxNatureFraîcheurSource
{r.institution}{i === 0 && meilleur} {r.product_name} {fmtRate(r.rate)}{r.apr != null ? ` (TAP ${fmtRate(r.apr)})` : ""} {KIND_FR[r.kind] ?? r.kind} {INSURED_FR[r.insured_status] ? ` · ${INSURED_FR[r.insured_status]}` : ""} {freshness(r.age_minutes)} {r.source_url && ( officielle ↗ )}

Un seul produit comparable par institution (l'offre spéciale prime sur le taux affiché). Les produits incomparables — assuré vs non assuré, affiché vs spécial — ne sont jamais mélangés dans un même classement sans l'indiquer.

)}

Évolution — {rateType === "fixed" ? "fixe" : "variable"} {termeLabel(term)}

{health.length > 0 && (

Fraîcheur des sources

{health.map((h) => ( {h.institution} ))}

Vert : collecte récente réussie · jaune : donnée conservée mais vieillissante · rouge : source en erreur. En cas d'échec d'une collecte, les derniers taux valides restent affichés avec leur date.

)}

Informations indicatives seulement, sans garantie — les conditions réelles dépendent de votre dossier. Immo-Ka n'est ni un prêteur ni un courtier hypothécaire.

); }