From 16a6d5a97ba72edaeca5e7dec11536beca09cd44 Mon Sep 17 00:00:00 2001 From: lekss361 Date: Sat, 30 May 2026 11:13:00 +0300 Subject: [PATCH] fix(tradein): hide lead CTA when contact email unset (no garbage mailto fallback) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review #689: the CTA fallback was a throwaway address (settings.contact_email, a Nominatim User-Agent contact — NOT a lead inbox). Unset env on first deploy → client's заявка with PII drafts to a stranger, lead silently lost. Fix: CONTACT_EMAIL = env only (trimmed, no fallback); render the «Оставить заявку» CTA ONLY when leadEnabled (email configured). PDF + transparency unaffected. tsc clean. --- .../components/trade-in/HeroTransparency.tsx | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/tradein-mvp/frontend/src/components/trade-in/HeroTransparency.tsx b/tradein-mvp/frontend/src/components/trade-in/HeroTransparency.tsx index 7daefc74..eca23deb 100644 --- a/tradein-mvp/frontend/src/components/trade-in/HeroTransparency.tsx +++ b/tradein-mvp/frontend/src/components/trade-in/HeroTransparency.tsx @@ -35,11 +35,11 @@ const CONF_BAND: Record = { }; /** - * Контакт для lead-стаба. Настраивается через NEXT_PUBLIC_TRADEIN_CONTACT_EMAIL; - * fallback совпадает с backend `settings.contact_email`. + * Лид-инбокс. Задаётся ТОЛЬКО через env NEXT_PUBLIC_TRADEIN_CONTACT_EMAIL. + * БЕЗ fallback: если не задан → CTA «оставить заявку» скрывается (leadEnabled), + * чтобы заявка с PII не ушла на чужой/тестовый адрес (review PR #689). */ -const CONTACT_EMAIL = - process.env.NEXT_PUBLIC_TRADEIN_CONTACT_EMAIL ?? "erginrajpopxbe@outlook.com"; +const CONTACT_EMAIL = (process.env.NEXT_PUBLIC_TRADEIN_CONTACT_EMAIL ?? "").trim(); /** * Эвристика уровня сопоставимых объектов из confidence_explanation. @@ -88,6 +88,8 @@ export function HeroTransparency({ estimate, brandSlug, brandName }: Props) { const band = CONF_BAND[estimate.confidence] ?? CONF_BAND.low; const tier = compsTier(estimate.confidence_explanation); const fresh = freshnessMoment(estimate); + // CTA показываем только при сконфигурированном лид-инбоксе (см. CONTACT_EMAIL) — review #689. + const leadEnabled = CONTACT_EMAIL.length > 0; // PDF endpoint (api/v1/trade_in.py) уже honor'ит ?brand= для white-label — // тот же паттерн, что в OfferCard, поэтому консистентно. @@ -110,16 +112,19 @@ export function HeroTransparency({ estimate, brandSlug, brandName }: Props) { return (
- {/* CTA — prominent primary (конверсия = преимущество над «мёртвым» PDF) */} - {/* TODO(lead-flow): заменить mailto-стаб на POST /api/v1/trade-in/lead, когда появится backend. */} - - - - - - - Оставить заявку на трейд-ин - + {/* CTA — prominent primary (конверсия = преимущество над «мёртвым» PDF). */} + {/* Рендерим ТОЛЬКО при сконфигурированном лид-инбоксе (review #689) — иначе */} + {/* заявка с PII ушла бы на чужой/тестовый адрес. TODO(lead-flow): POST /lead. */} + {leadEnabled && ( + + + + + + + Оставить заявку на трейд-ин + + )}