feat: partner-campaign integration in admin UI

- Add partner badge to campaigns list
- Add partner selector dropdown in campaign edit
- Support ?partnerId= query param in campaign create (replaces separate page)
- Filter already-assigned campaigns in partner assign flow
- Show taken campaigns greyed out with partner name
- Delete AdminPartnerCampaignCreate (replaced by query param approach)
- Add partner translations (ru, en, zh, fa)
This commit is contained in:
Fringg
2026-02-18 06:47:07 +03:00
parent 76d20fdb1a
commit 959f89266b
12 changed files with 201 additions and 207 deletions

View File

@@ -17,6 +17,8 @@ export interface CampaignListItem {
registrations_count: number;
total_revenue_kopeks: number;
conversion_rate: number;
partner_user_id: number | null;
partner_name: string | null;
created_at: string;
}
@@ -40,6 +42,8 @@ export interface CampaignDetail {
tariff_id: number | null;
tariff_duration_days: number | null;
tariff: TariffInfo | null;
partner_user_id: number | null;
partner_name: string | null;
created_by: number | null;
created_at: string;
updated_at: string | null;
@@ -59,6 +63,7 @@ export interface CampaignCreateRequest {
subscription_squads?: string[];
tariff_id?: number;
tariff_duration_days?: number;
partner_user_id?: number | null;
}
export interface CampaignUpdateRequest {
@@ -73,6 +78,7 @@ export interface CampaignUpdateRequest {
subscription_squads?: string[];
tariff_id?: number;
tariff_duration_days?: number;
partner_user_id?: number | null;
}
export interface CampaignToggleResponse {
@@ -159,6 +165,12 @@ export interface TariffListItem {
device_limit: number;
}
export interface AvailablePartner {
user_id: number;
username: string | null;
first_name: string | null;
}
export const campaignsApi = {
// Get campaigns overview
getOverview: async (): Promise<CampaignsOverview> => {
@@ -240,4 +252,10 @@ export const campaignsApi = {
const response = await apiClient.get('/cabinet/admin/campaigns/available-tariffs');
return response.data;
},
// Get available partners for campaign assignment
getAvailablePartners: async (): Promise<AvailablePartner[]> => {
const response = await apiClient.get('/cabinet/admin/campaigns/available-partners');
return response.data;
},
};