SPB Git forge

spb/rent-ka

Public
8commits 1branches 0releases
7.4 MBsize
maindefault branch
19 days agolast push
Python 68.8% TypeScript 18.6% CSS 8.7% JavaScript 3.3% HTML 0.6%
1.6 KB · 40 lines tsx
Raw Blame History
1// -----------------------------------------------------------------------------2// Rent-Ka — Rental listings aggregator (Canada, outside Québec)3// Author: Simon-Pierre Boucher — contact@spboucher.ai4// components/FairValueBadge.tsx: fair-value badge5//   Three states: below market / at market / above market.6//   Colour-blind friendly: icon + label, never colour alone.7// -----------------------------------------------------------------------------8const NBSP = " ";910export function fmtDeviation(dev: number | null | undefined): string | null {11  if (dev == null) return null;12  const pct = Math.round(Math.abs(dev) * 100);13  return `${dev < 0 ? "−" : "+"}${pct}${NBSP}%`;14}1516const META = {17  sous: { cls: "deal-good", icon: "▼", label: "Below market" },18  marche: { cls: "deal-ok", icon: "≈", label: "At market" },19  sur: { cls: "deal-high", icon: "▲", label: "Above market" },20} as const;2122export default function FairValueBadge({ verdict, deviation, compact = false }: {23  verdict: "sous" | "marche" | "sur" | null | undefined;24  deviation?: number | null;25  compact?: boolean;   // list-card version (short)26}) {27  if (!verdict || !(verdict in META)) return null;28  const m = META[verdict];29  const pct = fmtDeviation(deviation);30  return (31    <span className={`fv-badge ${m.cls} ${compact ? "fv-compact" : ""}`}32          title={`${m.label}${pct ? ` (${pct} vs estimated fair value)` : ""}`}>33      <span aria-hidden="true" className="fv-ico">{m.icon}</span>34      {compact35        ? (pct ?? m.label)36        : <>{m.label}{pct && <b className="fv-pct">{pct}</b>}</>}37    </span>38  );39}40