Проблема: 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.
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
api.js был написан как ES module ("export async function") но подключён
как обычный <script>. Safari WebKit не поднимает export'ы на window.
Переписан на обычный const/async function с window.API в конце.
- api.js полностью переписан: simple fetch с credentials:'include', без mode:cors
- emailLogin: без 150мс паузы, без retry — same-origin не висит
- nginx: /api/* → backend через тот же домен (убирает cross-subdomain)
- backend cookie: SameSite=Lax, host-only
Анализ 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
- L.tileLayer 2GIS
- PlacesApi.nearby() в client
- Кнопка 'Показать/Скрыть бары'
- Маркеры баров с эмодзи (🍺🍽️☕🎉)
- Список под картой (карточки)
- Invite to place: отправка предложения в чат
- 2GIS deeplink в сообщении
- 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