feat(ui): smart proximity label — infer street from deal data

Instead of showing "סביבה קרובה" for all street-polygon deals, we now
infer the searched street from the most common streetNameHeb among
deal_source="street" deals. Deals on that street get "אותו רחוב" (blue);
deals on other streets get "סביבה קרובה" (lighter blue). Works correctly
for both address searches and gush+plot searches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-25 14:55:27 +00:00
parent 9aa9fa29f1
commit 918e7dbe02
+32 -11
View File
@@ -5,11 +5,34 @@ interface Props {
deals: Deal[];
}
const SOURCE_LABELS: Record<string, string> = {
same_building: "אותו בניין",
street: "סביבה קרובה",
neighborhood: "שכונה",
};
function inferStreetName(deals: Deal[]): string | null {
const freq: Record<string, number> = {};
for (const d of deals) {
if (d.deal_source === "street" && d.streetNameHeb) {
freq[d.streetNameHeb] = (freq[d.streetNameHeb] ?? 0) + 1;
}
}
const entries = Object.entries(freq);
if (!entries.length) return null;
return entries.reduce((a, b) => (b[1] > a[1] ? b : a))[0];
}
function proximityLabel(deal: Deal, inferredStreet: string | null): string {
if (!deal.deal_source) return "—";
if (deal.deal_source === "same_building") return "אותו בניין";
if (deal.deal_source === "neighborhood") return "שכונה";
// "street" source — check if actually same street
if (inferredStreet && deal.streetNameHeb === inferredStreet) return "אותו רחוב";
return "סביבה קרובה";
}
function proximityClass(deal: Deal, inferredStreet: string | null): string {
if (deal.deal_source === "same_building") return "bg-emerald-100 text-emerald-800";
if (deal.deal_source === "street" && inferredStreet && deal.streetNameHeb === inferredStreet)
return "bg-blue-100 text-blue-800";
if (deal.deal_source === "street") return "bg-sky-50 text-sky-700";
return "bg-slate-100 text-slate-700";
}
export function DealsTable({ deals }: Props) {
if (!deals.length) {
@@ -20,6 +43,8 @@ export function DealsTable({ deals }: Props) {
);
}
const inferredStreet = inferStreetName(deals);
return (
<div className="overflow-x-auto rounded-md border">
<table dir="rtl" className="w-full text-sm">
@@ -67,14 +92,10 @@ export function DealsTable({ deals }: Props) {
<span
className={
"inline-block rounded-full px-2 py-0.5 text-xs " +
(d.deal_source === "same_building"
? "bg-emerald-100 text-emerald-800"
: d.deal_source === "street"
? "bg-blue-100 text-blue-800"
: "bg-slate-100 text-slate-700")
proximityClass(d, inferredStreet)
}
>
{SOURCE_LABELS[d.deal_source] || d.deal_source}
{proximityLabel(d, inferredStreet)}
</span>
) : (
"—"