export function consultingFeeCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Consulting Fee Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Consulting Type Section
const typeSection = form.addSubform('type', { title: '💼 Consulting Type' });
typeSection.addRow(row => {
row.addDropdown('specialty', {
label: 'Consulting Specialty',
options: [
{ id: 'management', name: 'Management Consulting' },
{ id: 'strategy', name: 'Strategy Consulting' },
{ id: 'operations', name: 'Operations Consulting' },
{ id: 'hr', name: 'HR / Organizational' },
{ id: 'financial', name: 'Financial Advisory' },
{ id: 'marketing', name: 'Marketing / Brand Consulting' },
{ id: 'it', name: 'IT / Technology Consulting' },
{ id: 'legal', name: 'Legal Consulting' },
{ id: 'healthcare', name: 'Healthcare Consulting' },
{ id: 'sustainability', name: 'Sustainability / ESG' }
],
defaultValue: 'management',
isRequired: true
}, '1fr');
row.addDropdown('industry', {
label: 'Client Industry',
options: [
{ id: 'general', name: 'General / Multiple' },
{ id: 'technology', name: 'Technology / SaaS' },
{ id: 'finance', name: 'Financial Services' },
{ id: 'healthcare', name: 'Healthcare' },
{ id: 'manufacturing', name: 'Manufacturing' },
{ id: 'retail', name: 'Retail / E-commerce' },
{ id: 'energy', name: 'Energy / Utilities' },
{ id: 'government', name: 'Government / Public Sector' },
{ id: 'nonprofit', name: 'Non-profit' }
],
defaultValue: 'general',
tooltip: 'Industry specialization affects rates'
}, '1fr');
});
// Expertise Section
const expertiseSection = form.addSubform('expertise', { title: '⭐ Expertise Level' });
expertiseSection.addRow(row => {
row.addRadioButton('level', {
label: 'Experience Level',
options: [
{ id: 'junior', name: 'Junior Consultant (1-3 years)' },
{ id: 'mid', name: 'Consultant (4-7 years)' },
{ id: 'senior', name: 'Senior Consultant (8-15 years)' },
{ id: 'principal', name: 'Principal / Partner (15+ years)' }
],
defaultValue: 'senior',
isRequired: true
});
});
expertiseSection.addRow(row => {
row.addDropdown('firmType', {
label: 'Consultant Type',
options: [
{ id: 'independent', name: 'Independent Consultant' },
{ id: 'boutique', name: 'Boutique Firm' },
{ id: 'mid-size', name: 'Mid-size Firm' },
{ id: 'big4', name: 'Big 4 / Top Tier Firm' }
],
defaultValue: 'independent',
tooltip: 'Firm type affects market rates'
});
});
// Engagement Section
const engagementSection = form.addSubform('engagement', { title: '📋 Engagement Details' });
engagementSection.addRow(row => {
row.addDropdown('engagementType', {
label: 'Engagement Type',
options: [
{ id: 'hourly', name: 'Hourly Advisory' },
{ id: 'daily', name: 'Daily Rate' },
{ id: 'project', name: 'Fixed Project Fee' },
{ id: 'retainer', name: 'Monthly Retainer' }
],
defaultValue: 'project',
isRequired: true
}, '1fr');
row.addDropdown('projectSize', {
label: 'Project Scope',
options: [
{ id: 'small', name: 'Small (1-2 weeks)' },
{ id: 'medium', name: 'Medium (1-2 months)' },
{ id: 'large', name: 'Large (3-6 months)' },
{ id: 'enterprise', name: 'Enterprise (6+ months)' }
],
defaultValue: 'medium',
isVisible: () => engagementSection.dropdown('engagementType')?.value() === 'project'
}, '1fr');
});
engagementSection.addRow(row => {
row.addInteger('hours', {
label: 'Estimated Hours',
min: 1,
max: 2000,
defaultValue: 40,
isVisible: () => ['hourly', 'project'].includes(engagementSection.dropdown('engagementType')?.value() || '')
}, '1fr');
row.addInteger('days', {
label: 'Number of Days',
min: 1,
max: 365,
defaultValue: 5,
isVisible: () => engagementSection.dropdown('engagementType')?.value() === 'daily'
}, '1fr');
row.addInteger('months', {
label: 'Retainer Duration (Months)',
min: 1,
max: 24,
defaultValue: 6,
isVisible: () => engagementSection.dropdown('engagementType')?.value() === 'retainer'
}, '1fr');
});
engagementSection.addRow(row => {
row.addInteger('hoursPerMonth', {
label: 'Hours per Month',
min: 5,
max: 160,
defaultValue: 20,
isVisible: () => engagementSection.dropdown('engagementType')?.value() === 'retainer',
tooltip: 'Guaranteed hours included in retainer'
});
});
// Deliverables Section
const deliverablesSection = form.addSubform('deliverables', { title: '📊 Deliverables' });
deliverablesSection.addRow(row => {
row.addCheckbox('strategyDoc', {
label: 'Strategy Document',
defaultValue: true,
tooltip: 'Written strategic recommendations'
}, '1fr');
row.addCheckbox('presentation', {
label: 'Executive Presentation',
defaultValue: true,
tooltip: 'Board/leadership presentation'
}, '1fr');
});
deliverablesSection.addRow(row => {
row.addCheckbox('implementation', {
label: 'Implementation Roadmap',
defaultValue: false,
tooltip: 'Detailed action plan with timelines'
}, '1fr');
row.addCheckbox('workshops', {
label: 'Workshop Facilitation',
defaultValue: false,
tooltip: 'Team workshops or training sessions'
}, '1fr');
});
deliverablesSection.addRow(row => {
row.addCheckbox('analysis', {
label: 'Data Analysis & Insights',
defaultValue: false,
tooltip: 'Quantitative analysis and reporting'
}, '1fr');
row.addCheckbox('ongoing', {
label: 'Ongoing Support',
defaultValue: false,
tooltip: 'Post-project advisory calls'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Pricing Breakdown
const breakdownSection = form.addSubform('breakdown', { title: '📊 Fee Breakdown', isCollapsible: true });
breakdownSection.addRow(row => {
row.addPriceDisplay('baseRate', {
label: 'Base Hourly Rate',
computedValue: () => {
const level = expertiseSection.radioButton('level')?.value() || 'senior';
const firmType = expertiseSection.dropdown('firmType')?.value() || 'independent';
const specialty = typeSection.dropdown('specialty')?.value() || 'management';
// Base rates by level
const levelRates: Record<string, number> = {
'junior': 100, 'mid': 175, 'senior': 275, 'principal': 450
};
// Firm multipliers
const firmMultipliers: Record<string, number> = {
'independent': 1, 'boutique': 1.15, 'mid-size': 1.3, 'big4': 1.6
};
// Specialty multipliers
const specialtyMultipliers: Record<string, number> = {
'management': 1, 'strategy': 1.2, 'operations': 0.95, 'hr': 0.9,
'financial': 1.15, 'marketing': 0.95, 'it': 1.1, 'legal': 1.25,
'healthcare': 1.15, 'sustainability': 1.05
};
const rate = (levelRates[level] || 275) * (firmMultipliers[firmType] || 1) * (specialtyMultipliers[specialty] || 1);
return Math.round(rate * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('industryAdjustment', {
label: 'Industry Premium',
computedValue: () => {
const level = expertiseSection.radioButton('level')?.value() || 'senior';
const firmType = expertiseSection.dropdown('firmType')?.value() || 'independent';
const industry = typeSection.dropdown('industry')?.value() || 'general';
const levelRates: Record<string, number> = { 'junior': 100, 'mid': 175, 'senior': 275, 'principal': 450 };
const firmMultipliers: Record<string, number> = { 'independent': 1, 'boutique': 1.15, 'mid-size': 1.3, 'big4': 1.6 };
const baseRate = (levelRates[level] || 275) * (firmMultipliers[firmType] || 1);
const industryPremiums: Record<string, number> = {
'general': 0, 'technology': 0.15, 'finance': 0.2, 'healthcare': 0.15,
'manufacturing': 0.05, 'retail': 0, 'energy': 0.1, 'government': -0.1, 'nonprofit': -0.2
};
return Math.round(baseRate * (industryPremiums[industry] || 0) * 100) / 100;
},
variant: 'default'
}, '1fr');
});
breakdownSection.addRow(row => {
row.addPriceDisplay('deliverablesFee', {
label: 'Deliverables Premium',
computedValue: () => {
let premium = 0;
if (deliverablesSection.checkbox('strategyDoc')?.value()) premium += 500;
if (deliverablesSection.checkbox('presentation')?.value()) premium += 750;
if (deliverablesSection.checkbox('implementation')?.value()) premium += 1500;
if (deliverablesSection.checkbox('workshops')?.value()) premium += 2000;
if (deliverablesSection.checkbox('analysis')?.value()) premium += 1000;
if (deliverablesSection.checkbox('ongoing')?.value()) premium += 500;
return premium;
},
variant: 'default'
});
});
// Quote Section
const quoteSection = form.addSubform('quote', { title: '💰 Your Quote', isCollapsible: false });
quoteSection.addRow(row => {
row.addPriceDisplay('effectiveRate', {
label: 'Effective Rate',
computedValue: () => {
const engagementType = engagementSection.dropdown('engagementType')?.value() || 'project';
const level = expertiseSection.radioButton('level')?.value() || 'senior';
const firmType = expertiseSection.dropdown('firmType')?.value() || 'independent';
const specialty = typeSection.dropdown('specialty')?.value() || 'management';
const industry = typeSection.dropdown('industry')?.value() || 'general';
const levelRates: Record<string, number> = { 'junior': 100, 'mid': 175, 'senior': 275, 'principal': 450 };
const firmMultipliers: Record<string, number> = { 'independent': 1, 'boutique': 1.15, 'mid-size': 1.3, 'big4': 1.6 };
const specialtyMultipliers: Record<string, number> = {
'management': 1, 'strategy': 1.2, 'operations': 0.95, 'hr': 0.9,
'financial': 1.15, 'marketing': 0.95, 'it': 1.1, 'legal': 1.25,
'healthcare': 1.15, 'sustainability': 1.05
};
const industryMultipliers: Record<string, number> = {
'general': 1, 'technology': 1.15, 'finance': 1.2, 'healthcare': 1.15,
'manufacturing': 1.05, 'retail': 1, 'energy': 1.1, 'government': 0.9, 'nonprofit': 0.8
};
let rate = (levelRates[level] || 275) * (firmMultipliers[firmType] || 1) * (specialtyMultipliers[specialty] || 1) * (industryMultipliers[industry] || 1);
if (engagementType === 'daily') {
return Math.round(rate * 8 * 100) / 100;
} else if (engagementType === 'retainer') {
return Math.round(rate * 0.85 * 100) / 100; // Retainer discount
}
return Math.round(rate * 100) / 100;
},
variant: 'success'
}, '1fr');
row.addTextPanel('rateLabel', {
computedValue: () => {
const engagementType = engagementSection.dropdown('engagementType')?.value() || 'project';
const labels: Record<string, string> = {
'hourly': 'per hour', 'daily': 'per day', 'project': 'per hour', 'retainer': 'per hour (discounted)'
};
return labels[engagementType] || 'per hour';
},
customStyles: { 'font-size': '1rem', 'text-align': 'center', 'color': '#64748b', 'padding-top': '0.5rem' }
}, '1fr');
});
quoteSection.addRow(row => {
row.addPriceDisplay('totalFee', {
label: 'Total Project Fee',
computedValue: () => {
const engagementType = engagementSection.dropdown('engagementType')?.value() || 'project';
const level = expertiseSection.radioButton('level')?.value() || 'senior';
const firmType = expertiseSection.dropdown('firmType')?.value() || 'independent';
const specialty = typeSection.dropdown('specialty')?.value() || 'management';
const industry = typeSection.dropdown('industry')?.value() || 'general';
const hours = engagementSection.integer('hours')?.value() || 40;
const days = engagementSection.integer('days')?.value() || 5;
const months = engagementSection.integer('months')?.value() || 6;
const hoursPerMonth = engagementSection.integer('hoursPerMonth')?.value() || 20;
const levelRates: Record<string, number> = { 'junior': 100, 'mid': 175, 'senior': 275, 'principal': 450 };
const firmMultipliers: Record<string, number> = { 'independent': 1, 'boutique': 1.15, 'mid-size': 1.3, 'big4': 1.6 };
const specialtyMultipliers: Record<string, number> = {
'management': 1, 'strategy': 1.2, 'operations': 0.95, 'hr': 0.9,
'financial': 1.15, 'marketing': 0.95, 'it': 1.1, 'legal': 1.25,
'healthcare': 1.15, 'sustainability': 1.05
};
const industryMultipliers: Record<string, number> = {
'general': 1, 'technology': 1.15, 'finance': 1.2, 'healthcare': 1.15,
'manufacturing': 1.05, 'retail': 1, 'energy': 1.1, 'government': 0.9, 'nonprofit': 0.8
};
const rate = (levelRates[level] || 275) * (firmMultipliers[firmType] || 1) * (specialtyMultipliers[specialty] || 1) * (industryMultipliers[industry] || 1);
let total = 0;
if (engagementType === 'hourly') {
total = rate * hours;
} else if (engagementType === 'daily') {
total = rate * 8 * days;
} else if (engagementType === 'project') {
total = rate * hours;
} else if (engagementType === 'retainer') {
total = rate * 0.85 * hoursPerMonth * months;
}
// Add deliverables
if (deliverablesSection.checkbox('strategyDoc')?.value()) total += 500;
if (deliverablesSection.checkbox('presentation')?.value()) total += 750;
if (deliverablesSection.checkbox('implementation')?.value()) total += 1500;
if (deliverablesSection.checkbox('workshops')?.value()) total += 2000;
if (deliverablesSection.checkbox('analysis')?.value()) total += 1000;
if (deliverablesSection.checkbox('ongoing')?.value()) total += 500;
return Math.round(total * 100) / 100;
},
variant: 'large'
});
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '📋 Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addTextPanel('summaryText', {
computedValue: () => {
const specialty = typeSection.dropdown('specialty')?.value() || 'management';
const engagementType = engagementSection.dropdown('engagementType')?.value() || 'project';
const specialtyLabels: Record<string, string> = {
'management': 'Management', 'strategy': 'Strategy', 'operations': 'Operations',
'hr': 'HR', 'financial': 'Financial', 'marketing': 'Marketing',
'it': 'IT', 'legal': 'Legal', 'healthcare': 'Healthcare', 'sustainability': 'ESG'
};
const engagementLabels: Record<string, string> = {
'hourly': 'hourly advisory', 'daily': 'daily engagement', 'project': 'project', 'retainer': 'retainer'
};
return `${specialtyLabels[specialty] || 'Management'} consulting ${engagementLabels[engagementType] || 'project'}`;
},
customStyles: { 'font-size': '0.95rem', 'font-weight': '500', 'text-align': 'center', 'color': '#1e293b' }
});
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Fees are estimates based on market rates. Final pricing may vary based on specific requirements and scope.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Request Proposal'
});
}