// ----------------------------------------------------------------------------- // Rent-Ka — Rental listings aggregator (Canada, outside Québec) // Author: Simon-Pierre Boucher — contact@spboucher.ai // components/KaScoresBlock.tsx: "KA Scores" section of the listing page. // Global badge + 5 gauges (Walk/Transit/Bike/Quiet/Services), honest // detail per score, personalized score from the user's weights // (/ka-scores), link to the methodology. // ----------------------------------------------------------------------------- import { Link } from "react-router-dom"; import { KaScores, KA_DEFAULT_WEIGHTS, fmtDist, kaGlobal, kaWeights } from "../api"; import KaScoreBadge, { KaScoreCircle } from "./KaScoreBadge"; const CAT_LABELS: Record = { epicerie: "Grocery", pharmacie: "Pharmacy", parc: "Park", cafe: "Café", ecole: "School", clinique: "Clinic", garderie: "Daycare", depanneur: "Convenience store", gym: "Gym", bibliotheque: "Library", }; const FAM_LABELS: Record = { commerces: "shops", sante: "health", education: "education", loisirs: "leisure", }; export default function KaScoresBlock({ ks }: { ks: KaScores }) { const weights = kaWeights(); const custom = JSON.stringify(weights) !== JSON.stringify(KA_DEFAULT_WEIGHTS); const perso = custom ? kaGlobal(ks, weights) : null; const d = ks.details ?? {}; const walkCats = (d.walk?.cats ?? []).filter((c) => c.dist_m != null).slice(0, 5); return (

KA Scores {ks.global != null && } {perso != null && ( you: {Math.round(perso)} )}

The detail behind this area's scores
{walkCats.length > 0 && (

Walk

    {walkCats.map((c) => (
  • {CAT_LABELS[c.cat] ?? c.cat} : {fmtDist(c.dist_m as number)} {" "}{c.pts >= 99 ? "✓" : c.pts >= 50 ? "~" : "·"}
  • ))}
)}

Transit

    {d.transit?.arret_bus_m != null && (
  • Bus stop at {fmtDist(d.transit.arret_bus_m)}
  • )} {d.transit?.station_metro_m != null && (
  • Subway station at {fmtDist(d.transit.station_metro_m)}
  • )} {d.transit?.pmd_percentile != null && (
  • Area transit service: {d.transit.pmd_percentile}th Canadian percentile (StatCan)
  • )} {d.transit?.raison &&
  • {d.transit.raison}
  • }

Bike

    {d.bike?.km_cyclables_1km != null && (
  • {d.bike.km_cyclables_1km.toLocaleString("en-CA")} km of bike lanes within 1 km
  • )} {d.bike?.raison &&
  • {d.bike.raison}
  • }

Quiet

    {(d.calme?.sources_bruit ?? []).length === 0 && (
  • No major noise source detected nearby
  • )} {(d.calme?.sources_bruit ?? []).map((s) => (
  • {s.source}{s.dist_m != null ? ` at ${fmtDist(s.dist_m)}` : ""}
  • ))} {(d.calme?.bonus_parc ?? 0) > 0 &&
  • Park nearby ✓
  • }
{d.services?.familles && ( <>

Services

    {Object.entries(d.services.familles).map(([f, n]) => (
  • {n} {FAM_LABELS[f] ?? f} in the area
  • ))}
)}

0-100 scores computed from OpenStreetMap and Statistics Canada proximity measures — Quiet is an environment estimate, not a sound measurement. Computed on{" "} {new Date(ks.computed_at * 1000).toLocaleDateString("en-CA")} (scale {ks.version}).{" "} How are KA Scores calculated? — and set your priorities

); }