feat(analytics): recommend page shows cad_quarter, buildings count, district stats

This commit is contained in:
lekss361 2026-05-11 17:37:57 +03:00
parent 2847262953
commit 03e572330b
4 changed files with 88 additions and 10 deletions

View file

@ -347,23 +347,36 @@ export default function RecommendPage() {
{data.summary.warnings.length > 0 || data.scope.data_caveat ? (
<Section title="Caveats">
{data.scope.data_caveat ? (
<p
<div
style={{
display: "flex",
flexWrap: "wrap",
gap: 8,
alignItems: "flex-start",
}}
>
<span
style={{
fontSize: 12,
display: "inline-block",
padding: "3px 8px",
background: "#f1f5f9",
border: "1px solid #e2e8f0",
borderRadius: 4,
fontSize: 11,
color: "#5b6066",
marginTop: 0,
whiteSpace: "nowrap",
}}
>
{data.scope.data_caveat}
</p>
) : null}
{data.scope.data_caveat ??
"Рекомендация основана на городском распределении сделок"}
</span>
</div>
{data.summary.warnings.length > 0 ? (
<ul
style={{
fontSize: 12,
color: "#9a6700",
margin: 0,
margin: "8px 0 0",
paddingLeft: 18,
}}
>

View file

@ -34,6 +34,20 @@ export function RecommendComparables({
: sold >= 30
? "#9a6700"
: "#b3261e";
const hasCadQuarter = c.cad_quarter != null;
const hasBuildings = c.buildings_n != null && c.buildings_n > 0;
const showMeta = hasCadQuarter || hasBuildings;
const metaParts: string[] = [];
if (hasCadQuarter) metaParts.push(`кв. ${c.cad_quarter}`);
if (hasBuildings) metaParts.push(`${c.buildings_n} корп.`);
const hasMapLink = c.lat != null && c.lon != null;
const mapUrl = hasMapLink
? `https://yandex.ru/maps/?ll=${c.lon}%2C${c.lat}&z=16&pt=${c.lon}%2C${c.lat}`
: null;
return (
<Link
key={c.obj_id}
@ -53,16 +67,48 @@ export function RecommendComparables({
style={{
fontSize: 14,
fontWeight: 600,
marginBottom: 6,
marginBottom: 4,
lineHeight: 1.2,
}}
>
{c.comm_name ?? `ЖК #${c.obj_id}`}
</div>
<div style={{ fontSize: 12, color: "#5b6066", marginBottom: 8 }}>
<div style={{ fontSize: 12, color: "#5b6066", marginBottom: 4 }}>
{c.dev_name ?? "—"}
{c.obj_class ? ` · ${c.obj_class}` : ""}
</div>
{showMeta ? (
<div
style={{
fontSize: 12,
color: "#5b6066",
marginBottom: 8,
display: "flex",
alignItems: "center",
gap: 6,
}}
>
<span>{metaParts.join(" · ")}</span>
{mapUrl ? (
<a
href={mapUrl}
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
style={{
textDecoration: "none",
lineHeight: 1,
fontSize: 13,
}}
title="Открыть на карте"
>
📍
</a>
) : null}
</div>
) : (
<div style={{ marginBottom: 8 }} />
)}
<div
style={{
display: "flex",

View file

@ -64,6 +64,20 @@ export function RecommendForm({
</option>
))}
</select>
{value.district_name.length >= 2
? (() => {
const selected = districtOptions.find(
(d) => d.district_name === value.district_name,
);
if (!selected) return null;
return (
<span style={hintStyle}>
{selected.zk_count ?? 0} ЖК · {selected.cad_quarter_count} с
кад. кварталом
</span>
);
})()
: null}
</label>
<label>

View file

@ -37,6 +37,7 @@ export interface DistrictRow {
area_m2: number | null;
median_price_per_m2: number | null;
mean_price_per_m2: number | null;
cad_quarter_count: number;
}
export interface YandexListing {
@ -253,6 +254,10 @@ export interface RecommendComparable {
obj_class: string | null;
flat_count: number | null;
sold_perc: number | null;
cad_quarter: string | null;
lat: number | null;
lon: number | null;
buildings_n: number | null;
}
export interface RecommendMixOutput {