From 1941c3d7df295641b8eb97f1fbe8ec73c948b254 Mon Sep 17 00:00:00 2001 From: TradeIn Deploy Date: Fri, 22 May 2026 12:02:56 +0500 Subject: [PATCH] =?UTF-8?q?fix(tradein):=20=D1=84=D0=BE=D1=82=D0=BE=20?= =?UTF-8?q?=D0=B0=D0=BD=D0=B0=D0=BB=D0=BE=D0=B3=D0=B0=20=D0=B2=20=D0=A1?= =?UTF-8?q?=D0=B2=D0=BE=D0=B4=D0=BA=D0=B5=20+=20=D1=87=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D1=81=D1=82=D0=B0=D1=82=D1=83=D1=81=20?= =?UTF-8?q?=D0=B8=D1=81=D1=82=D0=BE=D1=87=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UI-баги, замеченные при обзоре результата оценки: - HeroSummary: блок hero-photo был пустым серым плейсхолдером (в макете там фото, в коде слот не подключён). Теперь показывает фото первого аналога с картинкой; onError → fallback на плейсхолдер. - SourcesProgress: источники без данных после завершения оценки оставались в статусе idle с подписью «ожидает запрос» — выглядело как зависший запрос. Теперь после готовности → «нет данных» (терминальный статус). --- .../src/components/trade-in/HeroSummary.tsx | 24 +++++++++++++++---- .../components/trade-in/SourcesProgress.tsx | 6 ++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx b/tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx index 1a872eac..85ecf6d0 100644 --- a/tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx +++ b/tradein-mvp/frontend/src/components/trade-in/HeroSummary.tsx @@ -1,5 +1,7 @@ "use client"; +/* eslint-disable @next/next/no-img-element -- фото аналога с внешнего CDN, next/image не нужен */ + /** * HeroSummary — Секция 1 «Сводка» из mockup tradein.html. * Показывает медиану + достоверность CV + параметры объекта + 2 ценовых бара (объявления / сделки). @@ -49,6 +51,8 @@ export function HeroSummary({ estimate, input }: Props) { const m = estimate.median_price_rub; const lo = estimate.range_low_rub; const hi = estimate.range_high_rub; + // Фото первого аналога с картинкой — вместо пустого серого плейсхолдера. + const heroPhoto = estimate.analogs.find((a) => a.photo_url)?.photo_url ?? null; // Расчёт ширины для price bar (50% = середина): медиана внутри min/max const span = hi - lo; const medianPctRaw = span > 0 ? ((m - lo) / span) * 100 : 50; @@ -75,11 +79,23 @@ export function HeroSummary({ estimate, input }: Props) {
-
+
+ {heroPhoto && ( + Фото похожего объекта { + e.currentTarget.style.display = "none"; + }} + style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} + /> + )}
- {estimate.sources_used.length > 0 - ? `${estimate.sources_used[0]} · ${estimate.n_analogs} аналогов` - : "Нет фото"} + {heroPhoto + ? `фото аналога${estimate.sources_used[0] ? ` · ${estimate.sources_used[0]}` : ""}` + : estimate.sources_used.length > 0 + ? `${estimate.sources_used[0]} · ${estimate.n_analogs} аналогов` + : "Нет фото"}
diff --git a/tradein-mvp/frontend/src/components/trade-in/SourcesProgress.tsx b/tradein-mvp/frontend/src/components/trade-in/SourcesProgress.tsx index 62290b0e..2529acca 100644 --- a/tradein-mvp/frontend/src/components/trade-in/SourcesProgress.tsx +++ b/tradein-mvp/frontend/src/components/trade-in/SourcesProgress.tsx @@ -186,7 +186,11 @@ export function SourcesProgress({ estimate, isPending }: Props) { {r.status === "done" && r.count === undefined && готово} {r.status === "loading" && "сбор..."} {r.status === "error" && "timeout — нет ответа"} - {r.status === "idle" && ожидает запрос} + {r.status === "idle" && ( + + {isDone ? "нет данных" : "ожидает запрос"} + + )}
))}