export function aiChatbotRoiQuiz(form: FormTs) {
form.setTitle(() => '🤖 How Much Could an AI Chatbot Save Your Support Team?');
// ============ CALCULATOR STATE ============
const inputs = form.state<Record<string, number>>({
supportAgents: 5,
avgSalary: 45000,
ticketsPerMonth: 1000,
avgHandleTime: 15,
repeatTicketRate: 30,
afterHoursTickets: 20
});
const updateInput = (key: string, value: number) => {
inputs.update(current => ({ ...current, [key]: value }));
};
// ============ CALCULATIONS ============
const getMonthlyLaborCost = () => {
const i = inputs();
return (i.supportAgents * i.avgSalary) / 12;
};
const getTimeSpentOnRepeatTickets = () => {
const i = inputs();
const totalMinutes = i.ticketsPerMonth * i.avgHandleTime;
const repeatMinutes = totalMinutes * (i.repeatTicketRate / 100);
return repeatMinutes / 60; // hours
};
const getCostOfRepeatTickets = () => {
const hours = getTimeSpentOnRepeatTickets();
const hourlyRate = (inputs().avgSalary / 12) / 160; // 160 work hours per month
return hours * hourlyRate * inputs().supportAgents / inputs().supportAgents; // per agent portion
};
const getAfterHoursCost = () => {
const i = inputs();
const afterHoursTickets = i.ticketsPerMonth * (i.afterHoursTickets / 100);
const minutesNeeded = afterHoursTickets * i.avgHandleTime;
const hoursNeeded = minutesNeeded / 60;
// After-hours support typically costs 1.5x
const hourlyRate = ((i.avgSalary / 12) / 160) * 1.5;
return hoursNeeded * hourlyRate;
};
const getAiDeflectionRate = () => {
// Estimate based on ticket characteristics
const i = inputs();
const base = 40; // Base deflection rate
const repeatBonus = Math.min(i.repeatTicketRate * 0.5, 20); // Higher repeat = more deflectable
return Math.min(base + repeatBonus, 70);
};
const getMonthlySavings = () => {
const deflectionRate = getAiDeflectionRate() / 100;
const i = inputs();
// Savings from deflected tickets
const ticketsDeflected = i.ticketsPerMonth * deflectionRate;
const minutesSaved = ticketsDeflected * i.avgHandleTime;
const hoursSaved = minutesSaved / 60;
const hourlyRate = (i.avgSalary / 12) / 160;
const ticketSavings = hoursSaved * hourlyRate;
// After-hours coverage (AI handles these without overtime)
const afterHoursSavings = getAfterHoursCost() * 0.8; // AI handles 80% of after-hours
return ticketSavings + afterHoursSavings;
};
const getAnnualSavings = () => getMonthlySavings() * 12;
const getEstimatedChatbotCost = () => {
const i = inputs();
// Typical chatbot pricing: $500-2000/month base + $0.01-0.05 per conversation
const baseCost = i.ticketsPerMonth > 5000 ? 1500 : i.ticketsPerMonth > 1000 ? 800 : 400;
const perConversation = i.ticketsPerMonth * 0.02;
return baseCost + perConversation;
};
const getNetMonthlySavings = () => getMonthlySavings() - getEstimatedChatbotCost();
const getNetAnnualSavings = () => getNetMonthlySavings() * 12;
const getRoiPercentage = () => {
const annualCost = getEstimatedChatbotCost() * 12;
const annualSavings = getAnnualSavings();
return Math.round((annualSavings / annualCost) * 100);
};
const getPaybackMonths = () => {
const monthlySavings = getNetMonthlySavings();
if (monthlySavings <= 0) return 999;
const setupCost = 2000; // One-time setup
return Math.ceil(setupCost / monthlySavings);
};
const formatCurrency = (value: number) => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0
}).format(value);
};
// ============ COMPLETION SCREEN ============
form.configureCompletionScreen({
type: 'text',
title: () => `💰 Potential Annual Savings: ${formatCurrency(getNetAnnualSavings())}`,
message: () => {
const roi = getRoiPercentage();
const payback = getPaybackMonths();
return `Based on your inputs, an AI chatbot could deliver ${roi}% ROI with a payback period of ${payback} months. Download your detailed analysis for implementation recommendations.`;
}
});
// ============ PAGES SETUP ============
const pages = form.addPages('quiz-pages', {
heightMode: 'current-page'
});
// ============ PAGE 1: Team Size & Costs ============
const page1 = pages.addPage('team-costs', { mobileBreakpoint: 500 });
page1.addRow(row => {
row.addTextPanel('header1', {
label: 'Step 1 of 5: Your Support Team',
computedValue: () => 'Tell us about your current support operation',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page1.addSpacer({ height: '24px' });
page1.addRow(row => {
row.addSlider('supportAgents', {
label: 'How many support agents do you have?',
isRequired: true,
min: 1,
max: 50,
step: 1,
unit: 'agents',
defaultValue: 5,
onValueChange: (val) => {
if (val != null) updateInput('supportAgents', val);
}
});
});
page1.addRow(row => {
row.addSlider('avgSalary', {
label: 'Average annual salary per agent',
tooltip: 'Include benefits and overhead (typically 1.3x base salary)',
isRequired: true,
min: 25000,
max: 100000,
step: 5000,
unit: '/year',
defaultValue: 45000,
onValueChange: (val) => {
if (val != null) updateInput('avgSalary', val);
}
});
});
page1.addRow(row => {
row.addTextPanel('currentCost', {
label: '💵 Current Monthly Labor Cost',
computedValue: () => formatCurrency(getMonthlyLaborCost()),
customStyles: {
fontSize: '1.2rem',
fontWeight: '700',
color: '#dc2626',
textAlign: 'center',
padding: '15px',
background: '#fef2f2',
borderRadius: '8px',
border: '2px solid #fecaca'
}
});
});
// ============ PAGE 2: Ticket Volume ============
const page2 = pages.addPage('ticket-volume', { mobileBreakpoint: 500 });
page2.addRow(row => {
row.addTextPanel('header2', {
label: 'Step 2 of 5: Ticket Volume',
computedValue: () => 'How many support requests do you handle?',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page2.addSpacer({ height: '24px' });
page2.addRow(row => {
row.addSlider('ticketsPerMonth', {
label: 'How many support tickets per month?',
isRequired: true,
min: 100,
max: 10000,
step: 100,
unit: 'tickets',
defaultValue: 1000,
onValueChange: (val) => {
if (val != null) updateInput('ticketsPerMonth', val);
}
});
});
page2.addRow(row => {
row.addSlider('avgHandleTime', {
label: 'Average handle time per ticket',
tooltip: 'Include response time + resolution time',
isRequired: true,
min: 5,
max: 60,
step: 5,
unit: 'minutes',
defaultValue: 15,
onValueChange: (val) => {
if (val != null) updateInput('avgHandleTime', val);
}
});
});
page2.addRow(row => {
row.addTextPanel('ticketCostInfo', {
computedValue: () => {
const i = inputs();
const costPerTicket = ((i.avgSalary / 12) / 160) * (i.avgHandleTime / 60);
return `📊 Estimated cost per ticket: ${formatCurrency(costPerTicket)}`;
},
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
textAlign: 'center',
padding: '10px',
background: '#f3f4f6',
borderRadius: '6px'
}
});
});
// ============ PAGE 3: Automation Opportunity ============
const page3 = pages.addPage('automation-opportunity', { mobileBreakpoint: 500 });
page3.addRow(row => {
row.addTextPanel('header3', {
label: 'Step 3 of 5: Automation Opportunity',
computedValue: () => 'Help us estimate how much can be automated',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page3.addSpacer({ height: '24px' });
page3.addRow(row => {
row.addSlider('repeatTicketRate', {
label: 'What % of tickets are repetitive questions?',
tooltip: 'FAQ-type questions, password resets, status checks, etc.',
isRequired: true,
min: 10,
max: 80,
step: 5,
unit: '%',
defaultValue: 30,
onValueChange: (val) => {
if (val != null) updateInput('repeatTicketRate', val);
}
});
});
page3.addRow(row => {
row.addSlider('afterHoursTickets', {
label: 'What % of tickets come outside business hours?',
tooltip: 'These typically require overtime or delayed response',
isRequired: true,
min: 0,
max: 50,
step: 5,
unit: '%',
defaultValue: 20,
onValueChange: (val) => {
if (val != null) updateInput('afterHoursTickets', val);
}
});
});
page3.addRow(row => {
row.addSuggestionChips('ticketTypes', {
label: 'What types of tickets do you receive most? (helps estimate AI capability)',
suggestions: [
{ id: 'faq', name: '❓ FAQ/How-to' },
{ id: 'status', name: '📦 Order Status' },
{ id: 'password', name: '🔑 Password/Account' },
{ id: 'billing', name: '💳 Billing Questions' },
{ id: 'technical', name: '🔧 Technical Support' },
{ id: 'complaints', name: '😤 Complaints' },
{ id: 'returns', name: '📦 Returns/Refunds' }
],
min: 1
});
});
page3.addRow(row => {
row.addTextPanel('deflectionEstimate', {
computedValue: () => {
const rate = getAiDeflectionRate();
return `🤖 Estimated AI Deflection Rate: ${rate}%`;
},
customStyles: {
fontSize: '1.1rem',
fontWeight: '600',
color: '#059669',
textAlign: 'center',
padding: '12px',
background: '#ecfdf5',
borderRadius: '8px',
border: '2px solid #6ee7b7'
}
});
});
// ============ PAGE 4: Results ============
const page4 = pages.addPage('results', { mobileBreakpoint: 500 });
page4.addRow(row => {
row.addTextPanel('header4', {
label: 'Step 4 of 5: Your ROI Analysis',
computedValue: () => 'Here\'s what an AI chatbot could save you',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page4.addSpacer({ height: '24px' });
page4.addRow(row => {
row.addTextPanel('savingsHeader', {
label: '💰 Projected Annual Net Savings',
computedValue: () => '',
customStyles: {
fontSize: '1rem',
fontWeight: '600',
textAlign: 'center'
}
});
});
page4.addRow(row => {
row.addTextPanel('annualSavings', {
computedValue: () => formatCurrency(getNetAnnualSavings()),
customStyles: () => ({
fontSize: '2.5rem',
fontWeight: '800',
textAlign: 'center',
color: getNetAnnualSavings() > 0 ? '#059669' : '#dc2626',
padding: '20px',
background: getNetAnnualSavings() > 0 ? '#ecfdf5' : '#fef2f2',
borderRadius: '12px',
border: `3px solid ${getNetAnnualSavings() > 0 ? '#6ee7b7' : '#fca5a5'}`
})
});
});
page4.addRow(row => {
row.addTextPanel('roiMetric', {
computedValue: () => `📈 ${getRoiPercentage()}% ROI`,
customStyles: {
fontSize: '1.3rem',
fontWeight: '700',
color: '#1e40af',
textAlign: 'center',
marginTop: '10px'
}
}, '1fr');
row.addTextPanel('paybackMetric', {
computedValue: () => `⏱️ ${getPaybackMonths()} month payback`,
customStyles: {
fontSize: '1.3rem',
fontWeight: '700',
color: '#1e40af',
textAlign: 'center',
marginTop: '10px'
}
}, '1fr');
});
const breakdownSection = page4.addSubform('breakdownSection', {
title: '📊 Detailed Breakdown (click to expand)',
isCollapsible: true,
customStyles: {
marginTop: '1rem',
background: '#f9fafb',
borderRadius: '8px'
}
});
breakdownSection.addRow(row => {
row.addTextPanel('grossSavings', {
label: 'Gross Monthly Savings',
computedValue: () => formatCurrency(getMonthlySavings()),
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#d1fae5',
borderRadius: '6px'
}
}, '1fr');
row.addTextPanel('chatbotCost', {
label: 'Est. Chatbot Cost/Month',
computedValue: () => formatCurrency(getEstimatedChatbotCost()),
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#fee2e2',
borderRadius: '6px'
}
}, '1fr');
});
breakdownSection.addRow(row => {
row.addTextPanel('ticketsDeflected', {
label: 'Tickets Deflected/Month',
computedValue: () => {
const i = inputs();
const deflected = Math.round(i.ticketsPerMonth * (getAiDeflectionRate() / 100));
return `${deflected} tickets`;
},
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#dbeafe',
borderRadius: '6px'
}
}, '1fr');
row.addTextPanel('hoursSaved', {
label: 'Agent Hours Saved/Month',
computedValue: () => {
const i = inputs();
const deflected = i.ticketsPerMonth * (getAiDeflectionRate() / 100);
const hours = Math.round((deflected * i.avgHandleTime) / 60);
return `${hours} hours`;
},
customStyles: {
fontSize: '0.9rem',
padding: '8px 12px',
background: '#dbeafe',
borderRadius: '6px'
}
}, '1fr');
});
// ============ PAGE 5: Lead Capture ============
const page5 = pages.addPage('lead-capture', { mobileBreakpoint: 500 });
page5.addRow(row => {
row.addTextPanel('header5', {
label: 'Step 5 of 5: Get Your Full Analysis',
computedValue: () => 'Enter your details to receive your personalized ROI report',
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
marginBottom: '1rem'
}
});
});
page5.addSpacer({ height: '24px' });
page5.addRow(row => {
row.addTextbox('name', {
label: 'Your Name',
isRequired: true,
placeholder: 'Jordan Lee'
}, '1fr');
row.addEmail('email', {
label: 'Work Email',
isRequired: true,
placeholder: 'jordan@company.com'
}, '1fr');
});
page5.addRow(row => {
row.addTextbox('company', {
label: 'Company Name',
placeholder: 'Acme Support Co.'
}, '1fr');
row.addDropdown('currentTools', {
label: 'Current Support Platform',
options: [
{ id: 'zendesk', name: 'Zendesk' },
{ id: 'freshdesk', name: 'Freshdesk' },
{ id: 'intercom', name: 'Intercom' },
{ id: 'hubspot', name: 'HubSpot Service Hub' },
{ id: 'salesforce', name: 'Salesforce Service Cloud' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select platform'
}, '1fr');
});
page5.addRow(row => {
row.addCheckboxList('consent', {
options: [
{ id: 'report', name: '📄 Send me the detailed ROI analysis report', isRequired: true },
{ id: 'demo', name: '🤖 I\'d like a personalized chatbot demo' },
{ id: 'tips', name: '💡 Send me AI support automation tips' }
],
defaultValue: ['report'],
orientation: 'vertical'
});
});
// ============ PDF REPORT ============
form.configurePdf('chatbot-roi-report', pdf => {
pdf.configure({
filename: 'ai-chatbot-roi-analysis.pdf',
pageSize: 'A4',
allowUserDownload: true,
downloadButtonLabel: '📄 Download ROI Report',
header: {
title: 'AI Chatbot ROI Analysis',
subtitle: 'Personalized Savings Projection'
},
footer: {
text: 'Generated by FormTs AI ROI Calculator',
showPageNumbers: true
}
});
pdf.addSection('Executive Summary', section => {
section.addRow(row => {
row.addField('Annual Net Savings', formatCurrency(getNetAnnualSavings()));
row.addField('ROI', `${getRoiPercentage()}%`);
});
section.addRow(row => {
row.addField('Payback Period', `${getPaybackMonths()} months`);
row.addField('AI Deflection Rate', `${getAiDeflectionRate()}%`);
});
});
pdf.addSection('Your Current State', section => {
const i = inputs();
section.addTable(
['Metric', 'Value'],
[
['Support Agents', `${i.supportAgents}`],
['Monthly Tickets', `${i.ticketsPerMonth}`],
['Avg Handle Time', `${i.avgHandleTime} minutes`],
['Repetitive Tickets', `${i.repeatTicketRate}%`],
['After-Hours Tickets', `${i.afterHoursTickets}%`],
['Monthly Labor Cost', formatCurrency(getMonthlyLaborCost())]
]
);
});
pdf.addPageBreak();
pdf.addSection('Projected Impact', section => {
section.addTable(
['Category', 'Monthly', 'Annual'],
[
['Gross Savings', formatCurrency(getMonthlySavings()), formatCurrency(getMonthlySavings() * 12)],
['Chatbot Cost', `(${formatCurrency(getEstimatedChatbotCost())})`, `(${formatCurrency(getEstimatedChatbotCost() * 12)})`],
['Net Savings', formatCurrency(getNetMonthlySavings()), formatCurrency(getNetAnnualSavings())]
]
);
});
pdf.addSection('Implementation Recommendations', section => {
section.addText('Phase 1 (Month 1-2): Start with FAQ automation');
section.addText('Phase 2 (Month 2-3): Add order status and account queries');
section.addText('Phase 3 (Month 3-4): Enable after-hours coverage');
section.addText('Phase 4 (Month 4+): Continuous optimization and expansion');
});
pdf.addSection('Recommended AI Chatbot Platforms', section => {
section.addText('• Intercom Fin - Best for existing Intercom users');
section.addText('• Zendesk AI - Best for Zendesk ecosystems');
section.addText('• Ada - Best for enterprise scale');
section.addText('• Tidio - Best for SMB budget');
});
});
// ============ SUBMIT BUTTON ============
form.configureSubmitButton({
label: () => `🤖 Get My ROI Report (Save ${formatCurrency(getNetAnnualSavings())}/year)`
});
form.configureSubmitBehavior({
sendToServer: true
});
}