// UQO Éval — mode étudiant : l'analyse pédagogique complète d'une estimation. /** * Décompose le résultat du moteur (engine.ts) SANS inventer de calcul : * chaque chiffre affiché est recomposé à partir des mêmes règles que le * moteur (sélection des comparables, gaussiennes de pondération, ajustements, * combinaison 65/35, score de confiance) appliquées aux données du résultat. */ "use client"; import { useLang } from "./LangContext"; import type { EstimateResult } from "@/lib/engine"; const money = (v: number, lang: string) => new Intl.NumberFormat(lang === "fr" ? "fr-CA" : "en-CA", { style: "currency", currency: "CAD", maximumFractionDigits: 0, }).format(Math.round(v)); /** Reconstruit la décomposition du score de confiance (mêmes règles que engine.ts). */ function confidenceParts(r: EstimateResult) { const base = 35; const comps = Math.min(25, r.comps.length * 2.5); const disp = r.compsDispersionPct != null ? Math.max(0, 20 - r.compsDispersionPct) : 0; const model = r.modelEstimate != null ? 15 : 0; const widthPct = r.estimate > 0 ? ((r.high - r.low) / r.estimate) * 100 : 100; const width = -Math.max(0, (widthPct - 30) / 3); return { base, comps, disp, model, width, widthPct }; } function Formula({ children }: { children: React.ReactNode }) { return (
{children}
); } function Block({ title, children, }: { title: string; children: React.ReactNode; }) { return ({t("pedIntro")}
{t("pedWhyComps")}
{fr ? `Ici : ${r.nCompsUsed} comparables retenus${r.compsDispersionPct != null ? ` · dispersion médiane ±${r.compsDispersionPct} %` : ""}` : `Here: ${r.nCompsUsed} comparables kept${r.compsDispersionPct != null ? ` · median dispersion ±${r.compsDispersionPct}%` : ""}`}
{t("pedWeight")}
{t("pedBlend")}
{/* barre de combinaison réelle */}{t("modelPart")} :{" "} {r.modelEstimate != null ? money(r.modelEstimate, lang) : "—"} {t("compsPart")} :{" "} {r.compsEstimate != null ? money(r.compsEstimate, lang) : "—"}
{fr ? "Niveaux : A ≥ 75 · B ≥ 60 · C ≥ 45 · D < 45 (borné à 5-97)" : "Levels: A ≥ 75 · B ≥ 60 · C ≥ 45 · D < 45 (clamped 5-97)"}
{t(k)}
{t(d)}
{t("pedRoleTitle")} {t("pedRole")}