export function contractDraftingCalculator(form: FormTs) {
// Contract types and base rates
const contractTypes: Record<string, { baseHours: number, complexity: number }> = {
'service-agreement': { baseHours: 4, complexity: 1.0 },
'sales-contract': { baseHours: 3, complexity: 0.9 },
'partnership-agreement': { baseHours: 8, complexity: 1.5 },
'joint-venture': { baseHours: 10, complexity: 1.8 },
'licensing-agreement': { baseHours: 6, complexity: 1.3 },
'franchise-agreement': { baseHours: 12, complexity: 2.0 },
'distribution-agreement': { baseHours: 6, complexity: 1.2 },
'consulting-agreement': { baseHours: 3, complexity: 0.8 },
'independent-contractor': { baseHours: 2, complexity: 0.7 },
'saas-agreement': { baseHours: 8, complexity: 1.5 },
'master-services': { baseHours: 10, complexity: 1.6 },
'custom': { baseHours: 6, complexity: 1.0 }
};
// Hourly rates by attorney level
const hourlyRates: Record<string, number> = {
'paralegal': 95,
'associate': 275,
'senior-associate': 375,
'partner': 525
};
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Contract Drafting Cost Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Contract Type Section
const typeSection = form.addSubform('contractType', { title: '๐ Contract Type' });
typeSection.addRow(row => {
row.addDropdown('type', {
label: 'Type of Contract',
options: [
{ id: 'service-agreement', name: 'Service Agreement' },
{ id: 'sales-contract', name: 'Sales Contract' },
{ id: 'partnership-agreement', name: 'Partnership Agreement' },
{ id: 'joint-venture', name: 'Joint Venture Agreement' },
{ id: 'licensing-agreement', name: 'Licensing Agreement' },
{ id: 'franchise-agreement', name: 'Franchise Agreement' },
{ id: 'distribution-agreement', name: 'Distribution Agreement' },
{ id: 'consulting-agreement', name: 'Consulting Agreement' },
{ id: 'independent-contractor', name: 'Independent Contractor Agreement' },
{ id: 'saas-agreement', name: 'SaaS / Software Agreement' },
{ id: 'master-services', name: 'Master Services Agreement (MSA)' },
{ id: 'custom', name: 'Custom Contract' }
],
defaultValue: 'service-agreement',
isRequired: true
}, '1fr');
row.addDropdown('industry', {
label: 'Industry',
options: [
{ id: 'general', name: 'General Business' },
{ id: 'technology', name: 'Technology / Software' },
{ id: 'healthcare', name: 'Healthcare / Medical' },
{ id: 'financial', name: 'Financial Services' },
{ id: 'real-estate', name: 'Real Estate' },
{ id: 'manufacturing', name: 'Manufacturing' },
{ id: 'retail', name: 'Retail / E-commerce' },
{ id: 'construction', name: 'Construction' }
],
defaultValue: 'general',
isRequired: true
}, '1fr');
});
// Complexity Section
const complexitySection = form.addSubform('complexity', { title: 'โ๏ธ Complexity & Scope' });
complexitySection.addRow(row => {
row.addDropdown('partyCount', {
label: 'Number of Parties',
options: [
{ id: '2', name: '2 Parties (Standard)' },
{ id: '3', name: '3 Parties (+25%)' },
{ id: '4', name: '4+ Parties (+50%)' }
],
defaultValue: '2',
isRequired: true
}, '1fr');
row.addDropdown('contractLength', {
label: 'Expected Contract Length',
options: [
{ id: 'short', name: 'Short (5-10 pages)' },
{ id: 'medium', name: 'Medium (10-25 pages)' },
{ id: 'long', name: 'Long (25-50 pages)' },
{ id: 'comprehensive', name: 'Comprehensive (50+ pages)' }
],
defaultValue: 'medium',
isRequired: true
}, '1fr');
});
complexitySection.addRow(row => {
row.addDropdown('jurisdictions', {
label: 'Jurisdictions Covered',
options: [
{ id: 'single-state', name: 'Single State' },
{ id: 'multi-state', name: 'Multi-State (+30%)' },
{ id: 'international', name: 'International (+75%)' }
],
defaultValue: 'single-state',
isRequired: true
}, '1fr');
row.addDropdown('regulatoryCompliance', {
label: 'Regulatory Requirements',
options: [
{ id: 'none', name: 'Minimal / Standard' },
{ id: 'moderate', name: 'Moderate (+20%)' },
{ id: 'heavy', name: 'Heavy Regulatory (+50%)' }
],
defaultValue: 'none',
isRequired: true
}, '1fr');
});
// Attorney & Timeline Section
const attorneySection = form.addSubform('attorney', { title: '๐ Attorney & Timeline' });
attorneySection.addRow(row => {
row.addDropdown('level', {
label: 'Attorney Level',
options: [
{ id: 'paralegal', name: 'Paralegal / Legal Assistant ($95/hr)' },
{ id: 'associate', name: 'Associate Attorney ($275/hr)' },
{ id: 'senior-associate', name: 'Senior Associate ($375/hr)' },
{ id: 'partner', name: 'Partner ($525/hr)' }
],
defaultValue: 'associate',
isRequired: true
}, '1fr');
row.addDropdown('urgency', {
label: 'Timeline',
options: [
{ id: 'standard', name: 'Standard (2-3 weeks)' },
{ id: 'expedited', name: 'Expedited (1 week) (+35%)' },
{ id: 'rush', name: 'Rush (3-5 days) (+75%)' },
{ id: 'emergency', name: 'Emergency (24-48 hrs) (+100%)' }
],
defaultValue: 'standard',
isRequired: true
}, '1fr');
});
// Additional Services Section
const addonsSection = form.addSubform('addons', { title: 'โจ Additional Services' });
addonsSection.addRow(row => {
row.addCheckbox('negotiationSupport', {
label: 'Negotiation Support (+$500-1500)',
defaultValue: false
}, '1fr');
row.addCheckbox('revisionRounds', {
label: 'Extended Revisions (3 rounds) (+$350)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('executionSupport', {
label: 'Execution & Closing Support (+$250)',
defaultValue: false
}, '1fr');
row.addCheckbox('templateCreation', {
label: 'Template for Future Use (+$400)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('complianceReview', {
label: 'Compliance Review (+$500)',
defaultValue: false
}, '1fr');
row.addCheckbox('riskAssessment', {
label: 'Risk Assessment Report (+$600)',
defaultValue: false
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Summary Section
const summarySection = form.addSubform('summary', { title: '๐ฐ Cost Estimate', isCollapsible: false });
summarySection.addRow(row => {
row.addPriceDisplay('baseFee', {
label: 'Base Drafting Fee',
computedValue: () => {
const type = typeSection.dropdown('type')?.value() || 'service-agreement';
const level = attorneySection.dropdown('level')?.value() || 'associate';
const length = complexitySection.dropdown('contractLength')?.value() || 'medium';
const contractInfo = contractTypes[type];
const rate = hourlyRates[level] ?? 0;
let hours = (contractInfo?.baseHours ?? 0) * (contractInfo?.complexity ?? 0);
// Adjust for length
const lengthMultipliers: Record<string, number> = {
'short': 0.7,
'medium': 1.0,
'long': 1.6,
'comprehensive': 2.5
};
hours *= lengthMultipliers[length] || 1.0;
return Math.round(hours * rate);
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('complexityFees', {
label: 'Complexity Adjustments',
computedValue: () => {
const type = typeSection.dropdown('type')?.value() || 'service-agreement';
const level = attorneySection.dropdown('level')?.value() || 'associate';
const length = complexitySection.dropdown('contractLength')?.value() || 'medium';
const parties = complexitySection.dropdown('partyCount')?.value() || '2';
const jurisdictions = complexitySection.dropdown('jurisdictions')?.value() || 'single-state';
const regulatory = complexitySection.dropdown('regulatoryCompliance')?.value() || 'none';
const contractInfo = contractTypes[type];
const rate = hourlyRates[level] ?? 0;
let hours = (contractInfo?.baseHours ?? 0) * (contractInfo?.complexity ?? 0);
const lengthMultipliers: Record<string, number> = {
'short': 0.7, 'medium': 1.0, 'long': 1.6, 'comprehensive': 2.5
};
hours *= lengthMultipliers[length] || 1.0;
const baseFee = hours * rate;
let multiplier = 0;
// Party multiplier
if (parties === '3') multiplier += 0.25;
if (parties === '4') multiplier += 0.50;
// Jurisdiction multiplier
if (jurisdictions === 'multi-state') multiplier += 0.30;
if (jurisdictions === 'international') multiplier += 0.75;
// Regulatory multiplier
if (regulatory === 'moderate') multiplier += 0.20;
if (regulatory === 'heavy') multiplier += 0.50;
return Math.round(baseFee * multiplier);
},
variant: 'default',
prefix: '+'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('urgencyFee', {
label: 'Urgency Premium',
computedValue: () => {
const type = typeSection.dropdown('type')?.value() || 'service-agreement';
const level = attorneySection.dropdown('level')?.value() || 'associate';
const length = complexitySection.dropdown('contractLength')?.value() || 'medium';
const urgency = attorneySection.dropdown('urgency')?.value() || 'standard';
const contractInfo = contractTypes[type];
const rate = hourlyRates[level] ?? 0;
let hours = (contractInfo?.baseHours ?? 0) * (contractInfo?.complexity ?? 0);
const lengthMultipliers: Record<string, number> = {
'short': 0.7, 'medium': 1.0, 'long': 1.6, 'comprehensive': 2.5
};
hours *= lengthMultipliers[length] || 1.0;
const baseFee = hours * rate;
const urgencyMultipliers: Record<string, number> = {
'standard': 0, 'expedited': 0.35, 'rush': 0.75, 'emergency': 1.0
};
return Math.round(baseFee * (urgencyMultipliers[urgency] || 0));
},
variant: 'default',
prefix: '+'
}, '1fr');
row.addPriceDisplay('addonsFee', {
label: 'Additional Services',
computedValue: () => {
let total = 0;
const type = typeSection.dropdown('type')?.value() || 'service-agreement';
const contractInfo = contractTypes[type];
if (addonsSection.checkbox('negotiationSupport')?.value()) {
total += (contractInfo?.complexity ?? 0) >= 1.5 ? 1500 : 750;
}
if (addonsSection.checkbox('revisionRounds')?.value()) total += 350;
if (addonsSection.checkbox('executionSupport')?.value()) total += 250;
if (addonsSection.checkbox('templateCreation')?.value()) total += 400;
if (addonsSection.checkbox('complianceReview')?.value()) total += 500;
if (addonsSection.checkbox('riskAssessment')?.value()) total += 600;
return total;
},
variant: 'default',
prefix: '+'
}, '1fr');
});
const finalSection = form.addSubform('final', {
title: '๐งพ Total Estimate',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('totalFee', {
label: 'Estimated Total',
computedValue: () => {
const type = typeSection.dropdown('type')?.value() || 'service-agreement';
const level = attorneySection.dropdown('level')?.value() || 'associate';
const length = complexitySection.dropdown('contractLength')?.value() || 'medium';
const parties = complexitySection.dropdown('partyCount')?.value() || '2';
const jurisdictions = complexitySection.dropdown('jurisdictions')?.value() || 'single-state';
const regulatory = complexitySection.dropdown('regulatoryCompliance')?.value() || 'none';
const urgency = attorneySection.dropdown('urgency')?.value() || 'standard';
const contractInfo = contractTypes[type];
const rate = hourlyRates[level] ?? 0;
let hours = (contractInfo?.baseHours ?? 0) * (contractInfo?.complexity ?? 0);
const lengthMultipliers: Record<string, number> = {
'short': 0.7, 'medium': 1.0, 'long': 1.6, 'comprehensive': 2.5
};
hours *= lengthMultipliers[length] || 1.0;
let baseFee = hours * rate;
// Complexity adjustments
let complexityMult = 1.0;
if (parties === '3') complexityMult += 0.25;
if (parties === '4') complexityMult += 0.50;
if (jurisdictions === 'multi-state') complexityMult += 0.30;
if (jurisdictions === 'international') complexityMult += 0.75;
if (regulatory === 'moderate') complexityMult += 0.20;
if (regulatory === 'heavy') complexityMult += 0.50;
baseFee *= complexityMult;
// Urgency
const urgencyMultipliers: Record<string, number> = {
'standard': 1.0, 'expedited': 1.35, 'rush': 1.75, 'emergency': 2.0
};
baseFee *= urgencyMultipliers[urgency] || 1.0;
// Add-ons
if (addonsSection.checkbox('negotiationSupport')?.value()) {
baseFee += (contractInfo?.complexity ?? 0) >= 1.5 ? 1500 : 750;
}
if (addonsSection.checkbox('revisionRounds')?.value()) baseFee += 350;
if (addonsSection.checkbox('executionSupport')?.value()) baseFee += 250;
if (addonsSection.checkbox('templateCreation')?.value()) baseFee += 400;
if (addonsSection.checkbox('complianceReview')?.value()) baseFee += 500;
if (addonsSection.checkbox('riskAssessment')?.value()) baseFee += 600;
return Math.round(baseFee);
},
variant: 'large'
});
});
finalSection.addRow(row => {
row.addTextPanel('estimate', {
computedValue: () => {
const type = typeSection.dropdown('type')?.value() || 'service-agreement';
const level = attorneySection.dropdown('level')?.value() || 'associate';
const contractInfo = contractTypes[type];
const rate = hourlyRates[level] ?? 0;
const hours = Math.round((contractInfo?.baseHours ?? 0) * (contractInfo?.complexity ?? 0));
return `Estimated time: ${hours}-${hours + 4} hours at $${rate}/hr`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#64748b', 'text-align': 'center' }
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'This is an estimate only. Final fees depend on actual scope, complexity, and time required. A formal quote will be provided after initial consultation.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Request Quote'
});
}