feat(tradein/v2) [FE-1]: wire main dashboard to real API (mappers + page shell) #2048

Merged
lekss361 merged 1 commit from feat/tradein-v2-fe1-data-shell into main 2026-06-28 11:50:53 +00:00
Owner

Closes #2038 · foundation for #2036.

Что

/trade-in/v2 главный дашборд (NAV / HERO / 01 Параметры / 02 Результат / 03 Сводка / FOOTER) теперь рендерит реальную оценку вместо fixtures.ts.

Архитектура (стандарт для FE-2..5)

  • Новый components/trade-in/v2/mappers.ts — ЧИСТЫЕ функции AggregatedEstimate(+street-deals/analytics) → fixture-shape (формат /1e6 ru, toLocaleString('ru'), enum→RU, гистограмма-бины, scatter px, range CSS-%, donut из ratio). Вся геометрия/форматирование тут.
  • page.tsx владеет данными: форма → useEstimateMutation; restore по ?id= через window.location.search (как v1 — НЕ useSearchParams, иначе Suspense ломает next build); sub-хуки useStreetDeals/useEstimateHouseAnalytics; loading (grey fade-skeleton, без shimmer) / empty / insufficient / error — честные плейсхолдеры, без fixtures-as-real; partial sub-hook fail не блокирует страницу.
  • Компоненты ResultPanel/ObjectSummary/HeroBar/Footer принимают composite data prop с fixture-default → пиксель-перфект разметка не тронута. ParamsPanel → controlled-форма (onSubmit/isPending/error/initialValues).

Маппинг

  • 3 карточки: asking (median_price_rub) / ожидаемая сделка (expected_sold_* + донат из asking_to_sold_ratio) / ДКП (resolveDealTier: street-deals → dkp_corridor×area → actual_deals).
  • ranges ads/deals, scatter-mini (price×days_on_market), 7 источников (active из sources_used, count FE-groupBy), сводка (+house-analytics.kpi).

FE-approx (помечено TODO, снимется в BE-1 #2043)

  • cv — FE std/mean по analogs[].price_per_m2 (нет поля в ответе).
  • per-source count — FE groupBy (массивы усечены до top-N → занижает).
  • report dateexpires_at − 24h (нет created_at в ответе).
  • LocationDrawer/locationCoef/compass, РАДИУС, CRM-actions — degrade/hidden (BE-2 #2044 / BE-3 #2045).

Verify

  • NEXT_PUBLIC_BASE_PATH=/trade-in npx next build — зелёный, route /v2 34 kB / 146 kB First Load JS, types/lint OK.
  • Pre-push code-reviewer: APPROVE (field-names verified vs types/trade-in.ts, nullable-safe, Rules-of-Hooks OK, TS-strict, без визуальной регрессии).
  • Прод-render проверка — post-deploy QA на /trade-in/v2 (submit реального ЕКБ-адреса + restore по ?id=).

Не трогает: v1 (app/page.tsx), главный frontend/, overlays (FE-2..5 на fixtures пока).

Closes #2038 · foundation for #2036. ## Что `/trade-in/v2` главный дашборд (NAV / HERO / 01 Параметры / 02 Результат / 03 Сводка / FOOTER) теперь рендерит **реальную оценку** вместо `fixtures.ts`. ### Архитектура (стандарт для FE-2..5) - Новый `components/trade-in/v2/mappers.ts` — ЧИСТЫЕ функции `AggregatedEstimate(+street-deals/analytics) → fixture-shape` (формат `/1e6` ru, `toLocaleString('ru')`, enum→RU, гистограмма-бины, scatter px, range CSS-%, donut из ratio). Вся геометрия/форматирование тут. - `page.tsx` владеет данными: форма → `useEstimateMutation`; restore по `?id=` через `window.location.search` (как v1 — НЕ `useSearchParams`, иначе Suspense ломает `next build`); sub-хуки `useStreetDeals`/`useEstimateHouseAnalytics`; loading (grey fade-skeleton, без shimmer) / empty / insufficient / error — честные плейсхолдеры, без fixtures-as-real; partial sub-hook fail не блокирует страницу. - Компоненты `ResultPanel/ObjectSummary/HeroBar/Footer` принимают composite `data` prop с fixture-default → **пиксель-перфект разметка не тронута**. `ParamsPanel` → controlled-форма (`onSubmit/isPending/error/initialValues`). ### Маппинг - 3 карточки: asking (`median_price_rub`) / ожидаемая сделка (`expected_sold_*` + донат из `asking_to_sold_ratio`) / ДКП (`resolveDealTier`: street-deals → `dkp_corridor`×area → `actual_deals`). - ranges ads/deals, scatter-mini (price×days_on_market), 7 источников (active из `sources_used`, count FE-groupBy), сводка (+`house-analytics.kpi`). ### FE-approx (помечено TODO, снимется в BE-1 #2043) - `cv` — FE std/mean по `analogs[].price_per_m2` (нет поля в ответе). - per-source `count` — FE groupBy (массивы усечены до top-N → занижает). - report `date` — `expires_at − 24h` (нет `created_at` в ответе). - LocationDrawer/`locationCoef`/`compass`, РАДИУС, CRM-actions — degrade/hidden (BE-2 #2044 / BE-3 #2045). ## Verify - `NEXT_PUBLIC_BASE_PATH=/trade-in npx next build` — зелёный, route `/v2` 34 kB / 146 kB First Load JS, types/lint OK. - Pre-push `code-reviewer`: ✅ APPROVE (field-names verified vs `types/trade-in.ts`, nullable-safe, Rules-of-Hooks OK, TS-strict, без визуальной регрессии). - Прод-render проверка — post-deploy QA на `/trade-in/v2` (submit реального ЕКБ-адреса + restore по `?id=`). Не трогает: v1 (`app/page.tsx`), главный `frontend/`, overlays (FE-2..5 на fixtures пока).
lekss361 added 1 commit 2026-06-28 11:49:35 +00:00
feat(tradein/v2): wire main dashboard to real API (mappers + page shell) (#2038)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / openapi-codegen-check (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
890daa4a31
FE-1 foundation for #2036. app/v2/page.tsx now owns data: ParamsPanel form ->
useEstimateMutation, restore-by-id via window.location.search (mirrors v1, avoids
useSearchParams Suspense build break), sub-hooks useStreetDeals/useEstimateHouseAnalytics;
loading/empty/insufficient/error states (honest placeholders, no fixtures-as-real).

New components/trade-in/v2/mappers.ts: pure AggregatedEstimate(+street-deals/analytics)
-> fixture-shape transforms — 3 price tiers (asking/expected_sold/DKP), ranges, scatter,
7 source slots, summary. CV + per-source counts are FE-approx pending BE-1 (#2043).

ParamsPanel -> controlled form (onSubmit/isPending/error/initialValues). ResultPanel/
ObjectSummary/HeroBar/Footer accept a composite data prop defaulting to the existing
fixture (pixel-perfect markup unchanged). next build green (/v2 34 kB).
lekss361 merged commit e2ff8958ca into main 2026-06-28 11:50:53 +00:00
lekss361 deleted branch feat/tradein-v2-fe1-data-shell 2026-06-28 11:50:53 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2048
No description provided.