Files
tgex-frontend/lib/demo/hooks.ts
2025-12-29 10:12:13 +03:00

273 lines
6.9 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 === "active"
);
const totalCost = projectPlacements.reduce(
(sum, p) => sum + (p.cost || 0),
0
);
const totalSubs = projectPlacements.reduce(
(sum, p) => sum + (p.subscriptions_count || 0),
0
);
const totalViews = projectPlacements.reduce(
(sum, p) => sum + (p.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),
},
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.placement_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 };
};