Commit Graph

43 Commits

Author SHA1 Message Date
root
53bf382b84 Fix: ensureChat ответ {id,user_a,user_b}, не {chat_id} 2026-08-21 12:12:33 +00:00
root
34d4292538 Feature: UserProfileView показывает prefs (drinks/activities/purposes)
Бэк уже отдает prefs в публичном /users/:id, но фронт не доставал.

UserProfileView:
- Принимает u.prefs.{drinks,activities,purposes}
- Словари вынесены в глобальные DRINKS/ACTIVITIES/PURPOSES (используются ProfileView и UserProfileView)
- Рендерит три секции card-b с .chip.on: 'Что пьёт' / 'Чем занимается' / 'Цели'
- Скрывает секцию если массив пуст
2026-08-21 12:11:20 +00:00
root
e6d8ad0ee0 Fix: TDZ 'u' в UserProfileView console.log 2026-08-21 12:08:20 +00:00
root
2d560694c1 Fix: window.API без UserApi → /users/:id undefined 2026-08-21 12:07:38 +00:00
root
d5bf42a913 Debug: UserProfileView логирует ошибки через /debug/log 2026-08-21 12:06:28 +00:00
root
31a39d7436 Debug: console.log в UserProfileView + selfMarker → Profile 2026-08-21 12:03:58 +00:00
root
f6fa3fedab Fix: UserProfileView для тапа на маркер человека
Проблема: app.js вызывал UserProfileView.render при showView('user-profile'),
но view был не создан. ReferenceError.

Создал UserProfileView в profile.js:
- Читает /users/:id + /users/:id/stats
- Card с avatar-b.lg, name, city, ★ rating (если есть отзывы)
- bio
- Кнопки: 'Написать' (ensureChat → openChat) + 'Все отзывы' (UserReviewsView)
- Error/toast на любой сбой

API: добавил UserApi.get|reviews|stats namespace.
2026-08-21 11:59:09 +00:00
root
c5f8ac67ad UX overhaul: единый стиль BuhApp на всех экранах
ДИЗАЙН-СИСТЕМА в app.css:
- --primary #FF6B35, --success #3dd68c, --danger #ff5c5c
- --bg #0f0f12, --bg-elev #1a1a22, --bg-input #121218
- Компоненты: .card-b, .row-b, .field-b, .btn-b, .switch-b, .chip, .avatar-b, .bubble-b, .composer-b, .toast-b, .stars-b, .pulse-b, .empty-b

ПЕРЕПИСАНЫ на единый стиль:

Settings:
- Карточка с аватаром пользователя
- Card-row для юр.документов (📄 / 🔒 / ⚠️)
- 'Выйти' — danger btn-b с state machine (idle→load→ok)

Profile:
- Карточка аватара + кнопка 'Загрузить фото' через multipart /api/v1/me/photo
- Поля: field-b (ctrl + hint)
- Чипы в chip-list, новый стиль с .on
- Счётчик bio символов
- 'Сохранить' со state machine + toast

Review (создание):
- Звёзды в stars-b с center hint
- textarea с counter
- switch-b 'Анонимно' (вместо checkbox)
- Submit со state machine + toast 'Спасибо за отзыв!'

UserReviews:
- Средний рейтинг + звёзды
- Список карточек с отзывами

Chats:
- Список с avatar-b + last message + время + badge непрочитанных
- Пустое состояние с эмодзи
- formatChatTime() — 'сейчас' / '5м' / '3ч' / '2д'

Chat (один):
- Header с аватаром и кнопками 👤 ⭐
- composer-b: 📎 + input + ➤ (sticky bottom)
- bubble-b .in / .out с .ticks.read
- Send со state + toast
- sendPhoto() для фоток в чате

App.js _toast(msg, kind):
- Единый toast-b с классами ok / err

Всё в одном стиле. CSS variables, padding 16, radius 14, no disabled кнопок.
2026-08-21 11:42:16 +00:00
root
2b34791ff0 Fix: пароль ≥8 (бэк требует 8) 2026-08-21 11:33:58 +00:00
root
9188088276 UX: Auth как в Grok — табы Вход/Регистрация, живая валидация, toast
НОВЫЙ UX (от Grok):
- Один экран — табы Вход / Регистрация (мгновенное переключение)
- Все поля видны, кнопка всегда кликабельна
- Валидация в реальном времени: под каждым полем ✓/✗ с пояснением
- Состояния кнопки: idle / load ('⏳ Создаём...') / ok ('✓ Готово!') / err ('⚠️ ...')
- Toast 'Добро пожаловать, [имя]!' после успеха
- При ошибке: подсветка проблемного поля + фокус на нём
- Email живая валидация (regex), пароль ≥6 (как требует Grok / API: ≥8 → я ставлю 8 для совместимости с бэком)
- Пароль 2 — только в режиме Регистрация
- Переключение режима сбрасывает валидацию, фокус на первое пустое поле

CSS новые классы: .btn.ok, .btn.load, .btn.err, input.bad, input.good, .hint.ok/err/mute

Технически:
- showEmailLogin() рисует сразу табы + форму
- _initAuthForm() биндит всё
- _submitAuth(mode) делает реальный запрос
- showEmailRegister() → переключает таб на 'Регистрация'
2026-08-21 11:33:31 +00:00
root
a2cc623756 Fix session persistence + полный рерайт регистрации
FIX SESSION:
- Store.save() теперь сохраняет в localStorage ('buhapp_session_v1')
- Store.load() восстанавливает access+refresh
- Store.clear() чистит и память и localStorage
- При загрузке api.js сразу Store.load() — сессия восстанавливается автоматически
- При refresh страницы init() видит Store.access и сразу делает me()

REGISTRATION REDO:
- Отдельный экран showEmailRegister() (не на том же экране что login)
- Поля: имя, email, пароль, пароль2, 18+, соглашения, запомнить
- Полная валидация в реальном времени (имя не пустое, email валидный,
  пароль ≥8, пароли совпадают, чекбоксы отмечены)
- Кнопка disabled пока форма не готова, hint показывает что не так
- После успешной регистрации: сразу показ 'Добро пожаловать!' + переход на карту
- Ошибка от сервера — показывается в hint + подсветка поля email красным
- Удалён старый emailRegisterPre и дублирующий emailRegister
2026-08-21 11:24:47 +00:00
root
1f02bf04e5 Refactor: Leaflet → MapLibre GL 2026-08-21 11:20:37 +00:00
root
8016e2976e Feature: Запомнить меня (cookie 30 дней)
- HTML: <input type=checkbox id='el-remember' checked>
- api.js: loginEmail(email, password, remember)
- app.js: emailLogin/register читают флаг и шлют в /auth/login
- backend: remember=true → accessTTL=30дн, false → 1ч
2026-08-21 11:18:59 +00:00
root
f72f890076 Fix: ?v=20 cache-bust + правильный порядок scripts 2026-08-21 11:12:49 +00:00
root
ab6320dff8 Fix: api.js без ES modules — Safari iOS не видит export
api.js был написан как ES module ("export async function") но подключён
как обычный <script>. Safari WebKit не поднимает export'ы на window.

Переписан на обычный const/async function с window.API в конце.
2026-08-21 11:10:12 +00:00
root
058649013d Fix login: same-origin proxy + minimal api.js + без retry/timeout
- api.js полностью переписан: simple fetch с credentials:'include', без mode:cors
- emailLogin: без 150мс паузы, без retry — same-origin не висит
- nginx: /api/* → backend через тот же домен (убирает cross-subdomain)
- backend cookie: SameSite=Lax, host-only
2026-08-21 11:04:11 +00:00
root
8fce24104d Fix Safari: Connection:close + SameSite=None + cache:no-store + 150ms delay
Анализ Grok: Safari зависает на ответе fetch после POST с Set-Cookie из-за keep-alive/HTTP2 reuse.
- backend Login/Register: Connection: close, Cache-Control: no-store
- backend cookie: SameSite=None (cross-subdomain в Safari)
- frontend api(): cache:'no-store', mode:'cors', timeout 20s
- frontend emailLogin: 150ms пауза после login перед следующим fetch
2026-08-21 10:57:09 +00:00
root
0fa3dcc573 UI: таббар скрыт пока не залогинился
- index.html: <nav id="tabbar" hidden>
- app.js: updateTabbar() — скрыть/показать по loggedIn
- emailLogin: onLogin() после успеха
- settings.logout: onLogout() + POST /auth/logout
- backend: POST /auth/logout — чистит cookie
2026-08-20 22:12:20 +00:00
root
2af273ffbe Fix TG WebApp: isAvailable только если есть initData
Раньше isAvailable=true если window.Telegram.WebApp объект существовал
(SDK грузится всегда). Но методы кидали WebAppMethodUnsupported вне Telegram.

Теперь: isAvailable=true только если есть initData (мы внутри Telegram)
Все методы (close, sendData, haptic, showAlert, showConfirm) — early return если не внутри Telegram.
2026-08-20 22:06:11 +00:00
root
d44eb2be8d Fix: только cookie auth (без Authorization) — все запросы без preflight
- api.js: убрал Authorization header для всех методов (cookie достаточно)
- убрал refresh block (cookie живёт дольше)
- profile.save: явный feedback ("⏳ Сохраняю..." → "✓ Сохранено") + try/catch вокруг TG_APP.haptic
2026-08-20 22:04:27 +00:00
root
ce3c863e66 Profile: try/catch в renderChips click + console.error при отсутствии el 2026-08-20 21:58:35 +00:00
root
fd8f6b38d0 Min fix: credentials:'include' + Authorization только для мутаций
GET использует cookie (без preflight), POST/PUT/DELETE — Authorization Bearer
2026-08-20 21:56:02 +00:00
root
06c8f8b593 Fix: tab switching hangs on iOS Safari
- showView: requestAnimationFrame + мгновенный loader (UI не висит)
- maybeOnboard на старте fire-and-forget (не блокирует init)
- MapView: НЕ запрашивает геолокацию автоматически (только по кнопке)
- MapView: правильно destroy map если container удалён (нет утечки Leaflet)
- invalidateSize() перед setView чтобы тайлы 2GIS догрузились
2026-08-20 21:28:33 +00:00
root
000206426f Map: явный синий маркер 'Я' + invalidateSize + zoom 14 2026-08-20 21:23:01 +00:00
root
4706203de8 Fix: onboarding overlay не сносит #app (#app удалялся root.innerHTML='')
- Убрал root.innerHTML='' в OnboardingView.render
- Оверлей теперь fixed/absolute поверх body — лейаут не страдает
- App.showView('map') после пропуска находит #app нормально
2026-08-20 21:21:14 +00:00
root
75b9fc018f Debug: add error overlay + App.init catch 2026-08-20 21:19:18 +00:00
root
7a27b2cf3f Map: 2GIS tiles + places (бары/рестораны)
- L.tileLayer 2GIS
- PlacesApi.nearby() в client
- Кнопка 'Показать/Скрыть бары'
- Маркеры баров с эмодзи (🍺🍽️☕🎉)
- Список под картой (карточки)
- Invite to place: отправка предложения в чат
- 2GIS deeplink в сообщении
2026-08-20 21:12:05 +00:00
root
4cc8858a25 UX Sprint: consent before register + welcome screen
- showWelcome() first screen for non-Telegram users
- 'Open in Telegram' CTA + 'or use email' button
- emailRegister shows consent overlay BEFORE API call
- After consent accept, registers and continues with onboarding
- Bumped consent UX: 4 checkboxes + legal links
- escapeHtml: quotes added to avoid edge XSS
2026-08-20 20:59:53 +00:00
root
7fa2dc83e4 UX fixes: auto geolocation, read-ticks, pulse animation
- Map: auto-request geolocation on view enter (no manual click needed)
- Map: pulse animation on 'Share location' button (calls attention)
- Map: better error message on permission denied (with link to settings)
- Map: 'loading...' state on radius change
- Chat: ✓ / ✓✓ read marks on own messages (from m.read_at)
- Chat: WS handler for 'message_read' event (real-time update)
- Chat: enterkeyhint='send' on input (mobile keyboard send button)
- Chat: send on Enter key (no shift)
- CSS: btn-pulse animation
- CSS: read-tick styles
2026-08-20 20:45:27 +00:00
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
root
7182e6828b Fix geolocation: button-triggered, error messages in Russian 2026-08-20 18:45:42 +00:00
root
31c53cd8d5 Fix: leaflet.js local, consent status check, OSM direct tile URL
- vendor/leaflet.js (no more CDN dependency for JS)
- direct tile.openstreetmap.org (was {s}.tile)
- backend GET /api/v1/auth/consents (check if all accepted)
- frontend ConsentApi.status() before showing overlay
- only show overlay once
2026-08-20 18:43:19 +00:00
root
6d98fc90eb Full CSS rewrite: fix layout, prevent Leaflet overflow, mobile frame 2026-08-20 18:40:21 +00:00
root
9d3a0c783b Fix consent overlay: relative to mobile-frame, not body 2026-08-20 18:38:43 +00:00
root
cb05669c7c Fix auth: backend returns Access/Refresh (CamelCase), JS expected access/refresh
Store.save() now handles both cases. Refresh endpoint uses 'Refresh' key.
This was causing /me 401 right after register.
2026-08-20 18:36:41 +00:00
root
e5dceb250b Debug register button: log to console, show clear error 2026-08-20 18:02:04 +00:00
root
41019d476d Fix registration button: enable when email+8+ chars; show hint 2026-08-20 18:00:50 +00:00
root
be8d196734 Fix mobile frame: tabbar inside frame, button visible, proper layout 2026-08-20 17:58:30 +00:00
root
d87e0bafa0 Make mode toggle visible: orange button, z-index 9999, hidden on real mobile 2026-08-20 17:57:19 +00:00
root
05254ec339 Fix mode toggle: don't reload, just swap class 2026-08-20 17:56:03 +00:00
root
ffbc917a5d Add mobile emulator mode for desktop testing
- 390px-wide frame on desktop, mimics mobile Telegram
- Toggle button (top-right): 'Mobile' / 'Fullscreen'
- Auto-detects screen width, remembers choice in localStorage
- Real mobile (≤768px) uses native layout
2026-08-20 17:54:45 +00:00
root
897fc4cd31 Add email login fallback (for testing outside Telegram)
WebApp detects if Telegram SDK is missing, shows email login form
so we can test without the bot running.
2026-08-20 17:52:38 +00:00
root
21d281a1c6 Telegram WebApp: Mini App with map, chats, profile, reviews
- index.html with bottom tabbar (Map/Chats/Profile/Settings)
- Telegram WebApp SDK auth via /api/v1/auth/telegram
- Consent gate on first login (4 checkboxes)
- Map view with Leaflet (OSM) + nearby users + radius selector
- Chat list + single chat with WebSocket realtime
- Profile editing (drinks, activities, purposes)
- Review screen with stars + anonymous toggle
- User reviews list with stats
- User profile (public) with rating, write/block/report
- Legal pages (TERMS / PRIVACY / DISCLAIMER)
2026-08-20 17:43:16 +00:00