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:
@@ -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>
|
||||
) : (
|
||||
"—"
|
||||
|
||||
Reference in New Issue
Block a user