buhapp-telegram/public/onboarding/icon-map.svg
BuhApp Dev 149f31d25d Add user onboarding flow (3-slide welcome) for new signups
- New OnboardingView module (public/js/views/onboarding.js):
  • Reads /onboarding/slides.json (designer schema with inline SVG icons,
    per-slide cta_primary/cta_skip labels) — falls back to 3 emoji slides
    if the JSON is unavailable.
  • Renders a Telegram-style dark overlay inside #mobile-frame with a
    220px floating SVG icon, title, body, dot indicator (expandable
    active dot), primary CTA, and a ghost Skip button.
  • Prev/Next via primary CTA; dot click jumps to slide; arrow keys and
    horizontal swipe also navigate.
  • Haptic feedback via TG_APP on slide change + finish.
  • markDone() writes buhapp.onboarded='1' to localStorage so the flow
    never repeats. isDone()/reset() exposed for QA.

- App integration (public/js/app.js):
  • New App.maybeOnboard() helper — awaited after every successful auth
    path: Telegram login, restored session, email login, email register,
    and consent accept. Skips silently if already onboarded.

- UI assets (public/onboarding/):
  • slides.json with 3 designer slides (Map / Chat / Review).
  • Inline-SVG icons for map, chat, and review (icon-*.svg kept for
    designer reference, preview.html too).

- Styles (public/css/app.css): new .onboarding-* dark-theme rules.
- Index (public/index.html): loads onboarding.js before app.js.
2026-08-20 20:20:54 +00:00

99 lines
4.9 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240" role="img" aria-label="Карта с геолокацией">
<defs>
<!-- Градиент фона карточки -->
<linearGradient id="mapBg" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#FF8A5C"/>
<stop offset="100%" stop-color="#FF6B35"/>
</linearGradient>
<!-- Тень под пин-маркером -->
<radialGradient id="pinShadow" cx="0.5" cy="0.5" r="0.5">
<stop offset="0%" stop-color="#000" stop-opacity="0.35"/>
<stop offset="70%" stop-color="#000" stop-opacity="0.08"/>
<stop offset="100%" stop-color="#000" stop-opacity="0"/>
</radialGradient>
<!-- Свечение вокруг пина -->
<radialGradient id="pinGlow" cx="0.5" cy="0.5" r="0.5">
<stop offset="0%" stop-color="#FF6B35" stop-opacity="0.45"/>
<stop offset="100%" stop-color="#FF6B35" stop-opacity="0"/>
</radialGradient>
<!-- Мягкий блик на "карте" -->
<linearGradient id="mapSheen" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="0.18"/>
<stop offset="100%" stop-color="#FFFFFF" stop-opacity="0"/>
</linearGradient>
</defs>
<!-- Внешний круг-подложка (бренд) -->
<circle cx="120" cy="120" r="112" fill="url(#mapBg)"/>
<circle cx="120" cy="120" r="112" fill="url(#mapSheen)"/>
<!-- Декоративные точки вокруг -->
<circle cx="46" cy="62" r="4" fill="#FFFFFF" opacity="0.45"/>
<circle cx="196" cy="58" r="3" fill="#FFFFFF" opacity="0.55"/>
<circle cx="58" cy="188" r="3" fill="#FFFFFF" opacity="0.5"/>
<circle cx="200" cy="184" r="4" fill="#FFFFFF" opacity="0.4"/>
<circle cx="34" cy="124" r="2.5" fill="#FFFFFF" opacity="0.5"/>
<circle cx="210" cy="130" r="2.5" fill="#FFFFFF" opacity="0.5"/>
<!-- "Карта" — белая карточка со скруглёнными краями -->
<g transform="translate(36 44)">
<rect x="0" y="0" width="168" height="152" rx="20" ry="20" fill="#FFFFFF"/>
<!-- Сетка улиц (приглушённая) -->
<g stroke="#FFE2D3" stroke-width="2" stroke-linecap="round">
<line x1="0" y1="32" x2="168" y2="32"/>
<line x1="0" y1="62" x2="168" y2="62"/>
<line x1="0" y1="96" x2="168" y2="96"/>
<line x1="0" y1="126" x2="168" y2="126"/>
<line x1="40" y1="0" x2="40" y2="152"/>
<line x1="84" y1="0" x2="84" y2="152"/>
<line x1="128" y1="0" x2="128" y2="152"/>
</g>
<!-- Главная дорога — оранжевая -->
<path d="M0 78 Q 60 70 84 80 T 168 76" stroke="#FFB58A" stroke-width="6" fill="none" stroke-linecap="round"/>
<!-- Река/парк -->
<path d="M0 110 Q 40 100 70 112 T 168 108" stroke="#FFD8C2" stroke-width="8" fill="none" stroke-linecap="round" opacity="0.7"/>
<!-- Маленькие здания -->
<rect x="14" y="14" width="14" height="10" rx="2" fill="#F5F5F7"/>
<rect x="50" y="42" width="16" height="12" rx="2" fill="#F5F5F7"/>
<rect x="100" y="16" width="12" height="9" rx="2" fill="#F5F5F7"/>
<rect x="138" y="42" width="18" height="12" rx="2" fill="#F5F5F7"/>
<rect x="14" y="130" width="14" height="12" rx="2" fill="#F5F5F7"/>
<rect x="100" y="132" width="14" height="10" rx="2" fill="#F5F5F7"/>
<rect x="140" y="128" width="16" height="14" rx="2" fill="#F5F5F7"/>
</g>
<!-- Свечение вокруг пина -->
<circle cx="120" cy="118" r="58" fill="url(#pinGlow)"/>
<!-- Тень под пином -->
<ellipse cx="120" cy="186" rx="14" ry="4" fill="url(#pinShadow)"/>
<!-- Пин-маркер (большой, по центру) -->
<g transform="translate(120 118)">
<!-- Внешняя капля -->
<path d="M0 -42 C 16 -42 24 -28 24 -16 C 24 -2 12 12 0 28 C -12 12 -24 -2 -24 -16 C -24 -28 -16 -42 0 -42 Z"
fill="#1C1C1E"/>
<!-- Внутренний круг -->
<circle cx="0" cy="-16" r="11" fill="#FF6B35"/>
<!-- Белая точка по центру -->
<circle cx="0" cy="-16" r="4" fill="#FFFFFF"/>
</g>
<!-- Маленькие "компании рядом" — аватары-пины -->
<g transform="translate(64 156)">
<circle cx="0" cy="0" r="14" fill="#1C1C1E"/>
<circle cx="0" cy="0" r="11" fill="#FFD8C2"/>
<circle cx="0" cy="-2" r="3.5" fill="#1C1C1E"/>
<path d="M-7 7 Q 0 1 7 7 L 7 9 L -7 9 Z" fill="#1C1C1E"/>
</g>
<g transform="translate(176 154)">
<circle cx="0" cy="0" r="14" fill="#1C1C1E"/>
<circle cx="0" cy="0" r="11" fill="#FFFFFF"/>
<circle cx="0" cy="-2" r="3.5" fill="#FF6B35"/>
<path d="M-7 7 Q 0 1 7 7 L 7 9 L -7 9 Z" fill="#FF6B35"/>
</g>
<!-- Радиус-дуга "рядом" -->
<path d="M 64 156 A 60 60 0 0 1 176 154" stroke="#FFFFFF" stroke-width="2" stroke-dasharray="3 4" fill="none" opacity="0.55"/>
</svg>