// ----------------------------------------------------------------------------- // Lou-Ka — Agrégateur de logements à louer (province de Québec) // Auteur : Simon-Pierre Boucher — contact@spboucher.ai // fiche/TrueCostCard.tsx : « Coût réel mensuel » — loyer + frais non inclus, // chaque poste étiqueté (inclus / observé / estimé / inconnu), total et // annuel, prix au pi² avec percentile réellement calculé, estimation // Hydro-Québec (cache ; bouton pour lancer le calcul à la demande). // ----------------------------------------------------------------------------- import { useState } from "react"; import { CoutReel, HydroEstimate, fetchHydro, fmtPrice } from "../api"; import { IcoBolt2, IcoWallet } from "../components/Icons"; import { Accordion, ErrorState, SectionCard, SkeletonLines, NBSP } from "./ui"; import { Res } from "./useFicheData"; const ST: Record = { included: "inclus", observed: "observé", estimated: "estimé", unknown: "inconnu", calculated: "calculé", inferred: "estimé" }; export default function TrueCostCard({ cout, hydro, adresse, uid, lat, lng, onRetry }: { cout: Res; hydro: Res; adresse: string; uid: string; lat: number | null; lng: number | null; onRetry: () => void; }) { const [h, setH] = useState(null); const [busy, setBusy] = useState(false); const d = cout.status === "ok" ? cout.data : null; const hy = h ?? (hydro.status === "ok" ? hydro.data : null); const hydroVisible = hy && (hy.disponible || hy.en_attente || !/captcha|configuré|incomplète/.test(hy.raison || "")); if (cout.status === "na" || (d && d.loyer == null)) return null; const lancer = () => { setBusy(true); fetchHydro(adresse, { uid, lat, lng }, true).then(setH).catch(() => {}).finally(() => setBusy(false)); }; return ( } sub="Loyer + frais non inclus, chaque poste avec son statut"> {cout.status === "loading" && } {cout.status === "error" && Calcul du coût réel temporairement indisponible.} {d && ( <>
    {d.lignes.map((li) => (
  • {li.poste}{ST[li.statut] ?? li.statut} {li.montant != null && li.montant > 0 && fmtPrice(li.montant)} {li.montant === 0 && li.statut === "included" && `0${NBSP}$`} {li.montant == null && "—"}
  • ))} {d.total_estime != null && (
  • Total estimé≈{NBSP}{fmtPrice(d.total_estime)}{NBSP}/mois
  • )} {d.annuel_estime != null && (
  • soit sur 12 mois≈{NBSP}{fmtPrice(d.annuel_estime)}
  • )}
{d.postes_inconnus.length > 0 && (

Non chiffrables avec les données publiées : {d.postes_inconnus.join(", ").toLowerCase()} — le total réel peut être plus élevé.

)} {d.pi2 && (

{d.pi2.valeur.toFixed(2).replace(".", ",")}{NBSP}$/pi² {d.pi2.percentile_secteur != null && <> — moins cher que {100 - d.pi2.percentile_secteur}{NBSP}% des {d.pi2.n_secteur} logements comparables du secteur (~2{NBSP}km)} {d.pi2.percentile_secteur == null && d.pi2.percentile_ville != null && <> — moins cher que {100 - d.pi2.percentile_ville}{NBSP}% des {d.pi2.n_ville} comparables ({d.pi2.portee_ville})} {d.pi2.percentile_note && <> {d.pi2.percentile_note}}

)} {hydroVisible && hy && (
{hy.disponible ? ( Électricité : {fmtPrice(hy.cout_mensuel!)}{NBSP}/mois (≈{NBSP}{fmtPrice(hy.cout_annuel!)}{NBSP}/an{hy.kwh_annuel ? `, ${hy.kwh_annuel.toLocaleString("fr-CA")} kWh` : ""}) — estimation Hydro-Québec fondée sur la consommation réelle du logement. ) : hy.en_attente ? ( <> Estimation Hydro-Québec du coût d'électricité disponible à la demande. ) : ( Hydro-Québec n'a pas d'estimation pour cette adresse. )}
)}

{d.methode}

)}
); }