export function translationServicesCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Translation Services Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Language Pair Section
const languageSection = form.addSubform('languages', { title: '🌍 Language Pair' });
languageSection.addRow(row => {
row.addDropdown('sourceLanguage', {
label: 'Source Language',
options: [
{ id: 'en', name: 'English' },
{ id: 'es', name: 'Spanish' },
{ id: 'fr', name: 'French' },
{ id: 'de', name: 'German' },
{ id: 'it', name: 'Italian' },
{ id: 'pt', name: 'Portuguese' },
{ id: 'zh', name: 'Chinese (Mandarin)' },
{ id: 'ja', name: 'Japanese' },
{ id: 'ko', name: 'Korean' },
{ id: 'ar', name: 'Arabic' },
{ id: 'ru', name: 'Russian' },
{ id: 'pl', name: 'Polish' },
{ id: 'nl', name: 'Dutch' },
{ id: 'sv', name: 'Swedish' },
{ id: 'other', name: 'Other / Rare Language' }
],
defaultValue: 'en',
isRequired: true
}, '1fr');
row.addDropdown('targetLanguage', {
label: 'Target Language',
options: [
{ id: 'en', name: 'English' },
{ id: 'es', name: 'Spanish' },
{ id: 'fr', name: 'French' },
{ id: 'de', name: 'German' },
{ id: 'it', name: 'Italian' },
{ id: 'pt', name: 'Portuguese' },
{ id: 'zh', name: 'Chinese (Mandarin)' },
{ id: 'ja', name: 'Japanese' },
{ id: 'ko', name: 'Korean' },
{ id: 'ar', name: 'Arabic' },
{ id: 'ru', name: 'Russian' },
{ id: 'pl', name: 'Polish' },
{ id: 'nl', name: 'Dutch' },
{ id: 'sv', name: 'Swedish' },
{ id: 'other', name: 'Other / Rare Language' }
],
defaultValue: 'es',
isRequired: true
}, '1fr');
});
// Document Details Section
const documentSection = form.addSubform('document', { title: '📄 Document Details' });
documentSection.addRow(row => {
row.addInteger('wordCount', {
label: 'Word Count',
min: 1,
max: 1000000,
defaultValue: 2500,
isRequired: true,
tooltip: 'Total words in source document'
}, '1fr');
row.addDropdown('documentType', {
label: 'Document Type',
options: [
{ id: 'general', name: 'General / Business' },
{ id: 'marketing', name: 'Marketing / Advertising' },
{ id: 'technical', name: 'Technical / Engineering' },
{ id: 'legal', name: 'Legal / Contracts' },
{ id: 'medical', name: 'Medical / Healthcare' },
{ id: 'financial', name: 'Financial / Banking' },
{ id: 'academic', name: 'Academic / Scientific' },
{ id: 'literary', name: 'Literary / Creative' },
{ id: 'software', name: 'Software / UI Strings' },
{ id: 'website', name: 'Website / Web Content' }
],
defaultValue: 'general',
isRequired: true
}, '1fr');
});
documentSection.addRow(row => {
row.addDropdown('complexity', {
label: 'Content Complexity',
options: [
{ id: 'simple', name: 'Simple - Basic vocabulary' },
{ id: 'standard', name: 'Standard - Professional content' },
{ id: 'complex', name: 'Complex - Specialized terminology' },
{ id: 'expert', name: 'Expert - Highly technical' }
],
defaultValue: 'standard',
tooltip: 'Higher complexity requires specialist translators'
});
});
// Service Options Section
const serviceSection = form.addSubform('service', { title: '⚙️ Service Options' });
serviceSection.addRow(row => {
row.addDropdown('turnaround', {
label: 'Turnaround Time',
options: [
{ id: 'standard', name: 'Standard (5-7 business days)' },
{ id: 'express', name: 'Express (2-4 business days)' },
{ id: 'rush', name: 'Rush (24-48 hours)' },
{ id: 'urgent', name: 'Urgent (Same day)' }
],
defaultValue: 'standard',
isRequired: true
}, '1fr');
row.addDropdown('quality', {
label: 'Quality Level',
options: [
{ id: 'standard', name: 'Standard Translation' },
{ id: 'premium', name: 'Premium (Translation + Editing)' },
{ id: 'certified', name: 'Certified Translation' }
],
defaultValue: 'standard',
tooltip: 'Premium includes proofreading by second translator'
}, '1fr');
});
// Add-on Services Section
const addonsSection = form.addSubform('addons', { title: '✨ Additional Services' });
addonsSection.addRow(row => {
row.addCheckbox('proofreading', {
label: 'Native Proofreading',
defaultValue: false,
tooltip: 'Review by native speaker for fluency'
}, '1fr');
row.addCheckbox('formatting', {
label: 'Desktop Publishing / Formatting',
defaultValue: false,
tooltip: 'Match original document layout'
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('notarization', {
label: 'Notarization',
defaultValue: false,
tooltip: 'Notarized certification for legal use'
}, '1fr');
row.addCheckbox('apostille', {
label: 'Apostille Service',
defaultValue: false,
tooltip: 'For international legal recognition'
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('terminology', {
label: 'Glossary / Terminology Management',
defaultValue: false,
tooltip: 'Consistent terminology across documents'
}, '1fr');
row.addCheckbox('qa', {
label: 'Quality Assurance Report',
defaultValue: false,
tooltip: 'Detailed QA documentation'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Pricing Breakdown Section
const breakdownSection = form.addSubform('breakdown', { title: '📊 Price Breakdown', isCollapsible: true });
breakdownSection.addRow(row => {
row.addPriceDisplay('baseRate', {
label: 'Base Rate per Word',
computedValue: () => {
const source = languageSection.dropdown('sourceLanguage')?.value() || 'en';
const target = languageSection.dropdown('targetLanguage')?.value() || 'es';
const docType = documentSection.dropdown('documentType')?.value() || 'general';
// Base rates by language difficulty
const commonLanguages = ['en', 'es', 'fr', 'de', 'it', 'pt'];
const isSourceCommon = commonLanguages.includes(source);
const isTargetCommon = commonLanguages.includes(target);
let baseRate = 0.10; // Base for common pair
if (!isSourceCommon || !isTargetCommon) baseRate = 0.15;
if (!isSourceCommon && !isTargetCommon) baseRate = 0.22;
if (source === 'other' || target === 'other') baseRate = 0.25;
// Document type multipliers
const docMultipliers: Record<string, number> = {
'general': 1, 'marketing': 1.1, 'technical': 1.25, 'legal': 1.4,
'medical': 1.5, 'financial': 1.3, 'academic': 1.2, 'literary': 1.15,
'software': 1.1, 'website': 1.05
};
return Math.round(baseRate * (docMultipliers[docType] || 1) * 1000) / 1000;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('complexityPremium', {
label: 'Complexity Premium',
computedValue: () => {
const complexity = documentSection.dropdown('complexity')?.value() || 'standard';
const wordCount = documentSection.integer('wordCount')?.value() || 2500;
const baseRate = 0.10;
const complexityMultipliers: Record<string, number> = {
'simple': 0, 'standard': 0, 'complex': 0.03, 'expert': 0.06
};
return Math.round(wordCount * (complexityMultipliers[complexity] || 0) * 100) / 100;
},
variant: 'default'
}, '1fr');
});
breakdownSection.addRow(row => {
row.addPriceDisplay('turnaroundFee', {
label: 'Rush Fee',
computedValue: () => {
const turnaround = serviceSection.dropdown('turnaround')?.value() || 'standard';
const wordCount = documentSection.integer('wordCount')?.value() || 2500;
const baseTotal = wordCount * 0.12; // Approximate base
const rushMultipliers: Record<string, number> = {
'standard': 0, 'express': 0.25, 'rush': 0.5, 'urgent': 1
};
return Math.round(baseTotal * (rushMultipliers[turnaround] || 0) * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('qualityFee', {
label: 'Quality Level Fee',
computedValue: () => {
const quality = serviceSection.dropdown('quality')?.value() || 'standard';
const wordCount = documentSection.integer('wordCount')?.value() || 2500;
const baseTotal = wordCount * 0.12;
const qualityMultipliers: Record<string, number> = {
'standard': 0, 'premium': 0.3, 'certified': 0.5
};
return Math.round(baseTotal * (qualityMultipliers[quality] || 0) * 100) / 100;
},
variant: 'default'
}, '1fr');
});
breakdownSection.addRow(row => {
row.addPriceDisplay('addonsFee', {
label: 'Add-on Services',
computedValue: () => {
let total = 0;
const wordCount = documentSection.integer('wordCount')?.value() || 2500;
if (addonsSection.checkbox('proofreading')?.value()) total += wordCount * 0.02;
if (addonsSection.checkbox('formatting')?.value()) total += 75;
if (addonsSection.checkbox('notarization')?.value()) total += 50;
if (addonsSection.checkbox('apostille')?.value()) total += 150;
if (addonsSection.checkbox('terminology')?.value()) total += 100;
if (addonsSection.checkbox('qa')?.value()) total += 50;
return Math.round(total * 100) / 100;
},
variant: 'default'
});
});
// Quote Section
const quoteSection = form.addSubform('quote', { title: '💰 Your Quote', isCollapsible: false });
quoteSection.addRow(row => {
row.addPriceDisplay('totalPrice', {
label: 'Total Translation Cost',
computedValue: () => {
const source = languageSection.dropdown('sourceLanguage')?.value() || 'en';
const target = languageSection.dropdown('targetLanguage')?.value() || 'es';
const wordCount = documentSection.integer('wordCount')?.value() || 2500;
const docType = documentSection.dropdown('documentType')?.value() || 'general';
const complexity = documentSection.dropdown('complexity')?.value() || 'standard';
const turnaround = serviceSection.dropdown('turnaround')?.value() || 'standard';
const quality = serviceSection.dropdown('quality')?.value() || 'standard';
// Base rate calculation
const commonLanguages = ['en', 'es', 'fr', 'de', 'it', 'pt'];
const isSourceCommon = commonLanguages.includes(source);
const isTargetCommon = commonLanguages.includes(target);
let baseRate = 0.10;
if (!isSourceCommon || !isTargetCommon) baseRate = 0.15;
if (!isSourceCommon && !isTargetCommon) baseRate = 0.22;
if (source === 'other' || target === 'other') baseRate = 0.25;
// Multipliers
const docMultipliers: Record<string, number> = {
'general': 1, 'marketing': 1.1, 'technical': 1.25, 'legal': 1.4,
'medical': 1.5, 'financial': 1.3, 'academic': 1.2, 'literary': 1.15,
'software': 1.1, 'website': 1.05
};
const complexityMultipliers: Record<string, number> = {
'simple': 0.9, 'standard': 1, 'complex': 1.2, 'expert': 1.4
};
const rushMultipliers: Record<string, number> = {
'standard': 1, 'express': 1.25, 'rush': 1.5, 'urgent': 2
};
const qualityMultipliers: Record<string, number> = {
'standard': 1, 'premium': 1.3, 'certified': 1.5
};
let total = wordCount * baseRate *
(docMultipliers[docType] || 1) *
(complexityMultipliers[complexity] || 1) *
(rushMultipliers[turnaround] || 1) *
(qualityMultipliers[quality] || 1);
// Add-ons
if (addonsSection.checkbox('proofreading')?.value()) total += wordCount * 0.02;
if (addonsSection.checkbox('formatting')?.value()) total += 75;
if (addonsSection.checkbox('notarization')?.value()) total += 50;
if (addonsSection.checkbox('apostille')?.value()) total += 150;
if (addonsSection.checkbox('terminology')?.value()) total += 100;
if (addonsSection.checkbox('qa')?.value()) total += 50;
// Minimum order
return Math.max(Math.round(total * 100) / 100, 50);
},
variant: 'large'
});
});
quoteSection.addRow(row => {
row.addTextPanel('pricePerWord', {
computedValue: () => {
const wordCount = documentSection.integer('wordCount')?.value() || 2500;
const source = languageSection.dropdown('sourceLanguage')?.value() || 'en';
const target = languageSection.dropdown('targetLanguage')?.value() || 'es';
const docType = documentSection.dropdown('documentType')?.value() || 'general';
const commonLanguages = ['en', 'es', 'fr', 'de', 'it', 'pt'];
const isSourceCommon = commonLanguages.includes(source);
const isTargetCommon = commonLanguages.includes(target);
let baseRate = 0.10;
if (!isSourceCommon || !isTargetCommon) baseRate = 0.15;
if (!isSourceCommon && !isTargetCommon) baseRate = 0.22;
if (source === 'other' || target === 'other') baseRate = 0.25;
const docMultipliers: Record<string, number> = {
'general': 1, 'marketing': 1.1, 'technical': 1.25, 'legal': 1.4,
'medical': 1.5, 'financial': 1.3, 'academic': 1.2, 'literary': 1.15,
'software': 1.1, 'website': 1.05
};
const effectiveRate = baseRate * (docMultipliers[docType] || 1);
return `${wordCount.toLocaleString()} words × $${(Number(effectiveRate) || 0).toFixed(3)}/word (base)`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#64748b', 'text-align': 'center' }
});
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '📋 Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addTextPanel('summaryText', {
computedValue: () => {
const source = languageSection.dropdown('sourceLanguage')?.value() || 'en';
const target = languageSection.dropdown('targetLanguage')?.value() || 'es';
const quality = serviceSection.dropdown('quality')?.value() || 'standard';
const turnaround = serviceSection.dropdown('turnaround')?.value() || 'standard';
const langNames: Record<string, string> = {
'en': 'English', 'es': 'Spanish', 'fr': 'French', 'de': 'German',
'it': 'Italian', 'pt': 'Portuguese', 'zh': 'Chinese', 'ja': 'Japanese',
'ko': 'Korean', 'ar': 'Arabic', 'ru': 'Russian', 'pl': 'Polish',
'nl': 'Dutch', 'sv': 'Swedish', 'other': 'Rare Language'
};
const qualityLabels: Record<string, string> = {
'standard': 'Standard', 'premium': 'Premium', 'certified': 'Certified'
};
const turnaroundLabels: Record<string, string> = {
'standard': 'Standard', 'express': 'Express', 'rush': 'Rush', 'urgent': 'Urgent'
};
return `${langNames[source]} → ${langNames[target]} | ${qualityLabels[quality]} | ${turnaroundLabels[turnaround]} delivery`;
},
customStyles: { 'font-size': '0.95rem', 'font-weight': '500', 'text-align': 'center', 'color': '#1e293b' }
});
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Final pricing may vary based on source document review. Minimum order: $50.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Request Quote'
});
}