Карточка «не хватает данных» вместо статичной заглушки #3539
1 changed files with 57 additions and 6 deletions
|
|
@ -289,12 +289,63 @@ function EmptyResultPanel() {
|
|||
);
|
||||
}
|
||||
|
||||
function InsufficientPanel() {
|
||||
// Named predicate for the "no price at all" state — deliberately NOT
|
||||
// `!estimate.median_price_rub` (a bare zero/price check): that would also
|
||||
// misfire on a still-loading `estimate` or on legitimate falsy-but-present
|
||||
// values. The one reliable signal is the backend's own `insufficient_data`
|
||||
// flag, which is defined (see AggregatedEstimate in types/trade-in.ts /
|
||||
// backend @computed_field) to mean "this IS a successful response, but
|
||||
// median_price_rub <= 0 — there was nothing to price with". Only fires on a
|
||||
// present, successfully-returned estimate.
|
||||
function isInsufficientEstimate(estimate: AggregatedEstimate | null): boolean {
|
||||
return estimate != null && estimate.insufficient_data === true;
|
||||
}
|
||||
|
||||
// Карточка состояния «цены нет». Показывает объяснение, которое прислал сам
|
||||
// бэкенд (confidence_explanation — текст написан специально под это состояние),
|
||||
// и адрес, который геокодер всё-таки нашёл: target_address и координаты
|
||||
// заполнены даже когда цены нет. Плюс понятное следующее действие.
|
||||
// Цена, диапазон, «−N% к рынку» и аналоги здесь не рендерятся вовсе — на
|
||||
// проводе они 0/null, и показать их значило бы выдать сломанный экран «0 ₽»
|
||||
// вместо честного «дом нашли, цену — нет».
|
||||
function InsufficientPanel({
|
||||
estimate,
|
||||
onNew,
|
||||
}: {
|
||||
estimate: AggregatedEstimate;
|
||||
onNew: () => void;
|
||||
}) {
|
||||
return (
|
||||
<PlaceholderPanel
|
||||
title="НЕДОСТАТОЧНО ДАННЫХ"
|
||||
body="По этому адресу не нашлось достаточного числа аналогов и сделок для надёжной оценки. Уточните адрес или параметры квартиры."
|
||||
/>
|
||||
title="НЕ ХВАТАЕТ ДАННЫХ ДЛЯ ОЦЕНКИ"
|
||||
body={
|
||||
estimate.confidence_explanation ??
|
||||
"По этому адресу не нашлось достаточного числа аналогов и сделок для надёжной оценки. Уточните адрес или параметры квартиры."
|
||||
}
|
||||
>
|
||||
{estimate.target_address && (
|
||||
<div
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: tokens.ink,
|
||||
maxWidth: 360,
|
||||
lineHeight: 1.5,
|
||||
}}
|
||||
>
|
||||
Найденный адрес: {estimate.target_address}
|
||||
</div>
|
||||
)}
|
||||
<div style={{ display: "flex", gap: 10, marginTop: 4 }}>
|
||||
<button
|
||||
type="button"
|
||||
className="v2-retry-btn"
|
||||
onClick={onNew}
|
||||
style={retryBtnStyle}
|
||||
>
|
||||
УТОЧНИТЬ АДРЕС
|
||||
</button>
|
||||
</div>
|
||||
</PlaceholderPanel>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -588,7 +639,7 @@ export default function TradeInV2Page() {
|
|||
// existing Серов estimates were already stuck in this state). See
|
||||
// mapResultPanel's `dealsOnlyPrice` for how the result panel discloses the
|
||||
// deals-only source instead of mislabelling it as "по объявлениям".
|
||||
const insufficient = estimate != null && estimate.insufficient_data;
|
||||
const insufficient = isInsufficientEstimate(estimate);
|
||||
const apiError = mutation.error?.message ?? null;
|
||||
// M4: estimate-dependent meta/controls (the «ДЕЙСТВИТЕЛЕН ДО» validity line,
|
||||
// «КАК РАССЧИТАНО», PDF) only render once there is a real, sufficient estimate.
|
||||
|
|
@ -830,7 +881,7 @@ export default function TradeInV2Page() {
|
|||
</div>
|
||||
);
|
||||
} else if (estimate && insufficient) {
|
||||
middleContent = <InsufficientPanel />;
|
||||
middleContent = <InsufficientPanel estimate={estimate} onNew={handleNew} />;
|
||||
} else {
|
||||
middleContent = <EmptyResultPanel />;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue