feat(tradein/ui): вход в поддержку с сайта — плавающая кнопка + живая «Помощь» #2527

Merged
lekss361 merged 1 commit from feat/tradein-support-button into main 2026-07-16 19:11:58 +00:00
Owner

Зачем

Support-мост (#2526) уже работает на проде, но попасть в бота с сайта было неоткуда — клиент о нём просто не узнавал.

Заодно закрывает перекос пошире: LeadForm монтируется только при hasEstimate (v2/page.tsx:1064), то есть до расчёта оценки у клиента не было ни одного способа связаться. Единственная другая ссылка на связь во всём UI — NoAccessScreen.tsx:84, и та лишь на экране «доступ закончился».

Что сделано

Два входа, оба ведут в @MERAsupport_bot:

  • SupportButton (новый) — плавающая кнопка в правом нижнем углу, на всех экранах /v2
  • «Помощь» в меню TopNav — была задизейблена с «скоро появится», теперь живая ссылка

Профиль/Настройки в том же меню остаются задизейбленными — страниц под них нет.

Решения

Это внешняя ссылка, а не чат-виджет. Бот живёт в Telegram, поэтому ни API, ни состояния, ни сокетов не нужно.

URL — module-константа, не NEXT_PUBLIC_*. Env инлайнятся на build-time, так что переменная не дала бы гибкости рантайма — только лишний build-arg в трёх местах. Источник правды один: SUPPORT_BOT_URL в SupportButton.tsx, TopNav импортирует его (строка с URL физически существует в коде один раз).

Монтаж в v2/layout, не в глобальный app/layout. Последний накрывает ещё админку /scrapers/** и /sale-share — другой продукт без бренда МЕРА, им кнопка не нужна.

createPortal в document.body. /v2 рисует HUD внутри артборда 1536×1024 с transform: scale() (v2/page.tsx:860-871), а position: fixed внутри трансформированного предка позиционируется относительно него, а не вьюпорта — без портала кнопку унесло бы вместе с HUD. Паттерн 1:1 с MapPicker.tsx:104-108.

z-index: 25 — осознанно НИЖЕ всех оверлеев v2 (SectionOverlay 29/30, LocationDrawer 40/41, TopNav 50, UserMenu 200): при открытой модалке кнопка должна уходить под неё, а не воровать клики и таб-порядок.

Стиль только через tokens.ts — файл прямо запрещает хардкодить hex (там выверенные по WCAG контрасты). Готового <Button> в проекте нет, следуем инлайн-паттерну LeadForm.

A11y

aria-label="Написать в поддержку МЕРА в Telegram", тач-таргет 44px, focus-visible ring, инлайновый SVG с aria-hidden, rel="noopener noreferrer".

Проверка

  • tsc --noEmit — чисто
  • lint — чисто (3 warning'а pre-existing, не в этих файлах)
  • npm run build — успешно, /v2 49.4 kB, все 15 страниц prerender

⚠️ Визуальная проверка — на проде после деплоя. Локально RouteGuard без бекенда возвращает null (RouteGuard.tsx:46if (isLoading) return null), рендер не доходит до кнопки; эмулировать авторизацию ради скриншота дороже, чем посмотреть на живом стенде с настоящей сессией.

## Зачем Support-мост (#2526) уже работает на проде, но **попасть в бота с сайта было неоткуда** — клиент о нём просто не узнавал. Заодно закрывает перекос пошире: `LeadForm` монтируется только при `hasEstimate` (`v2/page.tsx:1064`), то есть **до расчёта оценки у клиента не было ни одного способа связаться**. Единственная другая ссылка на связь во всём UI — `NoAccessScreen.tsx:84`, и та лишь на экране «доступ закончился». ## Что сделано Два входа, оба ведут в `@MERAsupport_bot`: - **`SupportButton`** (новый) — плавающая кнопка в правом нижнем углу, на всех экранах `/v2` - **«Помощь»** в меню `TopNav` — была задизейблена с «скоро появится», теперь живая ссылка Профиль/Настройки в том же меню остаются задизейбленными — страниц под них нет. ## Решения **Это внешняя ссылка, а не чат-виджет.** Бот живёт в Telegram, поэтому ни API, ни состояния, ни сокетов не нужно. **URL — module-константа, не `NEXT_PUBLIC_*`.** Env инлайнятся на build-time, так что переменная не дала бы гибкости рантайма — только лишний build-arg в трёх местах. Источник правды один: `SUPPORT_BOT_URL` в `SupportButton.tsx`, `TopNav` импортирует его (строка с URL физически существует в коде один раз). **Монтаж в `v2/layout`, не в глобальный `app/layout`.** Последний накрывает ещё админку `/scrapers/**` и `/sale-share` — другой продукт без бренда МЕРА, им кнопка не нужна. **`createPortal` в `document.body`.** `/v2` рисует HUD внутри артборда 1536×1024 с `transform: scale()` (`v2/page.tsx:860-871`), а `position: fixed` внутри трансформированного предка позиционируется относительно **него**, а не вьюпорта — без портала кнопку унесло бы вместе с HUD. Паттерн 1:1 с `MapPicker.tsx:104-108`. **`z-index: 25` — осознанно НИЖЕ всех оверлеев v2** (SectionOverlay 29/30, LocationDrawer 40/41, TopNav 50, UserMenu 200): при открытой модалке кнопка должна уходить под неё, а не воровать клики и таб-порядок. **Стиль только через `tokens.ts`** — файл прямо запрещает хардкодить hex (там выверенные по WCAG контрасты). Готового `<Button>` в проекте нет, следуем инлайн-паттерну `LeadForm`. ## A11y `aria-label="Написать в поддержку МЕРА в Telegram"`, тач-таргет 44px, `focus-visible` ring, инлайновый SVG с `aria-hidden`, `rel="noopener noreferrer"`. ## Проверка - `tsc --noEmit` — чисто - `lint` — чисто (3 warning'а pre-existing, не в этих файлах) - `npm run build` — успешно, `/v2` 49.4 kB, все 15 страниц prerender ⚠️ **Визуальная проверка — на проде после деплоя.** Локально `RouteGuard` без бекенда возвращает `null` (`RouteGuard.tsx:46` — `if (isLoading) return null`), рендер не доходит до кнопки; эмулировать авторизацию ради скриншота дороже, чем посмотреть на живом стенде с настоящей сессией.
lekss361 added 1 commit 2026-07-16 19:09:56 +00:00
feat(tradein/ui): вход в поддержку с сайта — плавающая кнопка + живая «Помощь»
All checks were successful
CI / changes (pull_request) Successful in 11s
CI Trade-In / changes (pull_request) Successful in 12s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m15s
7fd40f6ea5
Support-мост (#2526) уже работает на проде, но попасть в бота с сайта было
неоткуда — клиент о нём просто не узнавал.

Два входа, оба ведут в @MERAsupport_bot:
- SupportButton — плавающая кнопка в правом нижнем углу, на всех экранах /v2
- «Помощь» в меню TopNav — была задизейблена с «скоро появится», теперь живая

Закрывает перекос пошире: LeadForm монтируется только при hasEstimate
(v2/page.tsx:1064), т.е. до расчёта оценки у клиента не было НИ ОДНОГО способа
связаться. Единственная другая ссылка на связь во всём UI — NoAccessScreen.tsx:84,
и та лишь на экране «доступ закончился».

Решения:
- Это внешняя ссылка, а не чат-виджет: бот живёт в Telegram, поэтому ни API,
  ни состояния, ни сокетов не нужно.
- URL — module-константа, не NEXT_PUBLIC_*: env инлайнятся на build-time, так что
  переменная не дала бы гибкости рантайма, только лишний build-arg. Источник
  правды один — SUPPORT_BOT_URL в SupportButton.tsx, TopNav импортирует его.
- Монтаж в v2/layout, не в глобальный app/layout: последний накрывает ещё админку
  /scrapers/** и /sale-share — другой продукт без бренда МЕРА.
- createPortal в document.body: /v2 рисует HUD внутри артборда 1536×1024 с
  transform: scale(), а position:fixed внутри трансформированного предка
  позиционируется относительно него, а не вьюпорта — без портала кнопку унесло бы
  вместе с HUD.
- z-index 25 — осознанно НИЖЕ всех оверлеев v2 (SectionOverlay 29/30,
  LocationDrawer 40/41, TopNav 50, UserMenu 200): при открытой модалке кнопка
  должна уходить под неё, а не воровать клики и таб-порядок.
- Стиль только через tokens.ts (файл прямо запрещает хардкодить hex);
  готового <Button> в проекте нет, следуем инлайн-паттерну LeadForm.

Профиль/Настройки в том же меню остаются задизейбленными — страниц под них нет.

A11y: aria-label, тач-таргет 44px, focus-visible ring, инлайновый SVG с aria-hidden.

Проверка: tsc --noEmit чисто, lint чисто (3 warning'а pre-existing, не в этих
файлах), npm run build успешно (/v2 49.4 kB, все 15 страниц prerender).
Визуальная проверка — на проде после деплоя: локально RouteGuard без бекенда
возвращает null (RouteGuard.tsx:46) и рендер не доходит до кнопки.
lekss361 merged commit d56103219a into main 2026-07-16 19:11:58 +00:00
lekss361 deleted branch feat/tradein-support-button 2026-07-16 19:11:58 +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#2527
No description provided.