"use client"; /** * OfferCard — Секция 4 «Оффер» (commercial — Brusnika p.4 «формирование * выкупной стоимости»). Показывает разбивку издержек самостоятельной продажи * на фиксированных дефолтных ставках (median_price_rub + DEFAULT_BARGAIN_PCT). * * NB: сама ВЫКУПНАЯ цена (сколько платит девелопер) НЕ рассчитывается — это * коммерческое решение девелопера/бренда (нет параметров haircut/маржи/срока). * Здесь — illustrative сравнение издержек по типовым рыночным ставкам * (см. offer-rates.ts), НЕ официальный оффер бренда. * * TODO(commercial): подставить реальные условия в DEFAULT_OFFER_RATES * (offer-rates.ts) — единственное место для смены ставок. */ import { useMemo } from "react"; import type { AggregatedEstimate } from "@/types/trade-in"; import { API_BASE_URL } from "@/lib/api"; import { DEFAULT_OFFER_RATES, computeBreakdown, } from "./offer-rates"; interface Props { estimate: AggregatedEstimate; /** #657 white-label: активный ?brand= slug — прокидывается в PDF endpoint. */ brandSlug?: string | null; } function fmtRub(v: number): string { return Math.round(v).toLocaleString("ru-RU"); } function formatMln(rub: number): string { return `${(rub / 1_000_000).toFixed(2).replace(".", ",")} млн`; } /** Середина дефолтного диапазона торга — стартовое значение ползунка. */ const DEFAULT_BARGAIN_PCT = (DEFAULT_OFFER_RATES.bargain.lo + DEFAULT_OFFER_RATES.bargain.hi) / 2; export function OfferCard({ estimate, brandSlug }: Props) { // PDF endpoint (api/v1/trade_in.py) уже honor'ит ?brand= для white-label. const pdfQuery = brandSlug ? `?brand=${encodeURIComponent(brandSlug)}` : ""; // ── Разбивка на фиксированных дефолтах ── const fixedPrice = Math.round(estimate.median_price_rub); const breakdown = useMemo( () => computeBreakdown(fixedPrice, DEFAULT_BARGAIN_PCT, DEFAULT_OFFER_RATES), [fixedPrice], ); return (
Секция 4 · Оффер

Формирование выкупной стоимости

Оценка по рынку:{" "} {estimate.insufficient_data ? "—" : `${formatMln(estimate.median_price_rub)} ₽`}
медиана цен в объявлениях аналогов
{/* ── Прайм-блок: ваша выгода ── */} {/* intentional: «Trade-In» здесь = механика сделки, не имя бренда (rebrand #1079) */}
Ваша выгода через Trade-In
{fmtRub(breakdown.totalLo)} – {fmtRub(breakdown.totalHi)} ₽
столько вы теряете при самостоятельной продаже — Trade-In берёт эти издержки на себя
{/* intentional: «Trade-In» здесь = механика сделки, не имя бренда (rebrand #1079) */} {breakdown.rows.map((row) => ( ))}
Статья расходовЧерез Trade-In Самостоятельная продажа
{row.name}
{row.sub}
{row.tradeLabel} {row.selfLo === row.selfHi ? `${fmtRub(row.selfLo)} ₽` : `${fmtRub(row.selfLo)} – ${fmtRub(row.selfHi)} ₽`}
Общие потери при самостоятельной продаже 0 ₽ · берём на себя {fmtRub(breakdown.totalLo)} – {fmtRub(breakdown.totalHi)} ₽
{/* intentional: «Trade-In» здесь = механика сделки, не имя бренда (rebrand #1079) */}
Издержки при самостоятельной продаже сопоставимы со скидкой{" "} {breakdown.totalPctMid.toFixed(0)}% от цены объявления.{" "} Trade-In закрывает их полностью, а цена в новостройке фиксируется на момент оценки. Проценты и суммы — ориентировочные рыночные значения, а не окончательный оффер.

Экономия времени

Берём на себя показы, переговоры и поиск покупателей. Менеджеру остаётся только подписать ДКП.

Юридическая безопасность

Проверяем чистоту документов, ЕГРН, прописанных и обременения. Исключаем риски.

Фиксированная цена новостройки

Сохраняем планировку в каталоге по цене на момент оценки — до закрытия сделки.

Гарантия цены

Снимаем риск колебаний рынка — выкупная стоимость зафиксирована в оффере на 30 дней.

Готовы отправить оффер клиенту?
PDF-отчёт + персональный оффер по выкупной цене — за 1 клик.
Скачать PDF
); } function pct(frac: number): string { return `${(frac * 100).toFixed(0)}%`; }