mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
feat: Yandex Metrika CID tracking, offline conversions UI, sticky pay button
- Pass yandex_cid to all auth endpoints (telegram, email, OIDC, OAuth) - Add OfflineConvGoal interface and offline_conv_* fields to AnalyticsCounters - Add storeYandexCid API method for server-side CID persistence - Add analytics fields to LandingConfig (view/click goals, sticky_pay_button) - Add yandex_cid/referrer/subid to PurchaseRequest - Add offline conversions UI block in admin AnalyticsTab - Add cacheYandexCid, syncYandexCid, fireAnalyticsEvent to analytics hook - Create yandexCid.ts utility (localStorage get/set helpers) - Add sticky pay button with portal on mobile in QuickPurchase - Fire view/click analytics goals on landing pages - Persist contact value and referrer/subid in session/localStorage - Add i18n keys for offlineConv and apiKey in all 4 locales
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import apiClient from './client';
|
||||
import { getYandexCid } from '../utils/yandexCid';
|
||||
import type {
|
||||
AuthResponse,
|
||||
LinkCallbackResponse,
|
||||
@@ -22,6 +23,7 @@ export const authApi = {
|
||||
init_data: initData,
|
||||
campaign_slug: campaignSlug || undefined,
|
||||
referral_code: referralCode || undefined,
|
||||
yandex_cid: getYandexCid() || undefined,
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
@@ -43,6 +45,7 @@ export const authApi = {
|
||||
...data,
|
||||
campaign_slug: campaignSlug || undefined,
|
||||
referral_code: referralCode || undefined,
|
||||
yandex_cid: getYandexCid() || undefined,
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
@@ -56,6 +59,7 @@ export const authApi = {
|
||||
id_token: idToken,
|
||||
campaign_slug: campaignSlug || undefined,
|
||||
referral_code: referralCode || undefined,
|
||||
yandex_cid: getYandexCid() || undefined,
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
@@ -71,6 +75,7 @@ export const authApi = {
|
||||
password,
|
||||
campaign_slug: campaignSlug || undefined,
|
||||
referral_code: referralCode || undefined,
|
||||
yandex_cid: getYandexCid() || undefined,
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
@@ -87,6 +92,7 @@ export const authApi = {
|
||||
const response = await apiClient.post('/cabinet/auth/email/register', {
|
||||
email,
|
||||
password,
|
||||
yandex_cid: getYandexCid() || undefined,
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
@@ -101,7 +107,7 @@ export const authApi = {
|
||||
}): Promise<RegisterResponse> => {
|
||||
const response = await apiClient.post<RegisterResponse>(
|
||||
'/cabinet/auth/email/register/standalone',
|
||||
data,
|
||||
{ ...data, yandex_cid: getYandexCid() || undefined },
|
||||
);
|
||||
return response.data;
|
||||
},
|
||||
@@ -198,6 +204,7 @@ export const authApi = {
|
||||
device_id: deviceId || undefined,
|
||||
campaign_slug: campaignSlug || undefined,
|
||||
referral_code: referralCode || undefined,
|
||||
yandex_cid: getYandexCid() || undefined,
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
|
||||
@@ -38,10 +38,20 @@ export interface TelegramWidgetConfig {
|
||||
oidc_client_id: string;
|
||||
}
|
||||
|
||||
export interface OfflineConvGoal {
|
||||
name: string;
|
||||
event_id: string;
|
||||
dedup: string;
|
||||
}
|
||||
|
||||
export interface AnalyticsCounters {
|
||||
yandex_metrika_id: string;
|
||||
google_ads_id: string;
|
||||
google_ads_label: string;
|
||||
offline_conv_enabled?: boolean;
|
||||
offline_conv_counter_id?: string;
|
||||
offline_conv_measurement_secret_masked?: string;
|
||||
offline_conv_goals?: OfflineConvGoal[];
|
||||
}
|
||||
|
||||
const BRANDING_CACHE_KEY = 'cabinet_branding';
|
||||
@@ -274,7 +284,14 @@ export const brandingApi = {
|
||||
const response = await apiClient.get<AnalyticsCounters>('/cabinet/branding/analytics');
|
||||
return response.data;
|
||||
} catch {
|
||||
return { yandex_metrika_id: '', google_ads_id: '', google_ads_label: '' };
|
||||
return {
|
||||
yandex_metrika_id: '',
|
||||
google_ads_id: '',
|
||||
google_ads_label: '',
|
||||
offline_conv_enabled: false,
|
||||
offline_conv_counter_id: '',
|
||||
offline_conv_goals: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@@ -303,4 +320,9 @@ export const brandingApi = {
|
||||
const response = await apiClient.patch<AnalyticsCounters>('/cabinet/branding/analytics', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Store Yandex Metrika ClientID for the authenticated cabinet user
|
||||
storeYandexCid: async (cid: string): Promise<void> => {
|
||||
await apiClient.post('/cabinet/branding/analytics/yandex-cid', { cid });
|
||||
},
|
||||
};
|
||||
|
||||
@@ -89,6 +89,12 @@ export interface LandingConfig {
|
||||
meta_description: string | null;
|
||||
discount: LandingDiscountInfo | null;
|
||||
background_config: AnimationConfig | null;
|
||||
// Per-landing analytics goals + sticky pay button (bot PR #2852 backend fields)
|
||||
analytics_view_enabled?: boolean;
|
||||
analytics_view_goal?: string | null;
|
||||
analytics_click_enabled?: boolean;
|
||||
analytics_click_goal?: string | null;
|
||||
sticky_pay_button?: boolean;
|
||||
}
|
||||
|
||||
export interface PurchaseRequest {
|
||||
@@ -102,6 +108,10 @@ export interface PurchaseRequest {
|
||||
gift_recipient_value?: string;
|
||||
gift_message?: string;
|
||||
language?: string;
|
||||
// Yandex offline-conversions linkage (bot PR #2851 backend fields)
|
||||
yandex_cid?: string;
|
||||
referrer?: string;
|
||||
subid?: string;
|
||||
}
|
||||
|
||||
export interface PurchaseResponse {
|
||||
|
||||
Reference in New Issue
Block a user