194 lines
7.3 KiB
TypeScript
194 lines
7.3 KiB
TypeScript
// Sponsored Ads — Mock Data: Campaigns, Tracking Events, Daily Stats
|
||
|
||
import type { Campaign, AdTrackingEvent, PlacementDailyStats } from '@/lib/types/ads';
|
||
|
||
// ===== MOCK CAMPAIGNS =====
|
||
|
||
export const MOCK_CAMPAIGNS: Campaign[] = [
|
||
{
|
||
id: 'camp-001',
|
||
partnerId: 'partner-sw',
|
||
partnerName: 'SoundWave Productions',
|
||
name: 'Mumbai Music Festival – Premium Push',
|
||
objective: 'AWARENESS',
|
||
status: 'ACTIVE',
|
||
startAt: '2026-02-01T00:00:00Z',
|
||
endAt: '2026-03-15T23:59:59Z',
|
||
billingModel: 'CPM',
|
||
totalBudget: 50000,
|
||
dailyCap: 2500,
|
||
spent: 18750,
|
||
targeting: { cityIds: ['mumbai', 'pune'], categoryIds: ['music'], countryCodes: ['IN'] },
|
||
surfaceKeys: ['HOME_FEATURED_CAROUSEL', 'CITY_TRENDING'],
|
||
eventIds: ['evt-101'],
|
||
frequencyCap: 5,
|
||
approvedBy: 'admin-1',
|
||
rejectedReason: null,
|
||
createdBy: 'admin-1',
|
||
createdAt: '2026-01-25T10:00:00Z',
|
||
updatedAt: '2026-02-10T08:00:00Z',
|
||
},
|
||
{
|
||
id: 'camp-002',
|
||
partnerId: 'partner-sb',
|
||
partnerName: 'Sunburn Events',
|
||
name: 'Goa Sunburn – Early Bird Blitz',
|
||
objective: 'SALES',
|
||
status: 'IN_REVIEW',
|
||
startAt: '2026-03-01T00:00:00Z',
|
||
endAt: '2026-04-25T23:59:59Z',
|
||
billingModel: 'CPC',
|
||
totalBudget: 75000,
|
||
dailyCap: 5000,
|
||
spent: 0,
|
||
targeting: { cityIds: [], categoryIds: ['music', 'nightlife'], countryCodes: ['IN'] },
|
||
surfaceKeys: ['HOME_FEATURED_CAROUSEL', 'HOME_TOP_EVENTS', 'SEARCH_BOOSTED'],
|
||
eventIds: ['evt-107'],
|
||
frequencyCap: 3,
|
||
approvedBy: null,
|
||
rejectedReason: null,
|
||
createdBy: 'admin-1',
|
||
createdAt: '2026-02-08T14:00:00Z',
|
||
updatedAt: '2026-02-08T14:00:00Z',
|
||
},
|
||
{
|
||
id: 'camp-003',
|
||
partnerId: 'partner-tc',
|
||
partnerName: 'TechConf India',
|
||
name: 'Delhi Tech Summit – Sponsor Package',
|
||
objective: 'AWARENESS',
|
||
status: 'DRAFT',
|
||
startAt: '2026-03-10T00:00:00Z',
|
||
endAt: '2026-03-21T23:59:59Z',
|
||
billingModel: 'FIXED',
|
||
totalBudget: 30000,
|
||
dailyCap: null,
|
||
spent: 0,
|
||
targeting: { cityIds: ['delhi'], categoryIds: ['technology', 'business'], countryCodes: ['IN'] },
|
||
surfaceKeys: ['HOME_TOP_EVENTS', 'CATEGORY_FEATURED'],
|
||
eventIds: ['evt-102'],
|
||
frequencyCap: 0,
|
||
approvedBy: null,
|
||
rejectedReason: null,
|
||
createdBy: 'admin-1',
|
||
createdAt: '2026-02-09T11:00:00Z',
|
||
updatedAt: '2026-02-09T11:00:00Z',
|
||
},
|
||
{
|
||
id: 'camp-004',
|
||
partnerId: 'partner-ri',
|
||
partnerName: 'RunIndia',
|
||
name: 'Pune Marathon – Registration Drive',
|
||
objective: 'SALES',
|
||
status: 'ENDED',
|
||
startAt: '2026-01-15T00:00:00Z',
|
||
endAt: '2026-02-05T23:59:59Z',
|
||
billingModel: 'CPM',
|
||
totalBudget: 20000,
|
||
dailyCap: 1500,
|
||
spent: 19800,
|
||
targeting: { cityIds: ['pune', 'mumbai'], categoryIds: ['sports'], countryCodes: ['IN'] },
|
||
surfaceKeys: ['HOME_TOP_EVENTS', 'CITY_TRENDING'],
|
||
eventIds: ['evt-106'],
|
||
frequencyCap: 4,
|
||
approvedBy: 'admin-1',
|
||
rejectedReason: null,
|
||
createdBy: 'admin-1',
|
||
createdAt: '2026-01-10T09:00:00Z',
|
||
updatedAt: '2026-02-05T23:59:59Z',
|
||
},
|
||
];
|
||
|
||
// ===== MOCK TRACKING EVENTS (for camp-001) =====
|
||
|
||
function genTrackingEvents(): AdTrackingEvent[] {
|
||
const events: AdTrackingEvent[] = [];
|
||
const surfaces = ['HOME_FEATURED_CAROUSEL', 'CITY_TRENDING'] as const;
|
||
const devices = ['mobile-ios', 'mobile-android', 'web-desktop', 'web-mobile'];
|
||
const cities = ['mumbai', 'pune'];
|
||
const baseTime = new Date('2026-02-03T00:00:00Z');
|
||
|
||
for (let day = 0; day < 7; day++) {
|
||
const impressionsPerDay = 80 + Math.floor(Math.random() * 40);
|
||
for (let i = 0; i < impressionsPerDay; i++) {
|
||
const ts = new Date(baseTime.getTime() + day * 86400000 + Math.floor(Math.random() * 86400000));
|
||
const surface = surfaces[Math.floor(Math.random() * surfaces.length)];
|
||
events.push({
|
||
id: `te-imp-${day}-${i}`,
|
||
type: 'IMPRESSION',
|
||
placementId: `splc-camp001-${surface}`,
|
||
campaignId: 'camp-001',
|
||
surfaceKey: surface,
|
||
eventId: 'evt-101',
|
||
userId: Math.random() > 0.4 ? `user-${100 + Math.floor(Math.random() * 50)}` : null,
|
||
anonId: `anon-${Math.floor(Math.random() * 200)}`,
|
||
sessionId: `sess-${day}-${Math.floor(Math.random() * 100)}`,
|
||
timestamp: ts.toISOString(),
|
||
device: devices[Math.floor(Math.random() * devices.length)],
|
||
cityId: cities[Math.floor(Math.random() * cities.length)],
|
||
});
|
||
}
|
||
|
||
// Clicks (~8-15% of impressions)
|
||
const clicksPerDay = Math.floor(impressionsPerDay * (0.08 + Math.random() * 0.07));
|
||
for (let c = 0; c < clicksPerDay; c++) {
|
||
const ts = new Date(baseTime.getTime() + day * 86400000 + Math.floor(Math.random() * 86400000));
|
||
const surface = surfaces[Math.floor(Math.random() * surfaces.length)];
|
||
events.push({
|
||
id: `te-clk-${day}-${c}`,
|
||
type: 'CLICK',
|
||
placementId: `splc-camp001-${surface}`,
|
||
campaignId: 'camp-001',
|
||
surfaceKey: surface,
|
||
eventId: 'evt-101',
|
||
userId: Math.random() > 0.3 ? `user-${100 + Math.floor(Math.random() * 50)}` : null,
|
||
anonId: `anon-${Math.floor(Math.random() * 200)}`,
|
||
sessionId: `sess-${day}-${Math.floor(Math.random() * 100)}`,
|
||
timestamp: ts.toISOString(),
|
||
device: devices[Math.floor(Math.random() * devices.length)],
|
||
cityId: cities[Math.floor(Math.random() * cities.length)],
|
||
});
|
||
}
|
||
}
|
||
|
||
return events;
|
||
}
|
||
|
||
export const MOCK_TRACKING_EVENTS = genTrackingEvents();
|
||
|
||
// ===== MOCK DAILY STATS =====
|
||
|
||
export function generateMockDailyStats(): PlacementDailyStats[] {
|
||
const stats: PlacementDailyStats[] = [];
|
||
const baseDate = new Date('2026-02-03');
|
||
const cpmRate = 50000 / (7 * 100); // simplified: budget / (days * avg impressions per batch)
|
||
|
||
for (let day = 0; day < 7; day++) {
|
||
const date = new Date(baseDate.getTime() + day * 86400000).toISOString().slice(0, 10);
|
||
const surfaces = ['HOME_FEATURED_CAROUSEL', 'CITY_TRENDING'] as const;
|
||
|
||
for (const surface of surfaces) {
|
||
const impressions = 40 + Math.floor(Math.random() * 25);
|
||
const clicks = Math.floor(impressions * (0.08 + Math.random() * 0.07));
|
||
const ctr = impressions > 0 ? Number((clicks / impressions).toFixed(4)) : 0;
|
||
const spend = Number(((impressions / 1000) * 250).toFixed(2)); // ₹250 CPM
|
||
|
||
stats.push({
|
||
id: `ds-${day}-${surface}`,
|
||
campaignId: 'camp-001',
|
||
placementId: `splc-camp001-${surface}`,
|
||
surfaceKey: surface,
|
||
date,
|
||
impressions,
|
||
clicks,
|
||
ctr,
|
||
spend,
|
||
});
|
||
}
|
||
}
|
||
|
||
return stats;
|
||
}
|
||
|
||
export const MOCK_DAILY_STATS = generateMockDailyStats();
|