mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
feat: add mock data layer — 50 leads, 5 campaigns, ads, activities, templates, agents
Indian names, ₹ currency, healthcare campaign context for Helix Engage. Includes factories.ts with nextId/randomFrom/daysAgo/createMockLead helpers, 50 leads across all statuses, 5 campaigns (3 active/1 paused/1 completed), 12 ads on active campaigns, 15 lead activities, 8 follow-ups, 5 WhatsApp templates, and 3 agents. All cross-references are internally consistent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
243
src/mocks/ads.ts
Normal file
243
src/mocks/ads.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
import type { Ad } from '@/types/entities';
|
||||
import { inr, daysAgo } from './factories';
|
||||
import { CAMPAIGN_ID_WD, CAMPAIGN_ID_GH, CAMPAIGN_ID_IVF, CAMPAIGN_ID_SN } from './campaigns';
|
||||
|
||||
// Fixed ad IDs for lead cross-references
|
||||
export const AD_ID_WD_1 = 'ad-wd-1';
|
||||
export const AD_ID_WD_2 = 'ad-wd-2';
|
||||
export const AD_ID_WD_3 = 'ad-wd-3';
|
||||
export const AD_ID_GH_1 = 'ad-gh-1';
|
||||
export const AD_ID_GH_2 = 'ad-gh-2';
|
||||
export const AD_ID_GH_3 = 'ad-gh-3';
|
||||
export const AD_ID_IVF_1 = 'ad-ivf-1';
|
||||
export const AD_ID_IVF_2 = 'ad-ivf-2';
|
||||
export const AD_ID_IVF_3 = 'ad-ivf-3';
|
||||
export const AD_ID_SN_1 = 'ad-sn-1';
|
||||
export const AD_ID_SN_2 = 'ad-sn-2';
|
||||
export const AD_ID_SN_3 = 'ad-sn-3';
|
||||
|
||||
export const mockAds: Ad[] = [
|
||||
// Women's Day campaign ads
|
||||
{
|
||||
id: AD_ID_WD_1,
|
||||
createdAt: daysAgo(29),
|
||||
updatedAt: daysAgo(1),
|
||||
adName: "Women's Day — Full Checkup Package",
|
||||
externalAdId: 'WD-123-A01',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'IMAGE',
|
||||
headline: 'Free Health Checkup This Women\'s Day',
|
||||
adDescription: 'Complete women\'s health checkup at Ramaiah Memorial Hospital. Book now — limited slots available.',
|
||||
destinationUrl: 'https://ramaiah.hospital/womens-day-checkup',
|
||||
previewUrl: null,
|
||||
impressions: 58000,
|
||||
clicks: 1540,
|
||||
conversions: 18,
|
||||
spend: inr(42000),
|
||||
campaignId: CAMPAIGN_ID_WD,
|
||||
},
|
||||
{
|
||||
id: AD_ID_WD_2,
|
||||
createdAt: daysAgo(28),
|
||||
updatedAt: daysAgo(1),
|
||||
adName: "Women's Day — Carousel Benefits",
|
||||
externalAdId: 'WD-123-A02',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'CAROUSEL',
|
||||
headline: 'Your Health, Our Priority — Women\'s Day Special',
|
||||
adDescription: 'Swipe to explore what\'s included in our comprehensive Women\'s Day Health Package.',
|
||||
destinationUrl: 'https://ramaiah.hospital/womens-day-checkup',
|
||||
previewUrl: null,
|
||||
impressions: 47000,
|
||||
clicks: 1290,
|
||||
conversions: 12,
|
||||
spend: inr(38000),
|
||||
campaignId: CAMPAIGN_ID_WD,
|
||||
},
|
||||
{
|
||||
id: AD_ID_WD_3,
|
||||
createdAt: daysAgo(27),
|
||||
updatedAt: daysAgo(2),
|
||||
adName: "Women's Day — Testimonial Video",
|
||||
externalAdId: 'WD-123-A03',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'VIDEO',
|
||||
headline: 'Real Stories. Real Care. Ramaiah Memorial.',
|
||||
adDescription: 'Watch how our patients experienced the Women\'s Day Health Checkup at Ramaiah Memorial Hospital.',
|
||||
destinationUrl: 'https://ramaiah.hospital/womens-day-checkup',
|
||||
previewUrl: null,
|
||||
impressions: 37000,
|
||||
clicks: 1010,
|
||||
conversions: 8,
|
||||
spend: inr(38000),
|
||||
campaignId: CAMPAIGN_ID_WD,
|
||||
},
|
||||
|
||||
// Cervical Cancer Screening campaign ads
|
||||
{
|
||||
id: AD_ID_GH_1,
|
||||
createdAt: daysAgo(24),
|
||||
updatedAt: daysAgo(1),
|
||||
adName: 'Cervical Screening — Awareness Image',
|
||||
externalAdId: 'GH-456-A01',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'IMAGE',
|
||||
headline: 'Cervical Cancer Is Preventable — Get Screened Today',
|
||||
adDescription: 'Early detection saves lives. Book your cervical cancer screening at Ramaiah Memorial Hospital.',
|
||||
destinationUrl: 'https://ramaiah.hospital/cervical-screening',
|
||||
previewUrl: null,
|
||||
impressions: 42000,
|
||||
clicks: 960,
|
||||
conversions: 11,
|
||||
spend: inr(29000),
|
||||
campaignId: CAMPAIGN_ID_GH,
|
||||
},
|
||||
{
|
||||
id: AD_ID_GH_2,
|
||||
createdAt: daysAgo(23),
|
||||
updatedAt: daysAgo(2),
|
||||
adName: 'Cervical Screening — GMB Lead Form',
|
||||
externalAdId: 'GH-456-A02',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'LEAD_FORM',
|
||||
headline: 'Schedule Your Cervical Screening — It Takes 2 Minutes',
|
||||
adDescription: 'Fill in your details and our team will call you within 24 hours to confirm your appointment.',
|
||||
destinationUrl: 'https://ramaiah.hospital/cervical-screening/form',
|
||||
previewUrl: null,
|
||||
impressions: 32500,
|
||||
clicks: 780,
|
||||
conversions: 7,
|
||||
spend: inr(24000),
|
||||
campaignId: CAMPAIGN_ID_GH,
|
||||
},
|
||||
{
|
||||
id: AD_ID_GH_3,
|
||||
createdAt: daysAgo(22),
|
||||
updatedAt: daysAgo(3),
|
||||
adName: 'Cervical Screening — Doctor Video',
|
||||
externalAdId: 'GH-456-A03',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'VIDEO',
|
||||
headline: 'Dr. Kavitha Explains Cervical Cancer Prevention',
|
||||
adDescription: 'Watch our Senior Gynaecologist explain everything you need to know about cervical cancer screening.',
|
||||
destinationUrl: 'https://ramaiah.hospital/cervical-screening',
|
||||
previewUrl: null,
|
||||
impressions: 24000,
|
||||
clicks: 470,
|
||||
conversions: 4,
|
||||
spend: inr(19000),
|
||||
campaignId: CAMPAIGN_ID_GH,
|
||||
},
|
||||
|
||||
// IVF Consultation campaign ads
|
||||
{
|
||||
id: AD_ID_IVF_1,
|
||||
createdAt: daysAgo(19),
|
||||
updatedAt: daysAgo(1),
|
||||
adName: 'IVF — Free First Consultation Image',
|
||||
externalAdId: 'IVF-789-A01',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'IMAGE',
|
||||
headline: 'Free IVF Consultation — Your Journey to Parenthood Starts Here',
|
||||
adDescription: 'Book a free first consultation with our IVF specialists at Ramaiah Memorial Hospital. No obligation.',
|
||||
destinationUrl: 'https://ramaiah.hospital/ivf-free-consultation',
|
||||
previewUrl: null,
|
||||
impressions: 88000,
|
||||
clicks: 2340,
|
||||
conversions: 24,
|
||||
spend: inr(62000),
|
||||
campaignId: CAMPAIGN_ID_IVF,
|
||||
},
|
||||
{
|
||||
id: AD_ID_IVF_2,
|
||||
createdAt: daysAgo(18),
|
||||
updatedAt: daysAgo(1),
|
||||
adName: 'IVF — Success Stories Carousel',
|
||||
externalAdId: 'IVF-789-A02',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'CAROUSEL',
|
||||
headline: '500+ IVF Successes at Ramaiah Memorial Hospital',
|
||||
adDescription: 'Read the stories of families who trusted Ramaiah Memorial Hospital for their IVF journey.',
|
||||
destinationUrl: 'https://ramaiah.hospital/ivf-success-stories',
|
||||
previewUrl: null,
|
||||
impressions: 76000,
|
||||
clicks: 2010,
|
||||
conversions: 18,
|
||||
spend: inr(54000),
|
||||
campaignId: CAMPAIGN_ID_IVF,
|
||||
},
|
||||
{
|
||||
id: AD_ID_IVF_3,
|
||||
createdAt: daysAgo(17),
|
||||
updatedAt: daysAgo(2),
|
||||
adName: 'IVF — WhatsApp Lead Gen',
|
||||
externalAdId: 'IVF-789-A03',
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'LEAD_FORM',
|
||||
headline: 'Chat With Our IVF Team on WhatsApp — Free & Confidential',
|
||||
adDescription: 'Have questions about IVF? Our specialists are available on WhatsApp for a free, confidential chat.',
|
||||
destinationUrl: 'https://wa.me/919876543210',
|
||||
previewUrl: null,
|
||||
impressions: 46000,
|
||||
clicks: 1250,
|
||||
conversions: 12,
|
||||
spend: inr(40000),
|
||||
campaignId: CAMPAIGN_ID_IVF,
|
||||
},
|
||||
|
||||
// Senior Health Package campaign ads (paused)
|
||||
{
|
||||
id: AD_ID_SN_1,
|
||||
createdAt: daysAgo(59),
|
||||
updatedAt: daysAgo(10),
|
||||
adName: 'Senior Package — Wellness Image',
|
||||
externalAdId: 'SN-101-A01',
|
||||
adStatus: 'PAUSED',
|
||||
adFormat: 'IMAGE',
|
||||
headline: 'Complete Senior Health Package — ₹3,999 Only',
|
||||
adDescription: 'Comprehensive health checkup for seniors at Ramaiah Memorial Hospital. 40+ tests included.',
|
||||
destinationUrl: 'https://ramaiah.hospital/senior-health-package',
|
||||
previewUrl: null,
|
||||
impressions: 31000,
|
||||
clicks: 680,
|
||||
conversions: 8,
|
||||
spend: inr(26000),
|
||||
campaignId: CAMPAIGN_ID_SN,
|
||||
},
|
||||
{
|
||||
id: AD_ID_SN_2,
|
||||
createdAt: daysAgo(58),
|
||||
updatedAt: daysAgo(10),
|
||||
adName: 'Senior Package — Family Carousel',
|
||||
externalAdId: 'SN-101-A02',
|
||||
adStatus: 'PAUSED',
|
||||
adFormat: 'CAROUSEL',
|
||||
headline: 'Give Your Parents the Gift of Good Health',
|
||||
adDescription: 'Book the Senior Health Package for a loved one. Includes cardiac, diabetes, and joint health screenings.',
|
||||
destinationUrl: 'https://ramaiah.hospital/senior-health-package',
|
||||
previewUrl: null,
|
||||
impressions: 26000,
|
||||
clicks: 570,
|
||||
conversions: 6,
|
||||
spend: inr(22000),
|
||||
campaignId: CAMPAIGN_ID_SN,
|
||||
},
|
||||
{
|
||||
id: AD_ID_SN_3,
|
||||
createdAt: daysAgo(57),
|
||||
updatedAt: daysAgo(11),
|
||||
adName: 'Senior Package — Doctor Video',
|
||||
externalAdId: 'SN-101-A03',
|
||||
adStatus: 'PAUSED',
|
||||
adFormat: 'VIDEO',
|
||||
headline: 'Why Senior Health Checkups Matter — Ramaiah Doctors Explain',
|
||||
adDescription: 'Hear from our specialists why regular health checkups are critical after 60.',
|
||||
destinationUrl: 'https://ramaiah.hospital/senior-health-package',
|
||||
previewUrl: null,
|
||||
impressions: 18000,
|
||||
clicks: 370,
|
||||
conversions: 4,
|
||||
spend: inr(15000),
|
||||
campaignId: CAMPAIGN_ID_SN,
|
||||
},
|
||||
];
|
||||
31
src/mocks/agents.ts
Normal file
31
src/mocks/agents.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import type { Agent } from '@/types/entities';
|
||||
|
||||
export const mockAgents: Agent[] = [
|
||||
{
|
||||
id: 'agent-rekha',
|
||||
name: 'Rekha S.',
|
||||
initials: 'RS',
|
||||
isOnShift: true,
|
||||
shiftNote: 'Morning shift — 8 AM to 4 PM',
|
||||
avgResponseHours: 1.2,
|
||||
activeLeadCount: 8,
|
||||
},
|
||||
{
|
||||
id: 'agent-suresh',
|
||||
name: 'Suresh P.',
|
||||
initials: 'SP',
|
||||
isOnShift: true,
|
||||
shiftNote: 'Afternoon shift — 12 PM to 8 PM',
|
||||
avgResponseHours: 1.8,
|
||||
activeLeadCount: 14,
|
||||
},
|
||||
{
|
||||
id: 'agent-meena',
|
||||
name: 'Meena K.',
|
||||
initials: 'MK',
|
||||
isOnShift: false,
|
||||
shiftNote: 'Off shift — returns tomorrow at 9 AM',
|
||||
avgResponseHours: 0.9,
|
||||
activeLeadCount: 6,
|
||||
},
|
||||
];
|
||||
117
src/mocks/campaigns.ts
Normal file
117
src/mocks/campaigns.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import type { Campaign } from '@/types/entities';
|
||||
import { inr, daysAgo } from './factories';
|
||||
|
||||
// Fixed IDs for cross-file references
|
||||
export const CAMPAIGN_ID_WD = 'campaign-wd-123';
|
||||
export const CAMPAIGN_ID_GH = 'campaign-gh-456';
|
||||
export const CAMPAIGN_ID_IVF = 'campaign-ivf-789';
|
||||
export const CAMPAIGN_ID_SN = 'campaign-sn-101';
|
||||
export const CAMPAIGN_ID_DA = 'campaign-da-202';
|
||||
|
||||
export const mockCampaigns: Campaign[] = [
|
||||
{
|
||||
id: CAMPAIGN_ID_WD,
|
||||
createdAt: daysAgo(45),
|
||||
updatedAt: daysAgo(1),
|
||||
campaignName: "Women's Day Health Checkup",
|
||||
campaignType: 'FACEBOOK_AD',
|
||||
campaignStatus: 'ACTIVE',
|
||||
platform: 'FACEBOOK',
|
||||
startDate: daysAgo(30),
|
||||
endDate: null,
|
||||
budget: inr(200000),
|
||||
amountSpent: inr(118000),
|
||||
impressionCount: 142000,
|
||||
clickCount: 3840,
|
||||
targetCount: 20000,
|
||||
contactedCount: 210,
|
||||
convertedCount: 38,
|
||||
leadCount: 275,
|
||||
externalCampaignId: 'WD-123',
|
||||
platformUrl: 'https://www.facebook.com/ads/manager/WD-123',
|
||||
},
|
||||
{
|
||||
id: CAMPAIGN_ID_GH,
|
||||
createdAt: daysAgo(40),
|
||||
updatedAt: daysAgo(2),
|
||||
campaignName: 'Cervical Cancer Screening Drive',
|
||||
campaignType: 'GOOGLE_AD',
|
||||
campaignStatus: 'ACTIVE',
|
||||
platform: 'GOOGLE',
|
||||
startDate: daysAgo(25),
|
||||
endDate: null,
|
||||
budget: inr(150000),
|
||||
amountSpent: inr(72000),
|
||||
impressionCount: 98500,
|
||||
clickCount: 2210,
|
||||
targetCount: 15000,
|
||||
contactedCount: 140,
|
||||
convertedCount: 22,
|
||||
leadCount: 180,
|
||||
externalCampaignId: 'GH-456',
|
||||
platformUrl: 'https://ads.google.com/campaigns/GH-456',
|
||||
},
|
||||
{
|
||||
id: CAMPAIGN_ID_IVF,
|
||||
createdAt: daysAgo(35),
|
||||
updatedAt: daysAgo(1),
|
||||
campaignName: 'IVF Consultation — Free First Visit',
|
||||
campaignType: 'FACEBOOK_AD',
|
||||
campaignStatus: 'ACTIVE',
|
||||
platform: 'FACEBOOK',
|
||||
startDate: daysAgo(20),
|
||||
endDate: null,
|
||||
budget: inr(300000),
|
||||
amountSpent: inr(156000),
|
||||
impressionCount: 210000,
|
||||
clickCount: 5600,
|
||||
targetCount: 25000,
|
||||
contactedCount: 310,
|
||||
convertedCount: 54,
|
||||
leadCount: 420,
|
||||
externalCampaignId: 'IVF-789',
|
||||
platformUrl: 'https://www.facebook.com/ads/manager/IVF-789',
|
||||
},
|
||||
{
|
||||
id: CAMPAIGN_ID_SN,
|
||||
createdAt: daysAgo(60),
|
||||
updatedAt: daysAgo(10),
|
||||
campaignName: 'Senior Health Package',
|
||||
campaignType: 'FACEBOOK_AD',
|
||||
campaignStatus: 'PAUSED',
|
||||
platform: 'FACEBOOK',
|
||||
startDate: daysAgo(60),
|
||||
endDate: null,
|
||||
budget: inr(100000),
|
||||
amountSpent: inr(63000),
|
||||
impressionCount: 75000,
|
||||
clickCount: 1620,
|
||||
targetCount: 10000,
|
||||
contactedCount: 95,
|
||||
convertedCount: 18,
|
||||
leadCount: 130,
|
||||
externalCampaignId: 'SN-101',
|
||||
platformUrl: 'https://www.facebook.com/ads/manager/SN-101',
|
||||
},
|
||||
{
|
||||
id: CAMPAIGN_ID_DA,
|
||||
createdAt: daysAgo(90),
|
||||
updatedAt: daysAgo(20),
|
||||
campaignName: 'Diabetes Awareness Camp',
|
||||
campaignType: 'WHATSAPP',
|
||||
campaignStatus: 'COMPLETED',
|
||||
platform: 'MANUAL',
|
||||
startDate: daysAgo(90),
|
||||
endDate: daysAgo(20),
|
||||
budget: inr(50000),
|
||||
amountSpent: inr(48500),
|
||||
impressionCount: 32000,
|
||||
clickCount: 980,
|
||||
targetCount: 8000,
|
||||
contactedCount: 72,
|
||||
convertedCount: 14,
|
||||
leadCount: 98,
|
||||
externalCampaignId: 'DA-202',
|
||||
platformUrl: null,
|
||||
},
|
||||
];
|
||||
149
src/mocks/factories.ts
Normal file
149
src/mocks/factories.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import type { Lead, Campaign, Ad, LeadSource, Priority } from '@/types/entities';
|
||||
|
||||
// Sequential ID generator
|
||||
let _idCounter = 1000;
|
||||
export function nextId(): string {
|
||||
return `mock-${_idCounter++}`;
|
||||
}
|
||||
|
||||
// Random element picker
|
||||
export function randomFrom<T>(arr: T[]): T {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
// ISO date string for N days ago
|
||||
export function daysAgo(n: number): string {
|
||||
const d = new Date();
|
||||
d.setDate(d.getDate() - n);
|
||||
return d.toISOString();
|
||||
}
|
||||
|
||||
// INR currency helper
|
||||
export function inr(amount: number): { amountMicros: number; currencyCode: string } {
|
||||
return { amountMicros: amount * 1_000_000, currencyCode: 'INR' };
|
||||
}
|
||||
|
||||
// Indian name pools
|
||||
export const indianFirstNames = [
|
||||
'Aarav', 'Aditya', 'Akash', 'Amit', 'Ananya', 'Anjali', 'Ankit', 'Anushka',
|
||||
'Arjun', 'Aryan', 'Deepa', 'Deepika', 'Divya', 'Geeta', 'Girish', 'Harsha',
|
||||
'Ishaan', 'Kavitha', 'Kiran', 'Lakshmi', 'Madhuri', 'Meena', 'Mohan', 'Nandini',
|
||||
'Nikhil', 'Pooja', 'Priya', 'Rahul', 'Raj', 'Rajesh', 'Ramesh', 'Rekha',
|
||||
'Rohit', 'Sarita', 'Seema', 'Shilpa', 'Shyam', 'Sneha', 'Sunita', 'Suresh',
|
||||
'Usha', 'Varun', 'Vijay', 'Vikram', 'Vipin', 'Vishal', 'Yamini', 'Yogesh',
|
||||
'Zara', 'Preethi',
|
||||
];
|
||||
|
||||
export const indianLastNames = [
|
||||
'Agarwal', 'Bhat', 'Chandra', 'Desai', 'Ghosh', 'Gupta', 'Iyer', 'Jain',
|
||||
'Kamath', 'Kumar', 'Mehta', 'Murthy', 'Nair', 'Patel', 'Rao', 'Reddy',
|
||||
'Sharma', 'Singh', 'Srinivas', 'Verma',
|
||||
];
|
||||
|
||||
const leadSources: LeadSource[] = [
|
||||
'FACEBOOK_AD', 'FACEBOOK_AD', 'FACEBOOK_AD',
|
||||
'GOOGLE_AD', 'GOOGLE_AD', 'GOOGLE_AD',
|
||||
'INSTAGRAM', 'INSTAGRAM',
|
||||
'WHATSAPP', 'WHATSAPP',
|
||||
'GOOGLE_MY_BUSINESS',
|
||||
'WEBSITE',
|
||||
];
|
||||
|
||||
const services = [
|
||||
'IVF Consultation', 'Fertility Assessment', 'Egg Freezing', 'Embryo Transfer',
|
||||
'Prenatal Care', 'Gynecology Checkup', 'Cervical Screening', 'Mammography',
|
||||
'General Health Checkup', 'Diabetes Consultation', 'Cardiology Checkup',
|
||||
'Orthopaedic Consultation', 'Senior Health Package', 'Nutrition Counselling',
|
||||
];
|
||||
|
||||
const priorities: Priority[] = ['LOW', 'NORMAL', 'NORMAL', 'NORMAL', 'HIGH', 'URGENT'];
|
||||
|
||||
export function createMockLead(overrides?: Partial<Lead>): Lead {
|
||||
const firstName = randomFrom(indianFirstNames);
|
||||
const lastName = randomFrom(indianLastNames);
|
||||
const emailLocal = `${firstName.toLowerCase()}.${lastName.charAt(0).toLowerCase()}`;
|
||||
const phoneNumber = `+91${Math.floor(7000000000 + Math.random() * 2999999999)}`;
|
||||
const spamScore = Math.floor(Math.random() * 100);
|
||||
const source = randomFrom(leadSources);
|
||||
|
||||
return {
|
||||
id: nextId(),
|
||||
createdAt: daysAgo(Math.floor(Math.random() * 14)),
|
||||
updatedAt: daysAgo(Math.floor(Math.random() * 2)),
|
||||
leadSource: source,
|
||||
leadStatus: 'NEW',
|
||||
priority: randomFrom(priorities),
|
||||
contactName: { firstName, lastName },
|
||||
contactPhone: [{ number: phoneNumber, callingCode: '+91' }],
|
||||
contactEmail: [{ address: `${emailLocal}@gmail.com` }],
|
||||
interestedService: randomFrom(services),
|
||||
assignedAgent: null,
|
||||
utmSource: null,
|
||||
utmMedium: null,
|
||||
utmCampaign: null,
|
||||
utmContent: null,
|
||||
utmTerm: null,
|
||||
landingPageUrl: null,
|
||||
referrerUrl: null,
|
||||
leadScore: Math.floor(Math.random() * 100),
|
||||
spamScore,
|
||||
isSpam: spamScore >= 60,
|
||||
isDuplicate: false,
|
||||
duplicateOfLeadId: null,
|
||||
firstContactedAt: null,
|
||||
lastContactedAt: null,
|
||||
contactAttempts: 0,
|
||||
convertedAt: null,
|
||||
patientId: null,
|
||||
campaignId: null,
|
||||
adId: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function createMockCampaign(overrides?: Partial<Campaign>): Campaign {
|
||||
return {
|
||||
id: nextId(),
|
||||
createdAt: daysAgo(30),
|
||||
updatedAt: daysAgo(1),
|
||||
campaignName: null,
|
||||
campaignType: 'FACEBOOK_AD',
|
||||
campaignStatus: 'ACTIVE',
|
||||
platform: 'FACEBOOK',
|
||||
startDate: daysAgo(30),
|
||||
endDate: null,
|
||||
budget: inr(100000),
|
||||
amountSpent: inr(50000),
|
||||
impressionCount: 50000,
|
||||
clickCount: 1200,
|
||||
targetCount: 10000,
|
||||
contactedCount: 80,
|
||||
convertedCount: 10,
|
||||
leadCount: 100,
|
||||
externalCampaignId: null,
|
||||
platformUrl: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
export function createMockAd(campaignId: string, overrides?: Partial<Ad>): Ad {
|
||||
return {
|
||||
id: nextId(),
|
||||
createdAt: daysAgo(28),
|
||||
updatedAt: daysAgo(2),
|
||||
adName: null,
|
||||
externalAdId: null,
|
||||
adStatus: 'ACTIVE',
|
||||
adFormat: 'IMAGE',
|
||||
headline: null,
|
||||
adDescription: null,
|
||||
destinationUrl: 'https://www.ramaiah.hospital',
|
||||
previewUrl: null,
|
||||
impressions: 10000,
|
||||
clicks: 250,
|
||||
conversions: 15,
|
||||
spend: inr(15000),
|
||||
campaignId,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
147
src/mocks/follow-ups.ts
Normal file
147
src/mocks/follow-ups.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
import type { FollowUp } from '@/types/entities';
|
||||
import { daysAgo } from './factories';
|
||||
|
||||
// daysFromNow helper for future dates
|
||||
function daysFromNow(n: number): string {
|
||||
const d = new Date();
|
||||
d.setDate(d.getDate() + n);
|
||||
// Set to business hours (10 AM IST)
|
||||
d.setHours(10, 0, 0, 0);
|
||||
return d.toISOString();
|
||||
}
|
||||
|
||||
function today(hour: number = 14): string {
|
||||
const d = new Date();
|
||||
d.setHours(hour, 0, 0, 0);
|
||||
return d.toISOString();
|
||||
}
|
||||
|
||||
export const mockFollowUps: FollowUp[] = [
|
||||
// 1 OVERDUE
|
||||
{
|
||||
id: 'followup-1',
|
||||
createdAt: daysAgo(3),
|
||||
followUpType: 'CALLBACK',
|
||||
followUpStatus: 'OVERDUE',
|
||||
scheduledAt: daysAgo(1),
|
||||
completedAt: null,
|
||||
priority: 'HIGH',
|
||||
assignedAgent: 'Suresh P.',
|
||||
patientId: 'lead-qualified-2',
|
||||
callId: null,
|
||||
patientName: 'Priya Sharma',
|
||||
patientPhone: '+919845123456',
|
||||
description: 'Patient requested callback after reviewing IVF package brochure. Had questions about donor egg options and financing.',
|
||||
},
|
||||
|
||||
// 3 PENDING
|
||||
{
|
||||
id: 'followup-2',
|
||||
createdAt: daysAgo(1),
|
||||
followUpType: 'CALLBACK',
|
||||
followUpStatus: 'PENDING',
|
||||
scheduledAt: today(11),
|
||||
completedAt: null,
|
||||
priority: 'URGENT',
|
||||
assignedAgent: 'Rekha S.',
|
||||
patientId: 'lead-appt-1',
|
||||
callId: null,
|
||||
patientName: 'Ananya Nair',
|
||||
patientPhone: '+918867234567',
|
||||
description: 'Confirm appointment for IVF consultation tomorrow at 11 AM. Remind patient to bring previous fertility test reports.',
|
||||
},
|
||||
{
|
||||
id: 'followup-3',
|
||||
createdAt: daysAgo(2),
|
||||
followUpType: 'APPOINTMENT_REMINDER',
|
||||
followUpStatus: 'PENDING',
|
||||
scheduledAt: today(15),
|
||||
completedAt: null,
|
||||
priority: 'HIGH',
|
||||
assignedAgent: 'Meena K.',
|
||||
patientId: 'lead-appt-3',
|
||||
callId: null,
|
||||
patientName: 'Sunita Reddy',
|
||||
patientPhone: '+919901345678',
|
||||
description: 'Send Women\'s Day Checkup appointment reminder via WhatsApp. Appointment is tomorrow at 9 AM.',
|
||||
},
|
||||
{
|
||||
id: 'followup-4',
|
||||
createdAt: daysAgo(1),
|
||||
followUpType: 'MARKETING',
|
||||
followUpStatus: 'PENDING',
|
||||
scheduledAt: daysFromNow(1),
|
||||
completedAt: null,
|
||||
priority: 'NORMAL',
|
||||
assignedAgent: 'Suresh P.',
|
||||
patientId: 'lead-contacted-5',
|
||||
callId: null,
|
||||
patientName: 'Deepika Iyer',
|
||||
patientPhone: '+917678456789',
|
||||
description: 'Follow up on Cervical Screening campaign interest. Patient was busy during first call and asked to be called back next day.',
|
||||
},
|
||||
|
||||
// 2 COMPLETED
|
||||
{
|
||||
id: 'followup-5',
|
||||
createdAt: daysAgo(5),
|
||||
followUpType: 'CALLBACK',
|
||||
followUpStatus: 'COMPLETED',
|
||||
scheduledAt: daysAgo(3),
|
||||
completedAt: daysAgo(3),
|
||||
priority: 'HIGH',
|
||||
assignedAgent: 'Rekha S.',
|
||||
patientId: 'lead-converted-1',
|
||||
callId: null,
|
||||
patientName: 'Lakshmi Patel',
|
||||
patientPhone: '+919876543210',
|
||||
description: 'Post-appointment follow-up call. Patient confirmed satisfaction with IVF consultation. Proceeding with treatment plan.',
|
||||
},
|
||||
{
|
||||
id: 'followup-6',
|
||||
createdAt: daysAgo(8),
|
||||
followUpType: 'POST_VISIT',
|
||||
followUpStatus: 'COMPLETED',
|
||||
scheduledAt: daysAgo(6),
|
||||
completedAt: daysAgo(6),
|
||||
priority: 'NORMAL',
|
||||
assignedAgent: 'Meena K.',
|
||||
patientId: 'lead-converted-3',
|
||||
callId: null,
|
||||
patientName: 'Usha Mehta',
|
||||
patientPhone: '+917890567890',
|
||||
description: 'Post-visit satisfaction call for Senior Health Package. Patient very happy with service. Referred two friends.',
|
||||
},
|
||||
|
||||
// 2 CANCELLED
|
||||
{
|
||||
id: 'followup-7',
|
||||
createdAt: daysAgo(4),
|
||||
followUpType: 'CALLBACK',
|
||||
followUpStatus: 'CANCELLED',
|
||||
scheduledAt: daysAgo(2),
|
||||
completedAt: null,
|
||||
priority: 'NORMAL',
|
||||
assignedAgent: 'Suresh P.',
|
||||
patientId: 'lead-contacted-7',
|
||||
callId: null,
|
||||
patientName: 'Ramesh Gupta',
|
||||
patientPhone: '+918765234567',
|
||||
description: 'Callback cancelled — patient informed via WhatsApp that they are travelling and will reach out when available.',
|
||||
},
|
||||
{
|
||||
id: 'followup-8',
|
||||
createdAt: daysAgo(6),
|
||||
followUpType: 'MARKETING',
|
||||
followUpStatus: 'CANCELLED',
|
||||
scheduledAt: daysAgo(3),
|
||||
completedAt: null,
|
||||
priority: 'LOW',
|
||||
assignedAgent: 'Rekha S.',
|
||||
patientId: 'lead-contacted-9',
|
||||
callId: null,
|
||||
patientName: 'Mohan Verma',
|
||||
patientPhone: '+919123456789',
|
||||
description: 'Diabetes Awareness Camp follow-up cancelled — patient opted out of marketing communications.',
|
||||
},
|
||||
];
|
||||
8
src/mocks/index.ts
Normal file
8
src/mocks/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export * from './factories';
|
||||
export * from './campaigns';
|
||||
export * from './ads';
|
||||
export * from './leads';
|
||||
export * from './lead-activities';
|
||||
export * from './follow-ups';
|
||||
export * from './templates';
|
||||
export * from './agents';
|
||||
226
src/mocks/lead-activities.ts
Normal file
226
src/mocks/lead-activities.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
import type { LeadActivity } from '@/types/entities';
|
||||
import { daysAgo } from './factories';
|
||||
import { mockLeads } from './leads';
|
||||
|
||||
// Use stable lead IDs for activities
|
||||
const lead1 = mockLeads[0].id; // new lead
|
||||
const lead2 = mockLeads[1].id; // new lead
|
||||
const contacted1 = mockLeads[20].id; // first contacted lead
|
||||
const contacted2 = mockLeads[21].id;
|
||||
const qualified1 = mockLeads[30].id; // first qualified lead
|
||||
const appt1 = mockLeads[35].id; // first appointment lead
|
||||
const converted1 = mockLeads[40].id; // first converted lead
|
||||
const spam1 = mockLeads[45].id; // first spam lead
|
||||
|
||||
export const mockLeadActivities: LeadActivity[] = [
|
||||
{
|
||||
id: 'activity-1',
|
||||
createdAt: daysAgo(2),
|
||||
activityType: 'STATUS_CHANGE',
|
||||
summary: 'Lead status changed from NEW to CONTACTED',
|
||||
occurredAt: daysAgo(2),
|
||||
performedBy: 'Rekha S.',
|
||||
previousValue: 'NEW',
|
||||
newValue: 'CONTACTED',
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: contacted1,
|
||||
},
|
||||
{
|
||||
id: 'activity-2',
|
||||
createdAt: daysAgo(1.8),
|
||||
activityType: 'WHATSAPP_SENT',
|
||||
summary: 'WhatsApp message sent — Women\'s Day Checkup template',
|
||||
occurredAt: daysAgo(1.8),
|
||||
performedBy: 'Rekha S.',
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
channel: 'WHATSAPP',
|
||||
durationSeconds: null,
|
||||
outcome: 'INFORMATION_SENT',
|
||||
leadId: contacted1,
|
||||
},
|
||||
{
|
||||
id: 'activity-3',
|
||||
createdAt: daysAgo(3),
|
||||
activityType: 'ASSIGNED',
|
||||
summary: 'Lead assigned to Suresh P.',
|
||||
occurredAt: daysAgo(3),
|
||||
performedBy: 'System',
|
||||
previousValue: null,
|
||||
newValue: 'Suresh P.',
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: contacted2,
|
||||
},
|
||||
{
|
||||
id: 'activity-4',
|
||||
createdAt: daysAgo(2.5),
|
||||
activityType: 'CALL_MADE',
|
||||
summary: 'Outbound call — patient confirmed interest in IVF consultation',
|
||||
occurredAt: daysAgo(2.5),
|
||||
performedBy: 'Suresh P.',
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
channel: 'PHONE',
|
||||
durationSeconds: 342,
|
||||
outcome: 'SUCCESSFUL',
|
||||
leadId: contacted2,
|
||||
},
|
||||
{
|
||||
id: 'activity-5',
|
||||
createdAt: daysAgo(4),
|
||||
activityType: 'STATUS_CHANGE',
|
||||
summary: 'Lead status changed from CONTACTED to QUALIFIED',
|
||||
occurredAt: daysAgo(4),
|
||||
performedBy: 'Suresh P.',
|
||||
previousValue: 'CONTACTED',
|
||||
newValue: 'QUALIFIED',
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: qualified1,
|
||||
},
|
||||
{
|
||||
id: 'activity-6',
|
||||
createdAt: daysAgo(3.5),
|
||||
activityType: 'NOTE_ADDED',
|
||||
summary: 'Patient is 32 years old, trying for 3 years, interested in IVF with donor eggs. Has been evaluated at another clinic — bring reports.',
|
||||
occurredAt: daysAgo(3.5),
|
||||
performedBy: 'Suresh P.',
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: qualified1,
|
||||
},
|
||||
{
|
||||
id: 'activity-7',
|
||||
createdAt: daysAgo(5),
|
||||
activityType: 'STATUS_CHANGE',
|
||||
summary: 'Lead status changed from QUALIFIED to APPOINTMENT_SET',
|
||||
occurredAt: daysAgo(5),
|
||||
performedBy: 'Rekha S.',
|
||||
previousValue: 'QUALIFIED',
|
||||
newValue: 'APPOINTMENT_SET',
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: appt1,
|
||||
},
|
||||
{
|
||||
id: 'activity-8',
|
||||
createdAt: daysAgo(4.8),
|
||||
activityType: 'WHATSAPP_SENT',
|
||||
summary: 'Appointment confirmation sent via WhatsApp — IVF Free Consultation template',
|
||||
occurredAt: daysAgo(4.8),
|
||||
performedBy: 'System',
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
channel: 'WHATSAPP',
|
||||
durationSeconds: null,
|
||||
outcome: 'INFORMATION_SENT',
|
||||
leadId: appt1,
|
||||
},
|
||||
{
|
||||
id: 'activity-9',
|
||||
createdAt: daysAgo(7),
|
||||
activityType: 'CONVERTED',
|
||||
summary: 'Lead successfully converted — Patient record created (ID: patient-mock-1045)',
|
||||
occurredAt: daysAgo(7),
|
||||
performedBy: 'Meena K.',
|
||||
previousValue: 'APPOINTMENT_SET',
|
||||
newValue: 'CONVERTED',
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: 'SUCCESSFUL',
|
||||
leadId: converted1,
|
||||
},
|
||||
{
|
||||
id: 'activity-10',
|
||||
createdAt: daysAgo(0.2),
|
||||
activityType: 'MARKED_SPAM',
|
||||
summary: 'Lead flagged as spam — spam score 87, invalid phone number pattern',
|
||||
occurredAt: daysAgo(0.2),
|
||||
performedBy: 'System',
|
||||
previousValue: 'false',
|
||||
newValue: 'true',
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: spam1,
|
||||
},
|
||||
{
|
||||
id: 'activity-11',
|
||||
createdAt: daysAgo(0.5),
|
||||
activityType: 'DUPLICATE_DETECTED',
|
||||
summary: 'Duplicate lead detected — same phone number as lead-new-1',
|
||||
occurredAt: daysAgo(0.5),
|
||||
performedBy: 'System',
|
||||
previousValue: null,
|
||||
newValue: lead1,
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: mockLeads[47].id, // lead-dup-1
|
||||
},
|
||||
{
|
||||
id: 'activity-12',
|
||||
createdAt: daysAgo(0.1),
|
||||
activityType: 'ASSIGNED',
|
||||
summary: 'Lead auto-assigned to Rekha S. based on availability',
|
||||
occurredAt: daysAgo(0.1),
|
||||
performedBy: 'System',
|
||||
previousValue: null,
|
||||
newValue: 'Rekha S.',
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: lead2,
|
||||
},
|
||||
{
|
||||
id: 'activity-13',
|
||||
createdAt: daysAgo(1.2),
|
||||
activityType: 'CALL_MADE',
|
||||
summary: 'Outbound call — no answer, will retry tomorrow',
|
||||
occurredAt: daysAgo(1.2),
|
||||
performedBy: 'Rekha S.',
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
channel: 'PHONE',
|
||||
durationSeconds: 15,
|
||||
outcome: 'NO_ANSWER',
|
||||
leadId: contacted1,
|
||||
},
|
||||
{
|
||||
id: 'activity-14',
|
||||
createdAt: daysAgo(6),
|
||||
activityType: 'FOLLOW_UP_CREATED',
|
||||
summary: 'Follow-up scheduled for callback — patient requested call after office hours',
|
||||
occurredAt: daysAgo(6),
|
||||
performedBy: 'Suresh P.',
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: 'CALLBACK_REQUESTED',
|
||||
leadId: qualified1,
|
||||
},
|
||||
{
|
||||
id: 'activity-15',
|
||||
createdAt: daysAgo(8),
|
||||
activityType: 'NOTE_ADDED',
|
||||
summary: 'Senior Health Package — patient is 68 years old, diabetic, requested cardiac screening add-on. Budget sensitive — offered 10% senior discount.',
|
||||
occurredAt: daysAgo(8),
|
||||
performedBy: 'Meena K.',
|
||||
previousValue: null,
|
||||
newValue: null,
|
||||
channel: 'SYSTEM',
|
||||
durationSeconds: null,
|
||||
outcome: null,
|
||||
leadId: converted1,
|
||||
},
|
||||
];
|
||||
210
src/mocks/leads.ts
Normal file
210
src/mocks/leads.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import type { Lead } from '@/types/entities';
|
||||
import { createMockLead, daysAgo, randomFrom, indianFirstNames, nextId } from './factories';
|
||||
import { CAMPAIGN_ID_WD, CAMPAIGN_ID_GH, CAMPAIGN_ID_IVF, CAMPAIGN_ID_SN, CAMPAIGN_ID_DA } from './campaigns';
|
||||
import { AD_ID_WD_1, AD_ID_WD_2, AD_ID_WD_3, AD_ID_GH_1, AD_ID_GH_2, AD_ID_IVF_1, AD_ID_IVF_2, AD_ID_IVF_3, AD_ID_SN_1 } from './ads';
|
||||
|
||||
const campaignPool = [CAMPAIGN_ID_WD, CAMPAIGN_ID_GH, CAMPAIGN_ID_IVF, CAMPAIGN_ID_SN, CAMPAIGN_ID_DA];
|
||||
const adPool = [AD_ID_WD_1, AD_ID_WD_2, AD_ID_WD_3, AD_ID_GH_1, AD_ID_GH_2, AD_ID_IVF_1, AD_ID_IVF_2, AD_ID_IVF_3, AD_ID_SN_1];
|
||||
const agents = ['Rekha S.', 'Suresh P.', 'Meena K.'];
|
||||
|
||||
// --- 20 NEW leads (0-2 days old) ---
|
||||
const newLeads: Lead[] = Array.from({ length: 20 }, (_, i) => {
|
||||
const campaignId = randomFrom(campaignPool);
|
||||
return createMockLead({
|
||||
id: `lead-new-${i + 1}`,
|
||||
leadStatus: 'NEW',
|
||||
createdAt: daysAgo(Math.random() * 2),
|
||||
updatedAt: daysAgo(Math.random() * 1),
|
||||
spamScore: Math.floor(Math.random() * 40), // low spam for new
|
||||
isSpam: false,
|
||||
campaignId,
|
||||
adId: randomFrom(adPool),
|
||||
assignedAgent: null,
|
||||
firstContactedAt: null,
|
||||
lastContactedAt: null,
|
||||
contactAttempts: 0,
|
||||
});
|
||||
});
|
||||
|
||||
// --- 10 CONTACTED leads (1-4 days old) ---
|
||||
const contactedLeads: Lead[] = Array.from({ length: 10 }, (_, i) => {
|
||||
const created = daysAgo(1 + Math.random() * 3);
|
||||
const firstContacted = daysAgo(0.5 + Math.random() * 1.5);
|
||||
const lastContacted = daysAgo(Math.random() * 0.5);
|
||||
return createMockLead({
|
||||
id: `lead-contacted-${i + 1}`,
|
||||
leadStatus: 'CONTACTED',
|
||||
createdAt: created,
|
||||
updatedAt: lastContacted,
|
||||
spamScore: Math.floor(Math.random() * 45),
|
||||
isSpam: false,
|
||||
campaignId: randomFrom(campaignPool),
|
||||
adId: randomFrom(adPool),
|
||||
assignedAgent: randomFrom(agents),
|
||||
firstContactedAt: firstContacted,
|
||||
lastContactedAt: lastContacted,
|
||||
contactAttempts: 1 + Math.floor(Math.random() * 3),
|
||||
});
|
||||
});
|
||||
|
||||
// --- 5 QUALIFIED leads (3-7 days old) ---
|
||||
const qualifiedLeads: Lead[] = Array.from({ length: 5 }, (_, i) => {
|
||||
const created = daysAgo(3 + Math.random() * 4);
|
||||
const firstContacted = daysAgo(2 + Math.random() * 2);
|
||||
const lastContacted = daysAgo(0.5 + Math.random() * 1);
|
||||
return createMockLead({
|
||||
id: `lead-qualified-${i + 1}`,
|
||||
leadStatus: 'QUALIFIED',
|
||||
priority: 'HIGH',
|
||||
createdAt: created,
|
||||
updatedAt: lastContacted,
|
||||
spamScore: Math.floor(Math.random() * 30),
|
||||
isSpam: false,
|
||||
campaignId: randomFrom([CAMPAIGN_ID_WD, CAMPAIGN_ID_IVF, CAMPAIGN_ID_GH]),
|
||||
adId: randomFrom(adPool),
|
||||
assignedAgent: randomFrom(agents),
|
||||
firstContactedAt: firstContacted,
|
||||
lastContactedAt: lastContacted,
|
||||
contactAttempts: 2 + Math.floor(Math.random() * 3),
|
||||
});
|
||||
});
|
||||
|
||||
// --- 5 APPOINTMENT_SET leads (5-10 days old) ---
|
||||
const appointmentLeads: Lead[] = Array.from({ length: 5 }, (_, i) => {
|
||||
const created = daysAgo(5 + Math.random() * 5);
|
||||
const firstContacted = daysAgo(4 + Math.random() * 2);
|
||||
const lastContacted = daysAgo(1 + Math.random() * 2);
|
||||
return createMockLead({
|
||||
id: `lead-appt-${i + 1}`,
|
||||
leadStatus: 'APPOINTMENT_SET',
|
||||
priority: 'HIGH',
|
||||
createdAt: created,
|
||||
updatedAt: lastContacted,
|
||||
spamScore: Math.floor(Math.random() * 25),
|
||||
isSpam: false,
|
||||
campaignId: randomFrom([CAMPAIGN_ID_WD, CAMPAIGN_ID_IVF, CAMPAIGN_ID_GH]),
|
||||
adId: randomFrom(adPool),
|
||||
assignedAgent: randomFrom(agents),
|
||||
firstContactedAt: firstContacted,
|
||||
lastContactedAt: lastContacted,
|
||||
contactAttempts: 3 + Math.floor(Math.random() * 3),
|
||||
});
|
||||
});
|
||||
|
||||
// --- 5 CONVERTED leads (7-14 days old) ---
|
||||
const convertedLeads: Lead[] = Array.from({ length: 5 }, (_, i) => {
|
||||
const created = daysAgo(7 + Math.random() * 7);
|
||||
const firstContacted = daysAgo(6 + Math.random() * 3);
|
||||
const lastContacted = daysAgo(1 + Math.random() * 3);
|
||||
const convertedAt = daysAgo(0.5 + Math.random() * 2);
|
||||
const patientId = `patient-${nextId()}`;
|
||||
return createMockLead({
|
||||
id: `lead-converted-${i + 1}`,
|
||||
leadStatus: 'CONVERTED',
|
||||
priority: 'NORMAL',
|
||||
createdAt: created,
|
||||
updatedAt: convertedAt,
|
||||
spamScore: Math.floor(Math.random() * 20),
|
||||
isSpam: false,
|
||||
campaignId: randomFrom([CAMPAIGN_ID_WD, CAMPAIGN_ID_IVF, CAMPAIGN_ID_GH, CAMPAIGN_ID_SN]),
|
||||
adId: randomFrom(adPool),
|
||||
assignedAgent: randomFrom(agents),
|
||||
firstContactedAt: firstContacted,
|
||||
lastContactedAt: lastContacted,
|
||||
contactAttempts: 4 + Math.floor(Math.random() * 4),
|
||||
convertedAt,
|
||||
patientId,
|
||||
});
|
||||
});
|
||||
|
||||
// --- 3 SPAM leads (spamScore >= 60, isSpam: true) ---
|
||||
const spamLeads: Lead[] = [
|
||||
createMockLead({
|
||||
id: 'lead-spam-1',
|
||||
leadStatus: 'NEW',
|
||||
createdAt: daysAgo(0.3),
|
||||
updatedAt: daysAgo(0.1),
|
||||
contactName: { firstName: 'Test', lastName: 'User' },
|
||||
contactPhone: [{ number: '+911111111111', callingCode: '+91' }],
|
||||
contactEmail: [{ address: 'test@test.com' }],
|
||||
spamScore: 87,
|
||||
isSpam: true,
|
||||
campaignId: CAMPAIGN_ID_WD,
|
||||
adId: AD_ID_WD_1,
|
||||
assignedAgent: null,
|
||||
}),
|
||||
createMockLead({
|
||||
id: 'lead-spam-2',
|
||||
leadStatus: 'NEW',
|
||||
createdAt: daysAgo(1),
|
||||
updatedAt: daysAgo(0.5),
|
||||
contactName: { firstName: 'Fake', lastName: 'Lead' },
|
||||
contactPhone: [{ number: '+919999999999', callingCode: '+91' }],
|
||||
contactEmail: [{ address: 'spam123@yopmail.com' }],
|
||||
spamScore: 95,
|
||||
isSpam: true,
|
||||
campaignId: CAMPAIGN_ID_IVF,
|
||||
adId: AD_ID_IVF_1,
|
||||
assignedAgent: null,
|
||||
}),
|
||||
createMockLead({
|
||||
id: 'lead-spam-3',
|
||||
leadStatus: 'NEW',
|
||||
createdAt: daysAgo(2),
|
||||
updatedAt: daysAgo(1),
|
||||
contactName: { firstName: 'Random', lastName: 'Bot' },
|
||||
contactPhone: [{ number: '+910000000000', callingCode: '+91' }],
|
||||
contactEmail: [{ address: 'noone@nowhere.com' }],
|
||||
spamScore: 72,
|
||||
isSpam: true,
|
||||
campaignId: CAMPAIGN_ID_GH,
|
||||
adId: AD_ID_GH_1,
|
||||
assignedAgent: null,
|
||||
}),
|
||||
];
|
||||
|
||||
// --- 2 DUPLICATE leads (isDuplicate: true, pointing to existing leads) ---
|
||||
const duplicateLeads: Lead[] = [
|
||||
createMockLead({
|
||||
id: 'lead-dup-1',
|
||||
leadStatus: 'NEW',
|
||||
// Same name/phone as lead-new-1 to simulate duplicate
|
||||
contactName: newLeads[0].contactName,
|
||||
contactPhone: newLeads[0].contactPhone,
|
||||
contactEmail: [{ address: `dup.${randomFrom(indianFirstNames).toLowerCase()}@gmail.com` }],
|
||||
createdAt: daysAgo(0.5),
|
||||
updatedAt: daysAgo(0.2),
|
||||
spamScore: 12,
|
||||
isSpam: false,
|
||||
isDuplicate: true,
|
||||
duplicateOfLeadId: newLeads[0].id,
|
||||
campaignId: CAMPAIGN_ID_WD,
|
||||
adId: AD_ID_WD_2,
|
||||
}),
|
||||
createMockLead({
|
||||
id: 'lead-dup-2',
|
||||
leadStatus: 'NEW',
|
||||
// Same name/phone as lead-contacted-1 to simulate duplicate
|
||||
contactName: contactedLeads[0].contactName,
|
||||
contactPhone: contactedLeads[0].contactPhone,
|
||||
contactEmail: contactedLeads[0].contactEmail,
|
||||
createdAt: daysAgo(0.8),
|
||||
updatedAt: daysAgo(0.3),
|
||||
spamScore: 18,
|
||||
isSpam: false,
|
||||
isDuplicate: true,
|
||||
duplicateOfLeadId: contactedLeads[0].id,
|
||||
campaignId: CAMPAIGN_ID_IVF,
|
||||
adId: AD_ID_IVF_2,
|
||||
}),
|
||||
];
|
||||
|
||||
export const mockLeads: Lead[] = [
|
||||
...newLeads,
|
||||
...contactedLeads,
|
||||
...qualifiedLeads,
|
||||
...appointmentLeads,
|
||||
...convertedLeads,
|
||||
...spamLeads,
|
||||
...duplicateLeads,
|
||||
];
|
||||
80
src/mocks/templates.ts
Normal file
80
src/mocks/templates.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import type { WhatsAppTemplate } from '@/types/entities';
|
||||
import { CAMPAIGN_ID_WD, CAMPAIGN_ID_IVF, CAMPAIGN_ID_GH, CAMPAIGN_ID_SN } from './campaigns';
|
||||
|
||||
export const mockTemplates: WhatsAppTemplate[] = [
|
||||
{
|
||||
id: 'template-1',
|
||||
name: "Women's Day Health Checkup",
|
||||
body: "Namaste {{patient_name}} 🌸\n\nHappy Women's Day from all of us at {{hospital_name}}!\n\nAs a special gift for Women's Day, we're offering a **Free Comprehensive Health Checkup** exclusively for women.\n\nThis includes:\n• Blood pressure & sugar screening\n• BMI & nutritional assessment\n• Gynaecological consultation\n\nCampaign: {{campaign_name}}\n\nBook your slot here: {{booking_link}}\n\nLimited slots available. Offer valid this month only.\n\nWarm regards,\nCare Team, {{hospital_name}}",
|
||||
variables: ['patient_name', 'hospital_name', 'campaign_name', 'booking_link'],
|
||||
linkedCampaignId: CAMPAIGN_ID_WD,
|
||||
linkedCampaignName: "Women's Day Health Checkup",
|
||||
approvalStatus: 'APPROVED',
|
||||
language: ['en'],
|
||||
sendCount: 142,
|
||||
deliveredCount: 138,
|
||||
readCount: 104,
|
||||
clickedCount: 62,
|
||||
failedCount: 4,
|
||||
},
|
||||
{
|
||||
id: 'template-2',
|
||||
name: 'IVF Free Consultation',
|
||||
body: "Namaste {{patient_name}},\n\nThank you for your interest in IVF treatment at {{hospital_name}}.\n\nWe would like to invite you for a **FREE first consultation** with our senior IVF specialist. This is a no-obligation session where we will:\n\n✅ Review your fertility history\n✅ Recommend the right treatment plan\n✅ Answer all your questions\n\nCampaign: {{campaign_name}}\n\nBook your free consultation here: {{booking_link}}\n\nYour journey to parenthood starts with one step. We're here for you.\n\nWith care,\n{{hospital_name}} Fertility Centre",
|
||||
variables: ['patient_name', 'hospital_name', 'campaign_name', 'booking_link'],
|
||||
linkedCampaignId: CAMPAIGN_ID_IVF,
|
||||
linkedCampaignName: 'IVF Consultation — Free First Visit',
|
||||
approvalStatus: 'APPROVED',
|
||||
language: ['en'],
|
||||
sendCount: 98,
|
||||
deliveredCount: 96,
|
||||
readCount: 78,
|
||||
clickedCount: 44,
|
||||
failedCount: 2,
|
||||
},
|
||||
{
|
||||
id: 'template-3',
|
||||
name: 'Cervical Screening Reminder',
|
||||
body: "Namaste {{patient_name}},\n\nThis is a gentle reminder from {{hospital_name}}.\n\n🎗️ **Cervical cancer is preventable with early screening.**\n\nWe are running a special screening drive as part of our {{campaign_name}}. A Pap smear test takes less than 10 minutes and can save your life.\n\nBook your screening appointment here: {{booking_link}}\n\nOur gynaecology team is available Monday to Saturday, 9 AM to 5 PM.\n\nTake care,\n{{hospital_name}}",
|
||||
variables: ['patient_name', 'hospital_name', 'campaign_name', 'booking_link'],
|
||||
linkedCampaignId: CAMPAIGN_ID_GH,
|
||||
linkedCampaignName: 'Cervical Cancer Screening Drive',
|
||||
approvalStatus: 'APPROVED',
|
||||
language: ['en'],
|
||||
sendCount: 56,
|
||||
deliveredCount: 54,
|
||||
readCount: 38,
|
||||
clickedCount: 21,
|
||||
failedCount: 2,
|
||||
},
|
||||
{
|
||||
id: 'template-4',
|
||||
name: 'General Follow-up',
|
||||
body: "Namaste {{patient_name}},\n\nThis is {{hospital_name}} reaching out to follow up on your recent enquiry.\n\nWe noticed you expressed interest in our services. Our care coordinator would love to help you find the right treatment plan.\n\nWould you like us to call you at a convenient time? Or you can book a consultation directly here: {{booking_link}}\n\nWe are available Monday to Saturday, 8 AM to 8 PM.\n\nLooking forward to serving you.\n\nWarm regards,\nPatient Care Team\n{{hospital_name}}",
|
||||
variables: ['patient_name', 'hospital_name', 'booking_link'],
|
||||
linkedCampaignId: null,
|
||||
linkedCampaignName: null,
|
||||
approvalStatus: 'APPROVED',
|
||||
language: ['en', 'kn', 'hi'],
|
||||
sendCount: 210,
|
||||
deliveredCount: 205,
|
||||
readCount: 162,
|
||||
clickedCount: 88,
|
||||
failedCount: 5,
|
||||
},
|
||||
{
|
||||
id: 'template-5',
|
||||
name: 'Senior Health Package',
|
||||
body: "Namaste {{patient_name}},\n\nAt {{hospital_name}}, we believe every senior deserves the best care.\n\nOur **Senior Health Package** is designed specifically for individuals above 60 years. It includes 40+ tests covering:\n\n🫀 Cardiac Health\n🩸 Diabetes & Thyroid\n🦴 Joint & Bone Density\n👁️ Vision & Hearing\n\nCampaign: {{campaign_name}}\n\nSpecial senior discount available. Book here: {{booking_link}}\n\nFor home collection or assistance, call us at 080-1234-5678.\n\nWith care,\n{{hospital_name}}",
|
||||
variables: ['patient_name', 'hospital_name', 'campaign_name', 'booking_link'],
|
||||
linkedCampaignId: CAMPAIGN_ID_SN,
|
||||
linkedCampaignName: 'Senior Health Package',
|
||||
approvalStatus: 'PENDING',
|
||||
language: ['en', 'kn'],
|
||||
sendCount: 0,
|
||||
deliveredCount: 0,
|
||||
readCount: 0,
|
||||
clickedCount: 0,
|
||||
failedCount: 0,
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user