274 lines
7.0 KiB
TypeScript
274 lines
7.0 KiB
TypeScript
// ============================================================================
|
|
// Demo Mode Hooks
|
|
// ============================================================================
|
|
|
|
import { useWorkspace } from "@/components/providers/workspace-provider";
|
|
import { demoApi } from "./api";
|
|
import {
|
|
demoChannels,
|
|
demoCreatives,
|
|
demoPlacements,
|
|
demoPurchasePlanChannels,
|
|
demoSpendingAnalytics,
|
|
demoCreativeAnalytics,
|
|
demoChannelAnalytics,
|
|
} from "./mock-data";
|
|
import type {
|
|
Channel,
|
|
Creative,
|
|
Placement,
|
|
PurchasePlanChannel,
|
|
SpendingAnalytics,
|
|
CreativeAnalyticsItem,
|
|
ChannelAnalyticsItem,
|
|
PaginatedResponse,
|
|
} from "@/lib/types/api";
|
|
|
|
// ============================================================================
|
|
// Types
|
|
// ============================================================================
|
|
|
|
interface UseDemoDataResult<T> {
|
|
data: T | null;
|
|
isDemo: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Hook: Check if should use demo mode
|
|
// ============================================================================
|
|
|
|
export const useIsDemoMode = (): boolean => {
|
|
const { isDemoMode } = useWorkspace();
|
|
return isDemoMode;
|
|
};
|
|
|
|
// ============================================================================
|
|
// Hook: Get demo channels
|
|
// ============================================================================
|
|
|
|
export const useDemoChannels = (): UseDemoDataResult<PaginatedResponse<Channel>> => {
|
|
const { isDemoMode } = useWorkspace();
|
|
|
|
if (isDemoMode) {
|
|
return {
|
|
data: {
|
|
items: demoChannels,
|
|
total: demoChannels.length,
|
|
page: 1,
|
|
size: 50,
|
|
pages: 1,
|
|
},
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return { data: null, isDemo: false };
|
|
};
|
|
|
|
// ============================================================================
|
|
// Hook: Get demo creatives
|
|
// ============================================================================
|
|
|
|
export const useDemoCreatives = (
|
|
projectId?: string
|
|
): UseDemoDataResult<PaginatedResponse<Creative>> => {
|
|
const { isDemoMode } = useWorkspace();
|
|
|
|
if (isDemoMode) {
|
|
let items = demoCreatives;
|
|
if (projectId) {
|
|
items = items.filter((c) => c.project_id === projectId);
|
|
}
|
|
|
|
return {
|
|
data: {
|
|
items,
|
|
total: items.length,
|
|
page: 1,
|
|
size: 50,
|
|
pages: 1,
|
|
},
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return { data: null, isDemo: false };
|
|
};
|
|
|
|
// ============================================================================
|
|
// Hook: Get demo placements
|
|
// ============================================================================
|
|
|
|
export const useDemoPlacements = (
|
|
projectId?: string
|
|
): UseDemoDataResult<PaginatedResponse<Placement>> => {
|
|
const { isDemoMode } = useWorkspace();
|
|
|
|
if (isDemoMode) {
|
|
let items = demoPlacements;
|
|
if (projectId) {
|
|
items = items.filter((p) => p.project_id === projectId);
|
|
}
|
|
|
|
return {
|
|
data: {
|
|
items,
|
|
total: items.length,
|
|
page: 1,
|
|
size: 50,
|
|
pages: 1,
|
|
},
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return { data: null, isDemo: false };
|
|
};
|
|
|
|
// ============================================================================
|
|
// Hook: Get demo purchase plan
|
|
// ============================================================================
|
|
|
|
export const useDemoPurchasePlan = (
|
|
projectId: string
|
|
): UseDemoDataResult<PaginatedResponse<PurchasePlanChannel>> => {
|
|
const { isDemoMode } = useWorkspace();
|
|
|
|
if (isDemoMode) {
|
|
const items = demoPurchasePlanChannels[projectId] || [];
|
|
|
|
return {
|
|
data: {
|
|
items,
|
|
total: items.length,
|
|
page: 1,
|
|
size: 50,
|
|
pages: 1,
|
|
},
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return { data: null, isDemo: false };
|
|
};
|
|
|
|
// ============================================================================
|
|
// Hook: Get demo spending analytics
|
|
// ============================================================================
|
|
|
|
export const useDemoSpendingAnalytics = (
|
|
projectId?: string
|
|
): UseDemoDataResult<SpendingAnalytics> => {
|
|
const { isDemoMode } = useWorkspace();
|
|
|
|
if (isDemoMode) {
|
|
if (projectId) {
|
|
// Filter by project
|
|
const projectPlacements = demoPlacements.filter(
|
|
(p) => p.project_id === projectId && p.status !== "Отмена" && p.status !== "Неактуально"
|
|
);
|
|
const totalCost = projectPlacements.reduce(
|
|
(sum, p) => sum + (p.details?.cost?.value || 0),
|
|
0
|
|
);
|
|
const totalSubs = projectPlacements.reduce(
|
|
(sum, p) => sum + (p.placement_post?.subscriptions_count || 0),
|
|
0
|
|
);
|
|
const totalViews = projectPlacements.reduce(
|
|
(sum, p) => sum + (p.placement_post?.views_count || 0),
|
|
0
|
|
);
|
|
|
|
return {
|
|
data: {
|
|
total_cost: totalCost,
|
|
total_subscriptions: totalSubs,
|
|
total_views: totalViews,
|
|
avg_cpf: totalSubs > 0 ? totalCost / totalSubs : null,
|
|
avg_cpm: totalViews > 0 ? (totalCost / totalViews) * 1000 : null,
|
|
chart_data: demoSpendingAnalytics.chart_data.slice(0, 3),
|
|
placements_count: 12,
|
|
},
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return {
|
|
data: demoSpendingAnalytics,
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return { data: null, isDemo: false };
|
|
};
|
|
|
|
// ============================================================================
|
|
// Hook: Get demo creative analytics
|
|
// ============================================================================
|
|
|
|
export const useDemoCreativeAnalytics = (
|
|
projectId?: string
|
|
): UseDemoDataResult<PaginatedResponse<CreativeAnalyticsItem>> => {
|
|
const { isDemoMode } = useWorkspace();
|
|
|
|
if (isDemoMode) {
|
|
let items = demoCreativeAnalytics;
|
|
if (projectId) {
|
|
const projectCreativeIds = demoCreatives
|
|
.filter((c) => c.project_id === projectId)
|
|
.map((c) => c.id);
|
|
items = items.filter((a) => projectCreativeIds.includes(a.id));
|
|
}
|
|
|
|
return {
|
|
data: {
|
|
items,
|
|
total: items.length,
|
|
page: 1,
|
|
size: 50,
|
|
pages: 1,
|
|
},
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return { data: null, isDemo: false };
|
|
};
|
|
|
|
// ============================================================================
|
|
// Hook: Get demo channel analytics
|
|
// ============================================================================
|
|
|
|
export const useDemoChannelAnalytics = (
|
|
projectId?: string
|
|
): UseDemoDataResult<PaginatedResponse<ChannelAnalyticsItem>> => {
|
|
const { isDemoMode } = useWorkspace();
|
|
|
|
if (isDemoMode) {
|
|
let items = demoChannelAnalytics;
|
|
if (projectId) {
|
|
const projectPlacementChannelIds = new Set(
|
|
demoPlacements
|
|
.filter((p) => p.project_id === projectId)
|
|
.map((p) => p.channel.id)
|
|
);
|
|
items = items.filter((a) => projectPlacementChannelIds.has(a.channel_id));
|
|
}
|
|
|
|
return {
|
|
data: {
|
|
items,
|
|
total: items.length,
|
|
page: 1,
|
|
size: 50,
|
|
pages: 1,
|
|
},
|
|
isDemo: true,
|
|
};
|
|
}
|
|
|
|
return { data: null, isDemo: false };
|
|
};
|
|
|