"use client"; // "ПОЯСНЕНИЕ К РАСЧЁТУ" right-side drawer for the /trade-in/v2 "МЕРА Оценка" // design port. Opened from HeroBar (the "?" near "ЛОКАЦИЯ"). It used to render // a FABRICATED location coefficient (0.87), a fake "base × coef = result" // formula and invented POI factor lists with a false "Источник: OpenStreetMap" // footer. That location-coef metric was replaced outright (see // backend/app/services/location_index.py for the full audit): ±5% range, // uncorrelated with real prices, never actually fed the estimate. This drawer // now renders GET /trade-in/location-index (mapLocation, ./mappers.ts): a real // % deviation of the local median ₽/м² from the citywide median — framed as a // comparison metric, explicitly NOT a price adjustment — plus the real // nearest-POI list. The three degraded states (loading / out_of_coverage / // insufficient_data) each get their own honest explanation instead of one // blank "недоступно". Keeps the same drawer shell / slide animation / close // button. Open/close is driven entirely by props; while open it is a real // modal dialog (role=dialog/aria-modal, focus-trap, Esc) with semantics // mirrored from SectionOverlay. import { useEffect, useRef } from "react"; import { tokens } from "./tokens"; import { pluralRu } from "./mappers"; import type { LocationData } from "./mappers"; // Default presentation data (unwired usage / not fetched yet): the honest // loading state, never a fabricated coefficient. const LOCATION_FIXTURE: LocationData = { status: "loading", indexLabel: "—", localMedianLabel: "—", cityMedianLabel: "—", sampleSize: 0, radiusLabel: "—", poiAvailable: false, factors: [], }; // data.indexLabel is already the signed, rounded fmtPct string produced by // mapLocation ("+12%" / "−8%" / "0%" / "—") — reusing it here (rather than a // second raw-number field) keeps the sign/rounding logic in one place // (./mappers.ts). Turns it into a plain-language comparison sentence instead // of a bare percent, so it reads as "vs. the city", never as a price change. function locationDirectionSentence(indexLabel: string): string { if (indexLabel.startsWith("−")) { return `Район дешевле города на ${indexLabel.slice(1)}`; } if (indexLabel.startsWith("+")) { return `Район дороже города на ${indexLabel.slice(1)}`; } if (indexLabel === "0%") return "Район на уровне медианы по городу"; return "—"; } // «Что рядом» — qualitative POI list, independent of the numeric index // (poi_status degrades separately from status, see mapLocation/./mappers.ts). function PoiSection({ data }: { data: LocationData }) { if (!data.poiAvailable) { return (