export function termsOfServiceCalculator(form: FormTs) {
// Base prices by platform type
const platformPrices: Record<string, number> = {
'website': 400,
'blog': 300,
'ecommerce': 800,
'saas': 1200,
'mobile-app': 900,
'marketplace': 1500,
'community': 600,
'api-service': 1000
};
// Jurisdiction multipliers
const jurisdictionMultipliers: Record<string, number> = {
'us-single': 1.0,
'us-multi': 1.3,
'eu-uk': 1.4,
'international': 1.8,
'specific-country': 1.2
};
// Complexity multipliers
const complexityMultipliers: Record<string, number> = {
'basic': 0.8,
'standard': 1.0,
'comprehensive': 1.5,
'enterprise': 2.0
};
// Additional clause prices
const clausePrices: Record<string, number> = {
'arbitration': 200,
'class-action-waiver': 150,
'dmca': 250,
'user-content': 300,
'subscription-billing': 350,
'refund-policy': 200,
'age-restrictions': 150,
'api-usage': 400,
'data-licensing': 350,
'indemnification': 200
};
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Terms of Service Cost Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Platform Section
const platformSection = form.addSubform('platform', { title: '๐ Platform Details' });
platformSection.addRow(row => {
row.addDropdown('platformType', {
label: 'Platform Type',
options: [
{ id: 'website', name: 'Standard Website' },
{ id: 'blog', name: 'Blog / Content Site' },
{ id: 'ecommerce', name: 'E-commerce Store' },
{ id: 'saas', name: 'SaaS Application' },
{ id: 'mobile-app', name: 'Mobile Application' },
{ id: 'marketplace', name: 'Marketplace / Platform' },
{ id: 'community', name: 'Community / Forum' },
{ id: 'api-service', name: 'API / Developer Service' }
],
defaultValue: 'website',
isRequired: true
}, '1fr');
row.addDropdown('complexity', {
label: 'Document Complexity',
options: [
{ id: 'basic', name: 'Basic (Essential terms only)' },
{ id: 'standard', name: 'Standard (Recommended)' },
{ id: 'comprehensive', name: 'Comprehensive (Detailed coverage)' },
{ id: 'enterprise', name: 'Enterprise (Full legal protection)' }
],
defaultValue: 'standard',
isRequired: true
}, '1fr');
});
platformSection.addRow(row => {
row.addDropdown('jurisdiction', {
label: 'Jurisdiction Coverage',
options: [
{ id: 'us-single', name: 'US - Single State' },
{ id: 'us-multi', name: 'US - Multi-State' },
{ id: 'eu-uk', name: 'EU / UK' },
{ id: 'international', name: 'International (Multiple regions)' },
{ id: 'specific-country', name: 'Other Specific Country' }
],
defaultValue: 'us-single',
isRequired: true
}, '1fr');
row.addDropdown('userBase', {
label: 'Expected User Base',
options: [
{ id: 'small', name: 'Small (< 1,000 users)' },
{ id: 'medium', name: 'Medium (1,000 - 50,000 users)' },
{ id: 'large', name: 'Large (50,000 - 500,000 users)' },
{ id: 'enterprise', name: 'Enterprise (500,000+ users)' }
],
defaultValue: 'small',
isRequired: true
}, '1fr');
});
// Special Clauses Section
const clausesSection = form.addSubform('clauses', { title: '๐ Special Clauses' });
clausesSection.addRow(row => {
row.addCheckbox('arbitration', {
label: 'Arbitration Clause',
defaultValue: false
}, '1fr');
row.addCheckbox('classActionWaiver', {
label: 'Class Action Waiver',
defaultValue: false
}, '1fr');
});
clausesSection.addRow(row => {
row.addCheckbox('dmca', {
label: 'DMCA / Copyright Policy',
defaultValue: false
}, '1fr');
row.addCheckbox('userContent', {
label: 'User-Generated Content Terms',
defaultValue: false
}, '1fr');
});
clausesSection.addRow(row => {
row.addCheckbox('subscriptionBilling', {
label: 'Subscription & Billing Terms',
defaultValue: false,
isVisible: () => {
const platform = platformSection.dropdown('platformType')?.value();
return ['saas', 'ecommerce', 'marketplace'].includes(platform || '');
}
}, '1fr');
row.addCheckbox('refundPolicy', {
label: 'Detailed Refund Policy',
defaultValue: false,
isVisible: () => {
const platform = platformSection.dropdown('platformType')?.value();
return ['saas', 'ecommerce', 'marketplace'].includes(platform || '');
}
}, '1fr');
});
clausesSection.addRow(row => {
row.addCheckbox('ageRestrictions', {
label: 'Age Restrictions / COPPA',
defaultValue: false
}, '1fr');
row.addCheckbox('apiUsage', {
label: 'API Usage Terms',
defaultValue: false,
isVisible: () => {
const platform = platformSection.dropdown('platformType')?.value();
return ['saas', 'api-service', 'marketplace'].includes(platform || '');
}
}, '1fr');
});
clausesSection.addRow(row => {
row.addCheckbox('dataLicensing', {
label: 'Data Licensing Terms',
defaultValue: false
}, '1fr');
row.addCheckbox('indemnification', {
label: 'Enhanced Indemnification',
defaultValue: false
}, '1fr');
});
// Additional Services Section
const servicesSection = form.addSubform('services', { title: 'โจ Additional Services' });
servicesSection.addRow(row => {
row.addCheckbox('legalReview', {
label: 'Attorney Review & Consultation',
defaultValue: true
}, '1fr');
row.addCheckbox('customization', {
label: 'Business-Specific Customization',
defaultValue: false
}, '1fr');
});
servicesSection.addRow(row => {
row.addDropdown('revisions', {
label: 'Revision Rounds',
options: [
{ id: '1', name: '1 Round (Included)' },
{ id: '2', name: '2 Rounds (+$150)' },
{ id: '3', name: '3 Rounds (+$300)' },
{ id: 'unlimited', name: 'Unlimited Revisions (+$500)' }
],
defaultValue: '1'
}, '1fr');
row.addDropdown('turnaround', {
label: 'Turnaround Time',
options: [
{ id: 'standard', name: 'Standard (5-7 business days)' },
{ id: 'expedited', name: 'Expedited (3-4 days) (+25%)' },
{ id: 'rush', name: 'Rush (1-2 days) (+50%)' }
],
defaultValue: 'standard'
}, '1fr');
});
servicesSection.addRow(row => {
row.addCheckbox('annualUpdate', {
label: 'Annual Update Service (+$300/year)',
defaultValue: false
}, '1fr');
row.addCheckbox('clickwrapSetup', {
label: 'Click-wrap Implementation Guide (+$150)',
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('baseCost', {
label: 'Base Document Cost',
computedValue: () => {
const platform = platformSection.dropdown('platformType')?.value() || 'website';
const complexity = platformSection.dropdown('complexity')?.value() || 'standard';
const jurisdiction = platformSection.dropdown('jurisdiction')?.value() || 'us-single';
const basePrice = platformPrices?.[platform] ?? 400;
const complexityMult = complexityMultipliers?.[complexity] ?? 1.0;
const jurisdictionMult = jurisdictionMultipliers?.[jurisdiction] ?? 1.0;
return Math.round(basePrice * complexityMult * jurisdictionMult);
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('clausesCost', {
label: 'Special Clauses',
computedValue: () => {
let total = 0;
if (clausesSection.checkbox('arbitration')?.value()) total += clausePrices['arbitration'] ?? 0;
if (clausesSection.checkbox('classActionWaiver')?.value()) total += clausePrices['class-action-waiver'] ?? 0;
if (clausesSection.checkbox('dmca')?.value()) total += clausePrices['dmca'] ?? 0;
if (clausesSection.checkbox('userContent')?.value()) total += clausePrices['user-content'] ?? 0;
if (clausesSection.checkbox('subscriptionBilling')?.value()) total += clausePrices['subscription-billing'] ?? 0;
if (clausesSection.checkbox('refundPolicy')?.value()) total += clausePrices['refund-policy'] ?? 0;
if (clausesSection.checkbox('ageRestrictions')?.value()) total += clausePrices['age-restrictions'] ?? 0;
if (clausesSection.checkbox('apiUsage')?.value()) total += clausePrices['api-usage'] ?? 0;
if (clausesSection.checkbox('dataLicensing')?.value()) total += clausePrices['data-licensing'] ?? 0;
if (clausesSection.checkbox('indemnification')?.value()) total += clausePrices['indemnification'] ?? 0;
return total;
},
variant: 'default',
prefix: '+'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('servicesCost', {
label: 'Additional Services',
computedValue: () => {
let total = 0;
if (servicesSection.checkbox('legalReview')?.value()) total += 300;
if (servicesSection.checkbox('customization')?.value()) total += 400;
const revisions = servicesSection.dropdown('revisions')?.value() || '1';
if (revisions === '2') total += 150;
else if (revisions === '3') total += 300;
else if (revisions === 'unlimited') total += 500;
if (servicesSection.checkbox('annualUpdate')?.value()) total += 300;
if (servicesSection.checkbox('clickwrapSetup')?.value()) total += 150;
return total;
},
variant: 'default',
prefix: '+'
}, '1fr');
row.addPriceDisplay('turnaroundCost', {
label: 'Rush Fee',
computedValue: () => {
const platform = platformSection.dropdown('platformType')?.value() || 'website';
const complexity = platformSection.dropdown('complexity')?.value() || 'standard';
const jurisdiction = platformSection.dropdown('jurisdiction')?.value() || 'us-single';
const turnaround = servicesSection.dropdown('turnaround')?.value() || 'standard';
const basePrice = platformPrices?.[platform] ?? 400;
const complexityMult = complexityMultipliers?.[complexity] ?? 1.0;
const jurisdictionMult = jurisdictionMultipliers?.[jurisdiction] ?? 1.0;
const baseCost = basePrice * complexityMult * jurisdictionMult;
if (turnaround === 'expedited') return Math.round(baseCost * 0.25);
if (turnaround === 'rush') return Math.round(baseCost * 0.50);
return 0;
},
variant: 'default',
prefix: '+'
}, '1fr');
});
const finalSection = form.addSubform('final', {
title: '๐งพ Total Cost',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('totalCost', {
label: 'Total Investment',
computedValue: () => {
const platform = platformSection.dropdown('platformType')?.value() || 'website';
const complexity = platformSection.dropdown('complexity')?.value() || 'standard';
const jurisdiction = platformSection.dropdown('jurisdiction')?.value() || 'us-single';
const turnaround = servicesSection.dropdown('turnaround')?.value() || 'standard';
// Base cost
const basePrice = platformPrices?.[platform] ?? 400;
const complexityMult = complexityMultipliers?.[complexity] ?? 1.0;
const jurisdictionMult = jurisdictionMultipliers?.[jurisdiction] ?? 1.0;
let total = basePrice * complexityMult * jurisdictionMult;
// Turnaround multiplier
if (turnaround === 'expedited') total *= 1.25;
else if (turnaround === 'rush') total *= 1.50;
// Clauses
if (clausesSection.checkbox('arbitration')?.value()) total += clausePrices['arbitration'] ?? 0;
if (clausesSection.checkbox('classActionWaiver')?.value()) total += clausePrices['class-action-waiver'] ?? 0;
if (clausesSection.checkbox('dmca')?.value()) total += clausePrices['dmca'] ?? 0;
if (clausesSection.checkbox('userContent')?.value()) total += clausePrices['user-content'] ?? 0;
if (clausesSection.checkbox('subscriptionBilling')?.value()) total += clausePrices['subscription-billing'] ?? 0;
if (clausesSection.checkbox('refundPolicy')?.value()) total += clausePrices['refund-policy'] ?? 0;
if (clausesSection.checkbox('ageRestrictions')?.value()) total += clausePrices['age-restrictions'] ?? 0;
if (clausesSection.checkbox('apiUsage')?.value()) total += clausePrices['api-usage'] ?? 0;
if (clausesSection.checkbox('dataLicensing')?.value()) total += clausePrices['data-licensing'] ?? 0;
if (clausesSection.checkbox('indemnification')?.value()) total += clausePrices['indemnification'] ?? 0;
// Services
if (servicesSection.checkbox('legalReview')?.value()) total += 300;
if (servicesSection.checkbox('customization')?.value()) total += 400;
const revisions = servicesSection.dropdown('revisions')?.value() || '1';
if (revisions === '2') total += 150;
else if (revisions === '3') total += 300;
else if (revisions === 'unlimited') total += 500;
if (servicesSection.checkbox('annualUpdate')?.value()) total += 300;
if (servicesSection.checkbox('clickwrapSetup')?.value()) total += 150;
return Math.round(total);
},
variant: 'large'
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'This estimate is for planning purposes only. Final pricing depends on specific requirements and complexity. Terms of Service should be reviewed by a qualified attorney for your jurisdiction.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Get Started'
});
}