From 98df57827e373439f7ebd5c897aa216de02ccd4b Mon Sep 17 00:00:00 2001 From: lekss361 Date: Sat, 4 Jul 2026 07:47:56 +0000 Subject: [PATCH] =?UTF-8?q?fix(tradein/v2):=20audit=20#2081=20residual=20?= =?UTF-8?q?=E2=80=94=20404=20short-circuit,=20disabled-tab=20tooltips,=20s?= =?UTF-8?q?tale=20hex=20token,=20=D0=94=D0=9A=D0=9F=20decode=20(#2392)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tradein-mvp/frontend/src/app/v2/page.tsx | 23 +++++++++++------ .../components/trade-in/v2/HistoryView.tsx | 13 ++++++++++ .../src/components/trade-in/v2/TopNav.tsx | 25 ++++++++++++++++--- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/tradein-mvp/frontend/src/app/v2/page.tsx b/tradein-mvp/frontend/src/app/v2/page.tsx index c6c8659b..7b9160d5 100644 --- a/tradein-mvp/frontend/src/app/v2/page.tsx +++ b/tradein-mvp/frontend/src/app/v2/page.tsx @@ -439,9 +439,24 @@ export default function TradeInV2Page() { // Skip the restore fetch once we already hold a fresh result. const restored = useEstimate(freshResult === null ? urlId : null); + // L3 — once the restore-by-id fetch has confirmed the estimate does not + // exist (404), `currentEstimateId` below drops to null so the sibling + // dashboard hooks (analytics/location-coef/placement-history/sell-time, + // all `enabled: estimate_id !== null`) don't each fire their own doomed + // request against the same dead id. Hoisted above the sub-hooks (was + // computed further down, after they'd already fired on the stale id). + const restoreActive = urlId !== null && freshResult === null; + const restoreError = restoreActive && restored.isError; + const restoreNotFound = + restoreError && + restored.error instanceof HTTPError && + restored.error.status === 404; + const estimate: AggregatedEstimate | null = freshResult ?? restored.data ?? null; - const currentEstimateId = freshResult?.estimate_id ?? urlId; + const currentEstimateId = restoreNotFound + ? null + : (freshResult?.estimate_id ?? urlId); // Per-user side data, independent of the current estimate. Both fail-soft // (retry:false): history feeds the «Предыдущие оценки» overlay (04), quota @@ -486,13 +501,7 @@ export default function TradeInV2Page() { const sellTimeData = sellTime.data ?? null; // ── Derived state flags ─────────────────────────────────────────────────── - const restoreActive = urlId !== null && freshResult === null; const restoreLoading = restoreActive && restored.isPending; - const restoreError = restoreActive && restored.isError; - const restoreNotFound = - restoreError && - restored.error instanceof HTTPError && - restored.error.status === 404; const loading = mutation.isPending || restoreLoading; const insufficient = diff --git a/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx b/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx index 2c590e3c..afda51c2 100644 --- a/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx +++ b/tradein-mvp/frontend/src/components/trade-in/v2/HistoryView.tsx @@ -175,6 +175,19 @@ export default function HistoryView({ > {data.dkpHeader.title} + {/* M12 — расшифровка «ДКП» один раз на секцию, тем же lowercase + hint-стилем что ObjectSummary.rowHint() (fontSize 8/letterSpacing + 0.2/muted3), а не uppercase ResultPanel §M8 стилем. */} +
+ ДКП · договор купли-продажи +
ОЦЕНКА НЕДВИЖИМОСТИ @@ -370,7 +372,14 @@ export default function TopNav({
-
+ {/* L5 — `title` gives the dimmed/non-interactive item a hover + tooltip explaining WHY it's disabled, instead of a silent dead + row (mirrored on Настройки/Помощь below). */} +
-
+
+