// ============================================================================ // Demo-Aware API Wrapper // ============================================================================ // This wrapper checks if the workspace is demo and returns mock data instead import { isDemoWorkspace, DEMO_WORKSPACE_ID } from "./constants"; import { demoChannels, demoCreatives, demoPlacements, demoPurchasePlanChannels, demoSpendingAnalytics, demoCreativeAnalytics, demoChannelAnalytics, demoProjects, demoWorkspace, demoMember, } from "./mock-data"; import type { PaginatedResponse, Channel, Creative, Placement, PurchasePlanChannel, SpendingAnalytics, CreativeAnalyticsItem, ChannelAnalyticsItem, Project, Workspace, WorkspaceMember, DateGrouping, } from "@/lib/types/api"; import { workspacesApi, projectsApi, channelsApi, creativesApi, placementsApi, purchasePlanApi, analyticsApi, membersApi, } from "@/lib/api"; // ============================================================================ // Helper // ============================================================================ const paginate = (items: T[], page = 1, size = 50): PaginatedResponse => ({ items: items.slice((page - 1) * size, page * size), total: items.length, page, size, pages: Math.ceil(items.length / size), }); // ============================================================================ // Demo-Aware Workspaces API // ============================================================================ export const demoAwareWorkspacesApi = { list: async (params?: { page?: number; size?: number }) => { // Always include demo workspace in list for demo mode return workspacesApi.list(params); }, get: async (workspaceId: string): Promise => { if (isDemoWorkspace(workspaceId)) { return demoWorkspace; } // Workspaces API doesn't have get method, fetch from list const response = await workspacesApi.list({ size: 100 }); const workspace = response.items.find(w => w.id === workspaceId); if (!workspace) throw new Error("Workspace not found"); return workspace; }, }; // ============================================================================ // Demo-Aware Projects API // ============================================================================ export const demoAwareProjectsApi = { list: async ( workspaceId: string, params?: { page?: number; size?: number } ): Promise> => { if (isDemoWorkspace(workspaceId)) { return paginate(demoProjects, params?.page, params?.size); } return projectsApi.list(workspaceId, params); }, }; // ============================================================================ // Demo-Aware Members API // ============================================================================ export const demoAwareMembersApi = { list: async ( workspaceId: string, params?: { page?: number; size?: number } ): Promise> => { if (isDemoWorkspace(workspaceId)) { return paginate([demoMember], params?.page, params?.size); } return membersApi.list(workspaceId, params); }, }; // ============================================================================ // Demo-Aware Channels API // ============================================================================ export const demoAwareChannelsApi = { list: async (params?: { page?: number; size?: number; username?: string; }): Promise> => { // Channels are global, check if we're in demo context via some mechanism // For now, always return real data - demo channels are handled per-workspace return channelsApi.list(params); }, listForDemo: (): PaginatedResponse => { return paginate(demoChannels); }, }; // ============================================================================ // Demo-Aware Creatives API // ============================================================================ export const demoAwareCreativesApi = { list: async ( workspaceId: string, params?: { project_id?: string; include_archived?: boolean; page?: number; size?: number; } ): Promise> => { if (isDemoWorkspace(workspaceId)) { let items = demoCreatives; if (params?.project_id) { items = items.filter((c) => c.project_id === params.project_id); } if (!params?.include_archived) { items = items.filter((c) => c.status === "active"); } return paginate(items, params?.page, params?.size); } return creativesApi.list(workspaceId, params); }, get: async (workspaceId: string, creativeId: string): Promise => { if (isDemoWorkspace(workspaceId)) { const creative = demoCreatives.find((c) => c.id === creativeId); if (!creative) throw new Error("Creative not found"); return creative; } return creativesApi.get(workspaceId, creativeId); }, }; // ============================================================================ // Demo-Aware Placements API // ============================================================================ export const demoAwarePlacementsApi = { list: async ( workspaceId: string, params?: { project_id?: string; placement_channel_id?: string; creative_id?: string; include_archived?: boolean; page?: number; size?: number; } ): Promise> => { if (isDemoWorkspace(workspaceId)) { let items = demoPlacements; 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?.include_archived) { items = items.filter((p) => p.status === "active"); } return paginate(items, params?.page, params?.size); } return placementsApi.list(workspaceId, params); }, get: async (workspaceId: string, placementId: string): Promise => { if (isDemoWorkspace(workspaceId)) { const placement = demoPlacements.find((p) => p.id === placementId); if (!placement) throw new Error("Placement not found"); return placement; } return placementsApi.get(workspaceId, placementId); }, }; // ============================================================================ // Demo-Aware Purchase Plan API // ============================================================================ export const demoAwarePurchasePlanApi = { list: async ( workspaceId: string, projectId: string, params?: { page?: number; size?: number } ): Promise> => { if (isDemoWorkspace(workspaceId)) { const items = demoPurchasePlanChannels[projectId] || []; return paginate(items, params?.page, params?.size); } return purchasePlanApi.list(workspaceId, projectId, params); }, }; // ============================================================================ // Demo-Aware Analytics API // ============================================================================ export const demoAwareAnalyticsApi = { spending: async ( workspaceId: string, params?: { project_id?: string; date_from?: string; date_to?: string; grouping?: DateGrouping; } ): Promise => { if (isDemoWorkspace(workspaceId)) { if (params?.project_id) { const projectPlacements = demoPlacements.filter( (p) => p.project_id === params.project_id && 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 { 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, 4), }; } return demoSpendingAnalytics; } return analyticsApi.spending(workspaceId, params); }, creatives: async ( workspaceId: string, params?: { project_id?: string; page?: number; size?: number } ): Promise> => { if (isDemoWorkspace(workspaceId)) { let items = demoCreativeAnalytics; if (params?.project_id) { const projectCreativeIds = demoCreatives .filter((c) => c.project_id === params.project_id) .map((c) => c.id); items = items.filter((a) => projectCreativeIds.includes(a.id)); } return paginate(items, params?.page, params?.size); } return analyticsApi.creatives(workspaceId, params); }, channels: async ( workspaceId: string, params?: { project_id?: string; page?: number; size?: number } ): Promise> => { if (isDemoWorkspace(workspaceId)) { let items = demoChannelAnalytics; if (params?.project_id) { const projectPlacementChannelIds = new Set( demoPlacements .filter((p) => p.project_id === params.project_id) .map((p) => p.placement_channel_id) ); items = items.filter((a) => projectPlacementChannelIds.has(a.channel_id) ); } return paginate(items, params?.page, params?.size); } return analyticsApi.channels(workspaceId, params); }, };