feat(auth): чекбоксы согласия с офертой и политикой при первой авторизации

Новый пользователь попадал в кабинет молча — никаких документов ему не показывали.
Теперь при создании аккаунта он подтверждает, что ознакомился с офертой и политикой.

Набор документов и сам факт включения гейта приходят с бэка
(GET /cabinet/info/legal-consent): там же учитывается, заполнены ли документы и
видны ли они в вебе. Фронт знает только ключи и адреса публичных страниц /offer
и /privacy — тех же, что уже линкует футер логина.

Два пути входа устроены по-разному, поэтому и UI разный:
- регистрация по email — чекбоксы прямо в форме, кнопка заблокирована до галочек;
- Telegram-вход происходит сам собой, спрашивать заранее не у чего. Поэтому ловим
  428 от бэка и показываем отдельный экран согласия, а замыкание помнит, какой
  именно вход повторить после простановки галочек. Тот же приём страхует и
  email-форму: конфиг мог протухнуть, если админ включил гейт между загрузкой
  страницы и отправкой.

Неизвестный ключ документа всё равно рисуем (без ссылки): бэк его требует, и молча
спрятанный чекбокс превратился бы в «кнопка не работает и непонятно почему».

Локали ru/en/zh/fa.
This commit is contained in:
Fringg
2026-07-30 00:31:47 +03:00
parent b615927283
commit 0f21629ba5
10 changed files with 319 additions and 16 deletions

View File

@@ -18,12 +18,14 @@ export const authApi = {
initData: string,
campaignSlug?: string | null,
referralCode?: string | null,
acceptedLegalDocuments?: string[],
): Promise<AuthResponse> => {
const response = await apiClient.post<AuthResponse>('/cabinet/auth/telegram', {
init_data: initData,
campaign_slug: campaignSlug || undefined,
referral_code: referralCode || undefined,
yandex_cid: getYandexCid() || undefined,
accepted_legal_documents: acceptedLegalDocuments,
});
return response.data;
},
@@ -40,12 +42,14 @@ export const authApi = {
},
campaignSlug?: string | null,
referralCode?: string | null,
acceptedLegalDocuments?: string[],
): Promise<AuthResponse> => {
const response = await apiClient.post<AuthResponse>('/cabinet/auth/telegram/widget', {
...data,
campaign_slug: campaignSlug || undefined,
referral_code: referralCode || undefined,
yandex_cid: getYandexCid() || undefined,
accepted_legal_documents: acceptedLegalDocuments,
});
return response.data;
},
@@ -54,12 +58,14 @@ export const authApi = {
idToken: string,
campaignSlug?: string | null,
referralCode?: string | null,
acceptedLegalDocuments?: string[],
): Promise<AuthResponse> => {
const response = await apiClient.post<AuthResponse>('/cabinet/auth/telegram/oidc', {
id_token: idToken,
campaign_slug: campaignSlug || undefined,
referral_code: referralCode || undefined,
yandex_cid: getYandexCid() || undefined,
accepted_legal_documents: acceptedLegalDocuments,
});
return response.data;
},
@@ -115,6 +121,7 @@ export const authApi = {
language?: string;
referral_code?: string;
campaign_slug?: string;
accepted_legal_documents?: string[];
}): Promise<RegisterResponse> => {
const response = await apiClient.post<RegisterResponse>(
'/cabinet/auth/email/register/standalone',