Commit Graph
3 Commits
Author SHA1 Message Date
Yuriy PanovandClaude Opus 5 1ee5431b92 hotel: apply the v7 design and add the callback dialog
Ports legacy/hotel v7 into the React landing.

- Copy: nav is Экономика / Для гостя / Интерьер / Сервис, and «Интерьер»
  now comes before «Сервис». The hero keeps one button and gets the
  2 500 ₽ / 600 000 ₽ / 7,2 млн ₽ facts. New headings and leads for the
  interior, service and request blocks. Session lengths 10–15 and 30–60
  min, area 12–36 m².
- Calculator counts sessions and gains the ЭкзоКлиник benchmark and a
  «Получить консультацию» button.
- Request form: company and email are optional. The server schema
  already treats them as optional.
- v8 phone type scale (≤620px), a 380px `micro` step, and a `slim`
  (≤640px) variant. The max-width variants are now declared widest first,
  so the narrower one wins where two apply.
- The market charts' SVGs stay inline, as in the mockup.

The header «Звонок» button opens the «Перезвоним вам» dialog from the
fitness landing (name, phone, consent). The server accepts form
'callback', names the deal «Обратный звонок — <имя>» and tags it
«обратный звонок». The phone link inside the dialog still reports a call
click.

With Inter substituted into the mockup, the page text matches it line for
line (except the fixed «2025–2026 гг.» typo), and every section height
matches at 360–1440 px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 19:00:20 +06:00
Yuriy PanovandClaude Opus 5 e13854e918 leads: new phone number and an amoCRM lead on every call-button click
The published number becomes +7 927 789-60-71 across all four landings —
`contacts` in each `src/data/content.ts`, plus the fallback messages in the
lead endpoints and `src/lib/lead.ts` that spell it out when amoCRM is down.
The `legacy/` reference pages keep the old number: they are the visual
originals, not something that ships.

Tapping the phone button now also creates a lead. It cannot reuse the form
path: a click carries no name and no number, so `callClickSchema` in
`shared/lead.ts` validates the tracking data alone, `LeadService.submitCallClick`
creates a contactless lead tagged `клик по телефону`, and `AmoClient.createLead`
takes an optional `contactId` for it. The mapper's field/note split moved into
`collect()` so both lead kinds share it.

The browser fires this with `sendBeacon` (falling back to `fetch keepalive`),
because the same click hands the page to `tel:` and a plain fetch would be
cut off mid-flight. Duplicates are held down from both ends: one lead per
browser session on the client, four per IP per 30 minutes on the server.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 00:58:15 +06:00
Yuriy PanovandClaude Opus 5 35f713a267 Convert hotel landing to React + Tailwind v4 with amoCRM lead capture
Ports the single-file ЭкзоОтель page to the same architecture as the fitness
landing: Vite + React 19 + TypeScript + Tailwind v4 on the client, Express 5 for
the /api/leads/hotels endpoint, zod schema shared between the two.

The original page is kept in legacy/index.html as the visual reference. Its 15
inlined base64 images are extracted to files (the 1 MB HTML becomes ~318 KB of
JS plus assets loaded on demand), and its text is reproduced line for line —
verified with an innerText diff. Section heights stay within 0.6% at 375 and
1440 px; the drift comes from Inter actually loading, which the original asked
for but never served.

Three deliberate departures, documented in the README:
  * eyebrow and lead in the CTA block were dark teal on navy (3.4:1); they now
    match the other dark sections
  * hero fact values overflowed their 80px column into the label below 430px
  * "2025–2026г.." typo in the market source note

Leads reuse the fitness amoCRM integration: contact lookup by phone in every
spelling, deal in the first stage of pipeline 10980758, account fields matched
automatically with the rest written to a note. Rate limit, honeypot, and a
localStorage fallback so a lead survives the CRM being down. Vite runs on 5174
and the API on 3001 so both landings can run at once.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 14:17:10 +06:00