export function languageLearningCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Language Learning Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Language Selection Section
const languageSection = form.addSubform('language', { title: '🌍 Language Selection' });
languageSection.addRow(row => {
row.addDropdown('targetLanguage', {
label: 'Language to Learn',
options: [
{ id: 'spanish', name: 'Spanish' },
{ id: 'french', name: 'French' },
{ id: 'german', name: 'German' },
{ id: 'italian', name: 'Italian' },
{ id: 'portuguese', name: 'Portuguese' },
{ id: 'mandarin', name: 'Mandarin Chinese' },
{ id: 'japanese', name: 'Japanese' },
{ id: 'korean', name: 'Korean' },
{ id: 'arabic', name: 'Arabic' },
{ id: 'russian', name: 'Russian' },
{ id: 'english', name: 'English (ESL)' },
{ id: 'other', name: 'Other Language' }
],
defaultValue: 'spanish',
isRequired: true
}, '1fr');
row.addDropdown('currentLevel', {
label: 'Current Level',
options: [
{ id: 'absolute-beginner', name: 'Absolute Beginner' },
{ id: 'beginner', name: 'Beginner (A1)' },
{ id: 'elementary', name: 'Elementary (A2)' },
{ id: 'intermediate', name: 'Intermediate (B1)' },
{ id: 'upper-intermediate', name: 'Upper Intermediate (B2)' },
{ id: 'advanced', name: 'Advanced (C1)' }
],
defaultValue: 'absolute-beginner',
isRequired: true
}, '1fr');
});
languageSection.addRow(row => {
row.addDropdown('goalLevel', {
label: 'Goal Level',
options: [
{ id: 'survival', name: 'Survival/Travel Basics' },
{ id: 'conversational', name: 'Conversational (B1)' },
{ id: 'professional', name: 'Professional (B2)' },
{ id: 'fluent', name: 'Fluent (C1)' },
{ id: 'native-like', name: 'Near-Native (C2)' }
],
defaultValue: 'conversational',
isRequired: true
}, '1fr');
row.addDropdown('learningPurpose', {
label: 'Purpose',
options: [
{ id: 'travel', name: 'Travel' },
{ id: 'work', name: 'Work/Business' },
{ id: 'academic', name: 'Academic/Study' },
{ id: 'personal', name: 'Personal Interest' },
{ id: 'immigration', name: 'Immigration/Citizenship' },
{ id: 'heritage', name: 'Heritage Language' }
],
defaultValue: 'personal'
}, '1fr');
});
// Learning Format Section
const formatSection = form.addSubform('format', { title: '📚 Learning Format' });
formatSection.addRow(row => {
row.addRadioButton('primaryFormat', {
label: 'Primary Learning Method',
options: [
{ id: 'private', name: 'Private Tutoring' },
{ id: 'group', name: 'Group Classes' },
{ id: 'online-live', name: 'Online Live Classes' },
{ id: 'self-study', name: 'Self-Study (Apps/Courses)' },
{ id: 'immersion', name: 'Immersion Program' },
{ id: 'hybrid', name: 'Hybrid (Mixed Methods)' }
],
defaultValue: 'private',
isRequired: true
});
});
// Private Tutoring Options
const privateSection = form.addSubform('private', {
title: '👨🏫 Private Tutoring',
isVisible: () => ['private', 'hybrid'].includes(formatSection.radioButton('primaryFormat')?.value() || '')
});
privateSection.addRow(row => {
row.addDropdown('tutorType', {
label: 'Tutor Type',
options: [
{ id: 'community', name: 'Community Tutor' },
{ id: 'professional', name: 'Professional Teacher' },
{ id: 'native-certified', name: 'Native + Certified' },
{ id: 'specialist', name: 'Specialist (Business, Exam Prep)' }
],
defaultValue: 'professional'
}, '1fr');
row.addDropdown('tutorLocation', {
label: 'Lesson Format',
options: [
{ id: 'online', name: 'Online (Zoom, Skype)' },
{ id: 'in-person', name: 'In-Person' },
{ id: 'both', name: 'Mix of Both' }
],
defaultValue: 'online'
}, '1fr');
});
privateSection.addRow(row => {
row.addDropdown('sessionLength', {
label: 'Session Length',
options: [
{ id: '30', name: '30 Minutes' },
{ id: '45', name: '45 Minutes' },
{ id: '60', name: '60 Minutes' },
{ id: '90', name: '90 Minutes' }
],
defaultValue: '60'
}, '1fr');
row.addDropdown('sessionsPerWeek', {
label: 'Sessions per Week',
options: [
{ id: '1', name: '1x per week' },
{ id: '2', name: '2x per week' },
{ id: '3', name: '3x per week' },
{ id: '5', name: '5x per week (Intensive)' }
],
defaultValue: '2'
}, '1fr');
});
// Group Class Options
const groupSection = form.addSubform('group', {
title: '👥 Group Classes',
isVisible: () => ['group', 'hybrid'].includes(formatSection.radioButton('primaryFormat')?.value() || '')
});
groupSection.addRow(row => {
row.addDropdown('schoolType', {
label: 'School Type',
options: [
{ id: 'community', name: 'Community College' },
{ id: 'language-school', name: 'Language School' },
{ id: 'university', name: 'University Extension' },
{ id: 'cultural', name: 'Cultural Center' },
{ id: 'online-school', name: 'Online School' }
],
defaultValue: 'language-school'
}, '1fr');
row.addDropdown('classSize', {
label: 'Class Size',
options: [
{ id: 'small', name: 'Small (4-6 students)' },
{ id: 'medium', name: 'Medium (7-12 students)' },
{ id: 'large', name: 'Large (13-20 students)' }
],
defaultValue: 'small'
}, '1fr');
});
groupSection.addRow(row => {
row.addDropdown('groupFrequency', {
label: 'Class Frequency',
options: [
{ id: '1', name: '1x per week' },
{ id: '2', name: '2x per week' },
{ id: '3', name: '3x per week' },
{ id: '5', name: 'Daily (Intensive)' }
],
defaultValue: '2'
}, '1fr');
row.addDropdown('groupDuration', {
label: 'Class Duration',
options: [
{ id: '60', name: '1 Hour' },
{ id: '90', name: '1.5 Hours' },
{ id: '120', name: '2 Hours' },
{ id: '180', name: '3 Hours' }
],
defaultValue: '90'
}, '1fr');
});
// Self-Study Options
const selfStudySection = form.addSubform('selfStudy', {
title: '📱 Self-Study Resources',
isVisible: () => ['self-study', 'hybrid'].includes(formatSection.radioButton('primaryFormat')?.value() || '')
});
selfStudySection.addRow(row => {
row.addCheckbox('appSubscription', {
label: 'Language App (Duolingo, Babbel, etc.)',
defaultValue: true
}, '1fr');
row.addCheckbox('premiumApp', {
label: 'Premium App Features',
defaultValue: false
}, '1fr');
});
selfStudySection.addRow(row => {
row.addCheckbox('onlineCourse', {
label: 'Structured Online Course',
defaultValue: false
}, '1fr');
row.addCheckbox('textbooks', {
label: 'Textbooks & Workbooks',
defaultValue: true
}, '1fr');
});
// Immersion Options
const immersionSection = form.addSubform('immersion', {
title: '✈️ Immersion Program',
isVisible: () => formatSection.radioButton('primaryFormat')?.value() === 'immersion'
});
immersionSection.addRow(row => {
row.addDropdown('immersionType', {
label: 'Program Type',
options: [
{ id: 'standard', name: 'Standard Course' },
{ id: 'intensive', name: 'Intensive Course' },
{ id: 'homestay', name: 'Homestay + Classes' },
{ id: 'work-study', name: 'Work & Study' }
],
defaultValue: 'standard'
}, '1fr');
row.addInteger('immersionWeeks', {
label: 'Program Duration (weeks)',
min: 1,
max: 52,
defaultValue: 4
}, '1fr');
});
immersionSection.addRow(row => {
row.addCheckbox('accommodation', {
label: 'Include Accommodation',
defaultValue: true
}, '1fr');
row.addCheckbox('meals', {
label: 'Include Meals',
defaultValue: false
}, '1fr');
});
// Additional Options
const additionalSection = form.addSubform('additional', { title: '➕ Additional Resources' });
additionalSection.addRow(row => {
row.addCheckbox('examPrep', {
label: 'Exam Preparation (DELE, DELF, HSK, etc.)',
defaultValue: false
}, '1fr');
row.addCheckbox('businessLanguage', {
label: 'Business Language Focus',
defaultValue: false
}, '1fr');
});
additionalSection.addRow(row => {
row.addCheckbox('conversationPartner', {
label: 'Conversation Partner/Exchange',
defaultValue: false
}, '1fr');
row.addCheckbox('flashcardApp', {
label: 'Flashcard App (Anki, etc.)',
defaultValue: false
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Results Section
const resultsSection = form.addSubform('results', { title: '📊 Cost & Time Estimate', isCollapsible: false });
const calculatePricing = () => {
const targetLanguage = languageSection.dropdown('targetLanguage')?.value() || 'spanish';
const currentLevel = languageSection.dropdown('currentLevel')?.value() || 'absolute-beginner';
const goalLevel = languageSection.dropdown('goalLevel')?.value() || 'conversational';
const primaryFormat = formatSection.radioButton('primaryFormat')?.value() || 'private';
// Language difficulty categories (hours needed for English speakers)
const languageDifficulty = {
'spanish': 600,
'french': 600,
'italian': 600,
'portuguese': 600,
'german': 750,
'russian': 1100,
'mandarin': 2200,
'japanese': 2200,
'korean': 2200,
'arabic': 2200,
'english': 600,
'other': 900
};
// Level progress (percentage of total hours)
const levelProgress = {
'absolute-beginner': 0,
'beginner': 0.1,
'elementary': 0.25,
'intermediate': 0.45,
'upper-intermediate': 0.65,
'advanced': 0.85
};
const goalProgress = {
'survival': 0.15,
'conversational': 0.45,
'professional': 0.65,
'fluent': 0.85,
'native-like': 1.0
};
const totalHoursForLanguage = languageDifficulty[targetLanguage];
const startProgress = levelProgress[currentLevel];
const endProgress = goalProgress[goalLevel];
const hoursNeeded = Math.max(50, Math.round(totalHoursForLanguage * (endProgress - startProgress)));
let monthlyCost = 0;
let estimatedMonths = 0;
if (primaryFormat === 'private' || primaryFormat === 'hybrid') {
const tutorType = privateSection.dropdown('tutorType')?.value() || 'professional';
const tutorLocation = privateSection.dropdown('tutorLocation')?.value() || 'online';
const sessionLength = parseInt(privateSection.dropdown('sessionLength')?.value() || '60');
const sessionsPerWeek = parseInt(privateSection.dropdown('sessionsPerWeek')?.value() || '2');
const tutorRates = {
'community': 15,
'professional': 35,
'native-certified': 50,
'specialist': 75
};
let hourlyRate = tutorRates[tutorType];
if (tutorLocation === 'in-person') hourlyRate *= 1.3;
const weeklyHours = (sessionLength / 60) * sessionsPerWeek;
const weeklyCost = hourlyRate * weeklyHours;
monthlyCost += weeklyCost * 4;
estimatedMonths = Math.ceil(hoursNeeded / (weeklyHours * 4));
}
if (primaryFormat === 'group' || primaryFormat === 'hybrid') {
const schoolType = groupSection.dropdown('schoolType')?.value() || 'language-school';
const classSize = groupSection.dropdown('classSize')?.value() || 'small';
const groupFrequency = parseInt(groupSection.dropdown('groupFrequency')?.value() || '2');
const groupDuration = parseInt(groupSection.dropdown('groupDuration')?.value() || '90');
const schoolRates = {
'community': 100,
'language-school': 200,
'university': 300,
'cultural': 150,
'online-school': 120
};
let monthlySchoolCost = schoolRates[schoolType];
if (classSize === 'small') monthlySchoolCost *= 1.5;
if (classSize === 'large') monthlySchoolCost *= 0.7;
monthlyCost += monthlySchoolCost;
const weeklyHours = (groupDuration / 60) * groupFrequency;
if (primaryFormat === 'group') {
estimatedMonths = Math.ceil(hoursNeeded / (weeklyHours * 4));
}
}
if (primaryFormat === 'online-live') {
monthlyCost = 150;
estimatedMonths = Math.ceil(hoursNeeded / 16);
}
if (primaryFormat === 'self-study') {
if (selfStudySection.checkbox('premiumApp')?.value()) {
monthlyCost += 15;
}
if (selfStudySection.checkbox('onlineCourse')?.value()) {
monthlyCost += 30;
}
if (selfStudySection.checkbox('textbooks')?.value()) {
monthlyCost += 10; // Amortized
}
estimatedMonths = Math.ceil(hoursNeeded / 10); // Slower progress
}
if (primaryFormat === 'hybrid') {
// Combine and accelerate
estimatedMonths = Math.ceil(estimatedMonths * 0.8);
}
if (primaryFormat === 'immersion') {
const immersionType = immersionSection.dropdown('immersionType')?.value() || 'standard';
const weeks = immersionSection.integer('immersionWeeks')?.value() || 4;
const includeAccommodation = immersionSection.checkbox('accommodation')?.value() || false;
const includeMeals = immersionSection.checkbox('meals')?.value() || false;
const weeklyRates = {
'standard': 300,
'intensive': 450,
'homestay': 600,
'work-study': 400
};
let weeklyCost = weeklyRates[immersionType];
if (includeAccommodation) weeklyCost += 400;
if (includeMeals) weeklyCost += 150;
monthlyCost = weeklyCost * 4;
estimatedMonths = Math.ceil(weeks / 4);
}
// Additional resources
if (additionalSection.checkbox('examPrep')?.value()) monthlyCost += 50;
if (additionalSection.checkbox('businessLanguage')?.value()) monthlyCost += 30;
if (additionalSection.checkbox('conversationPartner')?.value()) monthlyCost += 20;
if (additionalSection.checkbox('flashcardApp')?.value()) monthlyCost += 5;
const totalCost = monthlyCost * estimatedMonths;
return {
hoursNeeded,
estimatedMonths: Math.max(1, estimatedMonths),
monthlyCost: Math.round(monthlyCost),
totalCost: Math.round(totalCost)
};
};
resultsSection.addRow(row => {
row.addTextPanel('hoursNeeded', {
label: 'Estimated Hours to Goal',
computedValue: () => `${calculatePricing().hoursNeeded} hours`,
customStyles: { 'font-size': '1.2rem', 'font-weight': '500', 'text-align': 'center' }
}, '1fr');
row.addTextPanel('timeframe', {
label: 'Estimated Timeline',
computedValue: () => {
const months = calculatePricing().estimatedMonths;
if (months < 12) return `${months} months`;
const years = Math.floor(months / 12);
const remainingMonths = months % 12;
return remainingMonths > 0 ? `${years} year${years > 1 ? 's' : ''}, ${remainingMonths} months` : `${years} year${years > 1 ? 's' : ''}`;
},
customStyles: { 'font-size': '1.2rem', 'font-weight': '500', 'text-align': 'center' }
}, '1fr');
});
resultsSection.addRow(row => {
row.addPriceDisplay('monthlyCost', {
label: 'Monthly Investment',
computedValue: () => calculatePricing().monthlyCost,
variant: 'default'
}, '1fr');
row.addPriceDisplay('totalCost', {
label: 'Total Estimated Cost',
computedValue: () => calculatePricing().totalCost,
variant: 'default'
}, '1fr');
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '🎯 Learning Plan',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addTextPanel('summary', {
computedValue: () => {
const pricing = calculatePricing();
return `$${pricing.monthlyCost}/month for ~${pricing.estimatedMonths} months`;
},
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'text-align': 'center', 'color': '#059669' }
});
});
summarySection.addRow(row => {
row.addTextPanel('note', {
computedValue: () => 'Timeline depends on dedication and practice. Consistent daily study accelerates progress significantly.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Start Learning'
});
}