export function meetingCostQuiz(form: FormTs) {
form.setTitle(() => '⏱️ Calculate Your Meeting Overload Cost');
// ========== STATE ==========
const inputs = form.state<{
employees: number;
avgSalary: number;
meetingsPerWeek: number;
avgMeetingLength: number;
unnecessaryPercent: number;
attendeesOverloaded: number;
}>({
employees: 50,
avgSalary: 75000,
meetingsPerWeek: 10,
avgMeetingLength: 45,
unnecessaryPercent: 30,
attendeesOverloaded: 3
});
// ========== CALCULATIONS ==========
const getHourlyRate = () => {
return Math.round(inputs().avgSalary / 2080); // 40hrs x 52 weeks
};
const getWeeklyMeetingHours = () => {
const meetingsPerWeek = inputs().meetingsPerWeek;
const avgLength = inputs().avgMeetingLength;
return Math.round((meetingsPerWeek * avgLength) / 60 * 10) / 10;
};
const getWeeklyMeetingCostPerPerson = () => {
return Math.round(getWeeklyMeetingHours() * getHourlyRate());
};
const getAnnualMeetingCostPerPerson = () => {
return getWeeklyMeetingCostPerPerson() * 52;
};
const getCompanyWeeklyMeetingCost = () => {
return getWeeklyMeetingCostPerPerson() * inputs().employees;
};
const getCompanyAnnualMeetingCost = () => {
return getCompanyWeeklyMeetingCost() * 52;
};
const getUnnecessaryMeetingCost = () => {
return Math.round(getCompanyAnnualMeetingCost() * (inputs().unnecessaryPercent / 100));
};
const getOverloadedAttendeeCost = () => {
// Extra attendees beyond necessary
const extraAttendees = inputs().attendeesOverloaded;
const meetingsPerWeek = inputs().meetingsPerWeek;
const avgLength = inputs().avgMeetingLength;
const hourlyRate = getHourlyRate();
const weeklyCost = (meetingsPerWeek * avgLength / 60) * extraAttendees * hourlyRate;
return Math.round(weeklyCost * 52 * inputs().employees / 10); // Estimate for org
};
const getTotalWastedCost = () => {
return getUnnecessaryMeetingCost() + getOverloadedAttendeeCost();
};
const getProductiveHoursLost = () => {
const wastedHoursPerPerson = (getWeeklyMeetingHours() * (inputs().unnecessaryPercent / 100)) * 52;
return Math.round(wastedHoursPerPerson * inputs().employees);
};
const getMeetingHealthScore = () => {
let score = 100;
// Penalize for excessive meetings
if (inputs().meetingsPerWeek > 15) score -= 25;
else if (inputs().meetingsPerWeek > 10) score -= 15;
else if (inputs().meetingsPerWeek > 7) score -= 5;
// Penalize for long meetings
if (inputs().avgMeetingLength > 60) score -= 20;
else if (inputs().avgMeetingLength > 45) score -= 10;
// Penalize for high unnecessary percent
if (inputs().unnecessaryPercent > 40) score -= 25;
else if (inputs().unnecessaryPercent > 25) score -= 15;
else if (inputs().unnecessaryPercent > 15) score -= 5;
// Penalize for overloaded attendees
if (inputs().attendeesOverloaded > 4) score -= 15;
else if (inputs().attendeesOverloaded > 2) score -= 10;
return Math.max(0, score);
};
const getHealthLabel = () => {
const score = getMeetingHealthScore();
if (score >= 80) return 'Healthy Meeting Culture';
if (score >= 60) return 'Room for Improvement';
if (score >= 40) return 'Meeting Overload';
return 'Critical - Major Intervention Needed';
};
// ========== COMPLETION SCREEN ==========
form.configureCompletionScreen({
type: 'text',
title: '⏱️ Your Meeting Cost Report Is Ready!',
message: () => `Your organization spends an estimated $${getTotalWastedCost().toLocaleString()} per year on unnecessary meetings. Check your email for the detailed breakdown and optimization recommendations.`
});
// ========== PAGES ==========
const pages = form.addPages('quiz-pages', { heightMode: 'current-page' });
// ========== PAGE 1: Company Info ==========
const page1 = pages.addPage('company-info', { mobileBreakpoint: 500 });
page1.addRow(row => {
row.addTextPanel('header1', {
label: 'Step 1 of 4: Company Information',
computedValue: () => 'Tell us about your organization',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page1.addSpacer({ height: '24px' });
page1.addRow(row => {
row.addSlider('employees', {
label: 'Number of employees',
min: 10,
max: 500,
step: 10,
defaultValue: 50,
showValue: true,
onValueChange: (v) => inputs.update(s => ({ ...s, employees: v || 50 }))
});
});
page1.addRow(row => {
row.addSlider('avgSalary', {
label: 'Average annual salary',
min: 40000,
max: 200000,
step: 5000,
unit: '$',
defaultValue: 75000,
showValue: true,
onValueChange: (v) => inputs.update(s => ({ ...s, avgSalary: v || 75000 }))
});
});
page1.addRow(row => {
row.addTextPanel('hourlyRate', {
label: 'Calculated hourly rate',
computedValue: () => `💰 Average hourly cost: $${getHourlyRate()}/hour`,
customStyles: { background: '#f0f9ff', padding: '12px', borderRadius: '8px' }
});
});
// ========== PAGE 2: Meeting Habits ==========
const page2 = pages.addPage('meeting-habits', { mobileBreakpoint: 500 });
page2.addRow(row => {
row.addTextPanel('header2', {
label: 'Step 2 of 4: Meeting Habits',
computedValue: () => 'How does your team meet?',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page2.addSpacer({ height: '24px' });
page2.addRow(row => {
row.addSlider('meetingsPerWeek', {
label: 'Average meetings per person per week',
min: 3,
max: 30,
step: 1,
defaultValue: 10,
showValue: true,
onValueChange: (v) => inputs.update(s => ({ ...s, meetingsPerWeek: v || 10 }))
});
});
page2.addRow(row => {
row.addSlider('avgMeetingLength', {
label: 'Average meeting length',
min: 15,
max: 90,
step: 5,
unit: 'min',
defaultValue: 45,
showValue: true,
onValueChange: (v) => inputs.update(s => ({ ...s, avgMeetingLength: v || 45 }))
});
});
page2.addRow(row => {
row.addTextPanel('weeklyHours', {
label: 'Weekly meeting time',
computedValue: () => `⏱️ That's ${getWeeklyMeetingHours()} hours/week in meetings per person`,
customStyles: { background: '#fef3c7', padding: '12px', borderRadius: '8px' }
});
});
// ========== PAGE 3: Meeting Quality ==========
const page3 = pages.addPage('meeting-quality', { mobileBreakpoint: 500 });
page3.addRow(row => {
row.addTextPanel('header3', {
label: 'Step 3 of 4: Meeting Quality',
computedValue: () => 'Be honest about meeting effectiveness',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page3.addSpacer({ height: '24px' });
page3.addRow(row => {
row.addSlider('unnecessaryPercent', {
label: 'What percent of meetings could be emails or async?',
min: 5,
max: 70,
step: 5,
unit: '%',
defaultValue: 30,
showValue: true,
tooltip: 'Most organizations estimate 25-40%',
onValueChange: (v) => inputs.update(s => ({ ...s, unnecessaryPercent: v || 30 }))
});
});
page3.addRow(row => {
row.addSlider('attendeesOverloaded', {
label: 'How many extra people are usually invited "just in case"?',
min: 0,
max: 8,
step: 1,
defaultValue: 3,
showValue: true,
tooltip: 'People who attend but don\'t need to be there',
onValueChange: (v) => inputs.update(s => ({ ...s, attendeesOverloaded: v || 3 }))
});
});
page3.addRow(row => {
row.addSuggestionChips('meetingProblems', {
label: 'Common meeting problems you experience:',
suggestions: [
{ id: 'noagenda', name: '📋 No agenda' },
{ id: 'overtime', name: '⏰ Runs overtime' },
{ id: 'tangents', name: '🔀 Goes off-topic' },
{ id: 'nodecision', name: '❓ No decisions made' },
{ id: 'toofew', name: '😴 Could be shorter' },
{ id: 'recurring', name: '🔄 Unnecessary recurring' }
]
});
});
// ========== PAGE 4: Results ==========
const page4 = pages.addPage('results', { mobileBreakpoint: 500 });
page4.addRow(row => {
row.addTextPanel('header4', {
label: 'Step 4 of 4: Your Meeting Cost Analysis',
computedValue: () => 'Here\'s what meetings are costing you',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page4.addSpacer({ height: '24px' });
page4.addRow(row => {
row.addTextPanel('mainResult', {
label: 'Annual Wasted Meeting Cost',
computedValue: () => `$${getTotalWastedCost().toLocaleString()}`,
customStyles: () => ({
fontSize: '48px',
fontWeight: 'bold',
textAlign: 'center',
padding: '20px',
borderRadius: '12px',
color: getTotalWastedCost() > 500000 ? '#dc2626' : getTotalWastedCost() > 200000 ? '#ca8a04' : '#059669',
background: getTotalWastedCost() > 500000 ? '#fef2f2' : getTotalWastedCost() > 200000 ? '#fefce8' : '#ecfdf5'
})
});
});
page4.addRow(row => {
row.addTextPanel('healthScore', {
label: 'Meeting Health Score',
computedValue: () => `📊 ${getMeetingHealthScore()}% - ${getHealthLabel()}`,
customStyles: { textAlign: 'center', fontSize: '18px', padding: '10px' }
});
});
page4.addRow(row => {
row.addPriceDisplay('totalMeetingCost', {
label: 'Total Annual Meeting Cost',
computedValue: () => getCompanyAnnualMeetingCost(),
currency: '$',
decimals: 0
});
row.addPriceDisplay('unnecessaryCost', {
label: 'Unnecessary Meeting Cost',
computedValue: () => getUnnecessaryMeetingCost(),
currency: '$',
decimals: 0,
variant: 'highlight'
});
});
page4.addRow(row => {
row.addTextPanel('hoursLost', {
label: '⏱️ Productive Hours Lost',
computedValue: () => `${getProductiveHoursLost().toLocaleString()} hours/year across your organization`,
customStyles: { padding: '12px', background: '#fef2f2', borderRadius: '8px' }
});
});
const breakdownSection = page4.addSubform('breakdown', {
title: '📊 Detailed Breakdown (click to expand)',
isCollapsible: true,
customStyles: { background: '#f9fafb', borderRadius: '8px', marginTop: '20px' }
});
breakdownSection.addRow(row => {
row.addTextPanel('perPersonCost', {
label: 'Per-Person Metrics',
computedValue: () => `• Weekly meeting time: ${getWeeklyMeetingHours()} hours
• Weekly meeting cost: $${getWeeklyMeetingCostPerPerson().toLocaleString()}
• Annual meeting cost: $${getAnnualMeetingCostPerPerson().toLocaleString()}`
});
});
page4.addRow(row => {
row.addTextPanel('savingsOpportunity', {
label: '💡 Savings Opportunity',
computedValue: () => `By reducing unnecessary meetings by 50%, you could save $${Math.round(getTotalWastedCost() / 2).toLocaleString()}/year`,
customStyles: { padding: '15px', background: '#ecfdf5', borderRadius: '8px', marginTop: '15px', color: '#059669' }
});
});
// ========== PAGE 5: Lead Capture ==========
const page5 = pages.addPage('lead-capture', { mobileBreakpoint: 500 });
page5.addRow(row => {
row.addTextPanel('header5', {
label: 'Get Your Meeting Optimization Report',
computedValue: () => 'Receive actionable strategies to reduce meeting waste',
customStyles: { fontSize: '0.9rem', color: '#6b7280', marginBottom: '1rem' }
});
});
page5.addSpacer({ height: '24px' });
page5.addRow(row => {
row.addTextbox('name', { label: 'Your Name', isRequired: true, placeholder: 'Jane Smith' }, '1fr');
row.addEmail('email', { label: 'Work Email', isRequired: true, placeholder: 'jane@company.com' }, '1fr');
});
page5.addRow(row => {
row.addTextbox('company', { label: 'Company Name', placeholder: 'Acme Inc.' }, '1fr');
row.addDropdown('role', {
label: 'Your Role',
options: [
{ id: 'exec', name: 'Executive / C-Level' },
{ id: 'manager', name: 'Manager / Team Lead' },
{ id: 'hr', name: 'HR / People Ops' },
{ id: 'ops', name: 'Operations' },
{ id: 'ic', name: 'Individual Contributor' }
]
}, '1fr');
});
page5.addRow(row => {
row.addCheckboxList('consent', {
options: [
{ id: 'report', name: '📄 Send me the meeting cost report', isRequired: true },
{ id: 'tips', name: '💡 Include meeting optimization strategies' },
{ id: 'tools', name: '🛠️ Recommend tools to reduce meetings' }
],
defaultValue: ['report'],
orientation: 'vertical'
});
});
// ========== SUBMIT BUTTON ==========
form.configureSubmitButton({
label: () => `⏱️ Get My Report (Wasted: $${getTotalWastedCost().toLocaleString()}/yr)`
});
// ========== PDF REPORT ==========
form.configurePdf('meeting-cost-report', pdf => {
pdf.configure({
filename: 'meeting-cost-analysis.pdf',
pageSize: 'A4',
allowUserDownload: true,
downloadButtonLabel: '⏱️ Download Meeting Report',
header: {
title: 'Meeting Cost Analysis',
subtitle: 'Your Organization\'s Meeting ROI'
},
footer: {
text: 'Generated by FormTs',
showPageNumbers: true
}
});
pdf.addSection('Executive Summary', section => {
section.addRow(row => {
row.addField('Annual Wasted Cost', `$${getTotalWastedCost().toLocaleString()}`);
row.addField('Meeting Health Score', `${getMeetingHealthScore()}%`);
});
section.addRow(row => {
row.addField('Hours Lost/Year', `${getProductiveHoursLost().toLocaleString()}`);
row.addField('Status', getHealthLabel());
});
});
pdf.addSection('Cost Breakdown', section => {
section.addTable(
['Metric', 'Value'],
[
['Total Annual Meeting Cost', `$${getCompanyAnnualMeetingCost().toLocaleString()}`],
['Unnecessary Meeting Cost', `$${getUnnecessaryMeetingCost().toLocaleString()}`],
['Per-Person Annual Cost', `$${getAnnualMeetingCostPerPerson().toLocaleString()}`],
['Weekly Hours in Meetings', `${getWeeklyMeetingHours()} hours`]
]
);
});
pdf.addPageBreak();
pdf.addSection('Optimization Recommendations', section => {
section.addText('1. Implement "No Meeting Wednesdays" for deep work');
section.addText('2. Default to 25/50 minute meetings instead of 30/60');
section.addText('3. Require agendas for all meetings over 2 people');
section.addText('4. Use async video (Loom) for status updates');
section.addText('5. Audit recurring meetings quarterly');
section.addText('6. Limit attendees to essential participants only');
});
pdf.addSection('Potential Savings', section => {
section.addText(`50% reduction: $${Math.round(getTotalWastedCost() / 2).toLocaleString()}/year`);
section.addText(`25% reduction: $${Math.round(getTotalWastedCost() / 4).toLocaleString()}/year`);
});
});
form.configureSubmitBehavior({ sendToServer: true });
}