// Auteur : Simon-Pierre Boucher — contact@spboucher.ai /** * /stats — bandeau « LE CHIFFRE » (valeur totale du parc immobilier * québécois, comparaisons vulgarisées). Les sections analytiques * (KPI, jauges, séries, répartitions, tableaux, records, rapports PDF) * sont servies par — module Stats commun Groupe KA v2. */ "use client"; import { CountUp } from "./MetricViz"; import { useLang } from "./LangContext"; export interface ProvStats { generated: string; unites: number; valeur_totale_2026: number; valeur_role_totale: number; valeur_mediane_2026: number; croissance_2021_2026_pct: number; logements: number; aire_etages_km2: number; terrain_km2: number; municipalites: number; totaux_annee: { year: number; total: number; n: number }[]; par_type: { type: string; n: number; total: number; mediane: number | null }[]; par_ville: { ville: string; n: number; total: number; mediane: number | null }[]; } const POP_QC = 9_111_000; // population du Québec (2026, ISQ) const BUDGET_QC = 165_800_000_000; // dépenses budget QC 2026-2027 (approx.) const PIB_QC = 640_000_000_000; // PIB nominal QC (approx. 2025) const money = (v: number, lang: string, frac = 0) => new Intl.NumberFormat(lang === "fr" ? "fr-CA" : "en-CA", { style: "currency", currency: "CAD", maximumFractionDigits: frac, }).format(v); const compact = (v: number, lang: string) => { const fr = lang === "fr"; if (v >= 1e12) return `${(v / 1e12).toLocaleString(fr ? "fr-CA" : "en-CA", { maximumFractionDigits: 2 })} ${fr ? "billions $" : "T$"}`; if (v >= 1e9) return `${(v / 1e9).toLocaleString(fr ? "fr-CA" : "en-CA", { maximumFractionDigits: 1 })} G$`; if (v >= 1e6) return `${(v / 1e6).toLocaleString(fr ? "fr-CA" : "en-CA", { maximumFractionDigits: 1 })} M$`; return money(v, lang); }; const num = (v: number, lang: string) => v.toLocaleString(lang === "fr" ? "fr-CA" : "en-CA"); export default function StatsView({ s }: { s: ProvStats }) { const { lang } = useLang(); const fr = lang === "fr"; return (
{/* ---- LE CHIFFRE ---- */}
{fr ? "Juste pour le show" : "Just for the show"}

{fr ? ( <> Tout l'immobilier du Québec vaut,
au dollar près… ) : ( <> All Québec real estate is worth,
to the dollar… )}

money(v, lang)} />

{fr ? `≈ ${compact(s.valeur_totale_2026, lang)} · ${num(s.unites, lang)} propriétés · ${num(s.municipalites, lang)} municipalités · millésime 2026` : `≈ ${compact(s.valeur_totale_2026, lang)} · ${num(s.unites, lang)} properties · ${num(s.municipalites, lang)} municipalities · 2026 vintage`}

{( [ [fr ? "par Québécois·e" : "per Quebecer", money(s.valeur_totale_2026 / POP_QC, lang)], [fr ? "budgets annuels du Québec" : "annual Québec budgets", `× ${(s.valeur_totale_2026 / BUDGET_QC).toFixed(1)}`], [fr ? "fois le PIB du Québec" : "× Québec GDP", `× ${(s.valeur_totale_2026 / PIB_QC).toFixed(1)}`], [fr ? "depuis 2021 (périmètre constant)" : "since 2021 (constant perimeter)", `+${s.croissance_2021_2026_pct.toLocaleString(fr ? "fr-CA" : "en-CA")} %`], ] as [string, string][] ).map(([k, v]) => ( {v} {k} ))}

{fr ? "Somme des 3 747 008 estimations Vrai-Prix (modèle hédonique, rôle 2026). Évaluation municipale totale correspondante : " : "Sum of 3,747,008 Vrai-Prix estimates (hedonic model, 2026 roll). Corresponding total municipal assessment: "} {compact(s.valeur_role_totale, lang)}.

); }