feat: global ui & functional update
This commit is contained in:
@@ -8,6 +8,7 @@ import { ru } from "date-fns/locale";
|
||||
import { isDemoWorkspace, DEMO_WORKSPACE_ID } from "./constants";
|
||||
import {
|
||||
demoChannels,
|
||||
demoPlacementChannels,
|
||||
demoCreatives,
|
||||
demoPlacements,
|
||||
demoPurchasePlanChannels,
|
||||
@@ -124,6 +125,17 @@ export const demoAwareProjectsApi = {
|
||||
}
|
||||
return projectsApi.archive(workspaceId, projectId);
|
||||
},
|
||||
unarchive: async (
|
||||
workspaceId: string,
|
||||
projectId: string
|
||||
): Promise<Project> => {
|
||||
if (isDemoWorkspace(workspaceId)) {
|
||||
const project = demoProjects.find(p => p.id === projectId);
|
||||
if (!project) throw new Error("Project not found");
|
||||
return { ...project, status: "active" };
|
||||
}
|
||||
return projectsApi.unarchive(workspaceId, projectId);
|
||||
},
|
||||
delete: async (
|
||||
workspaceId: string,
|
||||
projectId: string
|
||||
@@ -138,6 +150,19 @@ export const demoAwareProjectsApi = {
|
||||
}
|
||||
return projectsApi.delete(workspaceId, projectId);
|
||||
},
|
||||
move: async (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
data: { target_workspace_id: string }
|
||||
): Promise<Project> => {
|
||||
if (isDemoWorkspace(workspaceId)) {
|
||||
const project = demoProjects.find(p => p.id === projectId);
|
||||
if (!project) throw new Error("Project not found");
|
||||
// In demo mode, just return the project (mock move)
|
||||
return project;
|
||||
}
|
||||
return projectsApi.move(workspaceId, projectId, data);
|
||||
},
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
@@ -234,14 +259,14 @@ export const demoAwarePlacementsApi = {
|
||||
}
|
||||
if (params?.placement_channel_id) {
|
||||
items = items.filter(
|
||||
(p) => p.placement_channel_id === params.placement_channel_id
|
||||
(p) => p.channel.id === params.placement_channel_id
|
||||
);
|
||||
}
|
||||
if (params?.creative_id) {
|
||||
items = items.filter((p) => p.creative_id === params.creative_id);
|
||||
}
|
||||
if (!params?.include_archived) {
|
||||
items = items.filter((p) => p.status === "active");
|
||||
items = items.filter((p) => p.status !== "Отмена" && p.status !== "Неактуально");
|
||||
}
|
||||
return paginate(items, params?.page, params?.size);
|
||||
}
|
||||
@@ -255,6 +280,18 @@ export const demoAwarePlacementsApi = {
|
||||
}
|
||||
return placementsApi.get(workspaceId, placementId);
|
||||
},
|
||||
getByProject: async (workspaceId: string, projectId: string): Promise<Placement[]> => {
|
||||
if (isDemoWorkspace(workspaceId)) {
|
||||
// In demo mode, return all placements for demo project
|
||||
// Filter by demo project id for realistic behavior
|
||||
return demoPlacements.filter((p) => {
|
||||
// For demo purposes, we'll just return all placements
|
||||
// In real usage, this would filter by project_id
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return placementsApi.getByProject(workspaceId, projectId);
|
||||
},
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
@@ -292,18 +329,18 @@ export const demoAwareAnalyticsApi = {
|
||||
if (isDemoWorkspace(workspaceId)) {
|
||||
if (params?.project_id) {
|
||||
const projectPlacements = demoPlacements.filter(
|
||||
(p) => p.project_id === params.project_id && p.status === "active"
|
||||
(p) => p.project_id === params.project_id && p.status !== "Отмена" && p.status !== "Неактуально"
|
||||
);
|
||||
const totalCost = projectPlacements.reduce(
|
||||
(sum, p) => sum + (p.cost || 0),
|
||||
(sum, p) => sum + (p.details?.cost?.value || 0),
|
||||
0
|
||||
);
|
||||
const totalSubs = projectPlacements.reduce(
|
||||
(sum, p) => sum + (p.subscriptions_count || 0),
|
||||
(sum, p) => sum + (p.placement_post?.subscriptions_count || 0),
|
||||
0
|
||||
);
|
||||
const totalViews = projectPlacements.reduce(
|
||||
(sum, p) => sum + (p.views_count || 0),
|
||||
(sum, p) => sum + (p.placement_post?.views_count || 0),
|
||||
0
|
||||
);
|
||||
return {
|
||||
@@ -313,6 +350,7 @@ export const demoAwareAnalyticsApi = {
|
||||
avg_cpf: totalSubs > 0 ? totalCost / totalSubs : null,
|
||||
avg_cpm: totalViews > 0 ? (totalCost / totalViews) * 1000 : null,
|
||||
chart_data: demoSpendingAnalytics.chart_data.slice(0, 4),
|
||||
placements_count: projectPlacements.length,
|
||||
};
|
||||
}
|
||||
return demoSpendingAnalytics;
|
||||
@@ -345,7 +383,7 @@ export const demoAwareAnalyticsApi = {
|
||||
const projectPlacementChannelIds = new Set(
|
||||
demoPlacements
|
||||
.filter((p) => p.project_id === params.project_id)
|
||||
.map((p) => p.placement_channel_id)
|
||||
.map((p) => p.channel.id)
|
||||
);
|
||||
items = items.filter((a) =>
|
||||
projectPlacementChannelIds.has(a.channel_id)
|
||||
@@ -357,13 +395,35 @@ export const demoAwareAnalyticsApi = {
|
||||
},
|
||||
placements: async (
|
||||
workspaceId: string,
|
||||
params?: { project_id?: string; page?: number; size?: number }
|
||||
params?: {
|
||||
project_id?: string;
|
||||
placement_channel_id?: string;
|
||||
creative_id?: string;
|
||||
date_from?: string;
|
||||
date_to?: string;
|
||||
page?: number;
|
||||
size?: number;
|
||||
}
|
||||
): Promise<PaginatedResponse<PlacementAnalyticsItem>> => {
|
||||
if (isDemoWorkspace(workspaceId)) {
|
||||
let items = demoPlacementAnalytics;
|
||||
if (params?.project_id) {
|
||||
items = items.filter((p) => p.project_id === params.project_id);
|
||||
}
|
||||
if (params?.placement_channel_id) {
|
||||
items = items.filter((p) => p.placement_channel_id === params.placement_channel_id);
|
||||
}
|
||||
if (params?.creative_id) {
|
||||
items = items.filter((p) => p.creative_id === params.creative_id);
|
||||
}
|
||||
if (params?.date_from) {
|
||||
const from = new Date(params.date_from);
|
||||
items = items.filter((p) => new Date(p.placement_date) >= from);
|
||||
}
|
||||
if (params?.date_to) {
|
||||
const to = new Date(params.date_to);
|
||||
items = items.filter((p) => new Date(p.placement_date) <= to);
|
||||
}
|
||||
return paginate(items, params?.page, params?.size);
|
||||
}
|
||||
return analyticsApi.placements(workspaceId, params);
|
||||
|
||||
Reference in New Issue
Block a user