export function onlineCourseCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Online Course Pricing Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Course Type Section
const courseSection = form.addSubform('course', { title: '📚 Course Details' });
courseSection.addRow(row => {
row.addDropdown('courseCategory', {
label: 'Course Category',
options: [
{ id: 'tech', name: 'Technology/Programming' },
{ id: 'business', name: 'Business/Entrepreneurship' },
{ id: 'marketing', name: 'Marketing/Sales' },
{ id: 'design', name: 'Design/Creative' },
{ id: 'personal', name: 'Personal Development' },
{ id: 'health', name: 'Health/Fitness' },
{ id: 'language', name: 'Language Learning' },
{ id: 'academic', name: 'Academic/Test Prep' },
{ id: 'professional', name: 'Professional Certification' },
{ id: 'hobby', name: 'Hobby/Lifestyle' }
],
defaultValue: 'tech',
isRequired: true
}, '1fr');
row.addDropdown('courseLevel', {
label: 'Course Level',
options: [
{ id: 'beginner', name: 'Beginner' },
{ id: 'intermediate', name: 'Intermediate' },
{ id: 'advanced', name: 'Advanced' },
{ id: 'professional', name: 'Professional/Expert' }
],
defaultValue: 'intermediate'
}, '1fr');
});
courseSection.addRow(row => {
row.addInteger('courseHours', {
label: 'Total Course Hours',
min: 1,
max: 200,
defaultValue: 20,
tooltip: 'Total video/content hours'
}, '1fr');
row.addInteger('modules', {
label: 'Number of Modules',
min: 1,
max: 50,
defaultValue: 8
}, '1fr');
});
// Course Format Section
const formatSection = form.addSubform('format', { title: '🎬 Course Format' });
formatSection.addRow(row => {
row.addRadioButton('courseFormat', {
label: 'Delivery Format',
options: [
{ id: 'self-paced', name: 'Self-Paced (Pre-recorded videos)' },
{ id: 'cohort', name: 'Cohort-Based (Live + recordings)' },
{ id: 'hybrid', name: 'Hybrid (Mix of live and self-paced)' },
{ id: 'live-only', name: 'Live Only (Real-time instruction)' }
],
defaultValue: 'self-paced',
isRequired: true
});
});
formatSection.addRow(row => {
row.addDropdown('accessDuration', {
label: 'Access Duration',
options: [
{ id: '3months', name: '3 Months' },
{ id: '6months', name: '6 Months' },
{ id: '12months', name: '12 Months' },
{ id: 'lifetime', name: 'Lifetime Access (+40% value)' }
],
defaultValue: 'lifetime'
}, '1fr');
row.addDropdown('updates', {
label: 'Content Updates',
options: [
{ id: 'none', name: 'No Updates' },
{ id: '12months', name: '12 Months Free Updates' },
{ id: 'lifetime', name: 'Lifetime Updates (+20% value)' }
],
defaultValue: '12months'
}, '1fr');
});
// Features Section
const featuresSection = form.addSubform('features', { title: '✨ Course Features' });
featuresSection.addRow(row => {
row.addCheckbox('certificate', {
label: 'Certificate of Completion',
defaultValue: true
}, '1fr');
row.addCheckbox('downloadable', {
label: 'Downloadable Resources',
defaultValue: true,
tooltip: 'PDFs, templates, cheat sheets'
}, '1fr');
});
featuresSection.addRow(row => {
row.addCheckbox('assignments', {
label: 'Hands-On Assignments/Projects',
defaultValue: true
}, '1fr');
row.addCheckbox('quizzes', {
label: 'Quizzes & Assessments',
defaultValue: false
}, '1fr');
});
featuresSection.addRow(row => {
row.addCheckbox('community', {
label: 'Private Community Access',
defaultValue: false,
tooltip: 'Discord, Facebook Group, or Forum'
}, '1fr');
row.addCheckbox('qa', {
label: 'Q&A Support',
defaultValue: false,
tooltip: 'Email or discussion board support'
}, '1fr');
});
// Premium Add-ons Section
const premiumSection = form.addSubform('premium', { title: '💎 Premium Add-Ons' });
premiumSection.addRow(row => {
row.addCheckbox('oneOnOne', {
label: '1-on-1 Coaching Calls (+$200-500)',
defaultValue: false,
tooltip: 'Includes 2-4 private coaching sessions'
}, '1fr');
row.addCheckbox('groupCalls', {
label: 'Group Coaching Calls (+$100)',
defaultValue: false,
tooltip: 'Weekly or monthly group Q&A sessions'
}, '1fr');
});
premiumSection.addRow(row => {
row.addCheckbox('mentorship', {
label: 'Ongoing Mentorship (+$150/mo)',
defaultValue: false
}, '1fr');
row.addCheckbox('jobPlacement', {
label: 'Job Placement Assistance (+$200)',
defaultValue: false,
tooltip: 'Resume review, interview prep, job board access'
}, '1fr');
});
premiumSection.addRow(row => {
row.addCheckbox('bonusCourse', {
label: 'Bonus Mini-Course (+$50)',
defaultValue: false
}, '1fr');
row.addCheckbox('softwareLicense', {
label: 'Software/Tool License (+$100-300)',
defaultValue: false,
tooltip: 'Included access to premium tools'
}, '1fr');
});
// Pricing Model Section
const pricingSection = form.addSubform('pricing', { title: '💳 Pricing Options' });
pricingSection.addRow(row => {
row.addRadioButton('pricingModel', {
label: 'Pricing Model',
options: [
{ id: 'one-time', name: 'One-Time Payment' },
{ id: 'payment-plan', name: 'Payment Plan (3-6 installments)' },
{ id: 'subscription', name: 'Monthly Subscription' }
],
defaultValue: 'one-time',
isRequired: true
});
});
pricingSection.addRow(row => {
row.addInteger('paymentPlanMonths', {
label: 'Number of Payments',
min: 2,
max: 12,
defaultValue: 3,
isVisible: () => pricingSection.radioButton('pricingModel')?.value() === 'payment-plan'
});
});
pricingSection.addRow(row => {
row.addCheckbox('earlyBird', {
label: 'Early Bird Discount (15% off)',
defaultValue: false
}, '1fr');
row.addCheckbox('moneyBack', {
label: '30-Day Money-Back Guarantee',
defaultValue: true
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Market Comparison Section
const marketSection = form.addSubform('market', { title: '📊 Market Pricing Reference', isCollapsible: true });
marketSection.addRow(row => {
row.addTextPanel('marketInfo', {
computedValue: () => {
const category = courseSection.dropdown('courseCategory')?.value() || 'tech';
const level = courseSection.dropdown('courseLevel')?.value() || 'intermediate';
const priceRanges: Record<string, Record<string, string>> = {
'tech': { beginner: '$50-200', intermediate: '$200-500', advanced: '$400-1,000', professional: '$500-2,000' },
'business': { beginner: '$50-150', intermediate: '$150-400', advanced: '$300-800', professional: '$500-2,500' },
'marketing': { beginner: '$30-150', intermediate: '$150-400', advanced: '$300-700', professional: '$400-1,500' },
'design': { beginner: '$40-150', intermediate: '$150-350', advanced: '$300-600', professional: '$400-1,000' },
'personal': { beginner: '$20-100', intermediate: '$100-300', advanced: '$200-500', professional: '$300-800' },
'health': { beginner: '$30-100', intermediate: '$100-250', advanced: '$200-450', professional: '$300-700' },
'language': { beginner: '$50-150', intermediate: '$150-350', advanced: '$300-500', professional: '$400-800' },
'academic': { beginner: '$50-200', intermediate: '$200-400', advanced: '$350-700', professional: '$500-1,500' },
'professional': { beginner: '$100-300', intermediate: '$300-700', advanced: '$500-1,500', professional: '$800-3,000' },
'hobby': { beginner: '$20-80', intermediate: '$80-200', advanced: '$150-350', professional: '$200-500' }
};
const range = priceRanges[category]?.[level] || '$100-500';
return `Market range for ${level} ${category} courses: ${range}`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#475569' }
});
});
marketSection.addRow(row => {
row.addTextPanel('pricePerHour', {
computedValue: () => 'Industry benchmark: $5-25 per hour of content for mid-tier courses',
customStyles: { 'font-size': '0.85rem', 'color': '#64748b' }
});
});
// Cost Breakdown Section
const breakdownSection = form.addSubform('breakdown', { title: '💰 Suggested Price Breakdown', isCollapsible: true });
breakdownSection.addRow(row => {
row.addPriceDisplay('baseValue', {
label: 'Base Content Value',
computedValue: () => {
const hours = courseSection.integer('courseHours')?.value() || 20;
const category = courseSection.dropdown('courseCategory')?.value() || 'tech';
const level = courseSection.dropdown('courseLevel')?.value() || 'intermediate';
const categoryMultiplier: Record<string, number> = {
tech: 15, business: 12, marketing: 10, design: 11, personal: 8,
health: 9, language: 10, academic: 12, professional: 18, hobby: 6
};
const levelMultiplier: Record<string, number> = {
beginner: 0.7, intermediate: 1, advanced: 1.4, professional: 1.8
};
return Math.round(hours * (categoryMultiplier[category] || 10) * (levelMultiplier[level] || 1));
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('formatValue', {
label: 'Format Premium',
computedValue: () => {
const format = formatSection.radioButton('courseFormat')?.value() || 'self-paced';
const hours = courseSection.integer('courseHours')?.value() || 20;
const formatPremium: Record<string, number> = {
'self-paced': 0, 'cohort': hours * 8, 'hybrid': hours * 5, 'live-only': hours * 12
};
return formatPremium[format] || 0;
},
variant: 'default'
}, '1fr');
});
breakdownSection.addRow(row => {
row.addPriceDisplay('featureValue', {
label: 'Features Value',
computedValue: () => {
let value = 0;
if (featuresSection.checkbox('certificate')?.value()) value += 20;
if (featuresSection.checkbox('downloadable')?.value()) value += 30;
if (featuresSection.checkbox('assignments')?.value()) value += 50;
if (featuresSection.checkbox('quizzes')?.value()) value += 25;
if (featuresSection.checkbox('community')?.value()) value += 75;
if (featuresSection.checkbox('qa')?.value()) value += 50;
return value;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('premiumValue', {
label: 'Premium Add-Ons',
computedValue: () => {
let value = 0;
if (premiumSection.checkbox('oneOnOne')?.value()) value += 350;
if (premiumSection.checkbox('groupCalls')?.value()) value += 100;
if (premiumSection.checkbox('mentorship')?.value()) value += 150;
if (premiumSection.checkbox('jobPlacement')?.value()) value += 200;
if (premiumSection.checkbox('bonusCourse')?.value()) value += 50;
if (premiumSection.checkbox('softwareLicense')?.value()) value += 200;
return value;
},
variant: 'default'
}, '1fr');
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '🎯 Suggested Course Price',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addPriceDisplay('suggestedPrice', {
label: 'Suggested Price',
computedValue: () => {
const hours = courseSection.integer('courseHours')?.value() || 20;
const category = courseSection.dropdown('courseCategory')?.value() || 'tech';
const level = courseSection.dropdown('courseLevel')?.value() || 'intermediate';
const format = formatSection.radioButton('courseFormat')?.value() || 'self-paced';
const access = formatSection.dropdown('accessDuration')?.value() || 'lifetime';
const updates = formatSection.dropdown('updates')?.value() || '12months';
const earlyBird = pricingSection.checkbox('earlyBird')?.value() || false;
const categoryMultiplier: Record<string, number> = {
tech: 15, business: 12, marketing: 10, design: 11, personal: 8,
health: 9, language: 10, academic: 12, professional: 18, hobby: 6
};
const levelMultiplier: Record<string, number> = {
beginner: 0.7, intermediate: 1, advanced: 1.4, professional: 1.8
};
const formatPremium: Record<string, number> = {
'self-paced': 0, 'cohort': hours * 8, 'hybrid': hours * 5, 'live-only': hours * 12
};
let baseValue = hours * (categoryMultiplier[category] || 10) * (levelMultiplier[level] || 1);
baseValue += formatPremium[format] || 0;
if (access === 'lifetime') baseValue *= 1.4;
else if (access === '12months') baseValue *= 1.2;
if (updates === 'lifetime') baseValue *= 1.2;
let featureValue = 0;
if (featuresSection.checkbox('certificate')?.value()) featureValue += 20;
if (featuresSection.checkbox('downloadable')?.value()) featureValue += 30;
if (featuresSection.checkbox('assignments')?.value()) featureValue += 50;
if (featuresSection.checkbox('quizzes')?.value()) featureValue += 25;
if (featuresSection.checkbox('community')?.value()) featureValue += 75;
if (featuresSection.checkbox('qa')?.value()) featureValue += 50;
let premiumValue = 0;
if (premiumSection.checkbox('oneOnOne')?.value()) premiumValue += 350;
if (premiumSection.checkbox('groupCalls')?.value()) premiumValue += 100;
if (premiumSection.checkbox('mentorship')?.value()) premiumValue += 150;
if (premiumSection.checkbox('jobPlacement')?.value()) premiumValue += 200;
if (premiumSection.checkbox('bonusCourse')?.value()) premiumValue += 50;
if (premiumSection.checkbox('softwareLicense')?.value()) premiumValue += 200;
let total = baseValue + featureValue + premiumValue;
if (earlyBird) total *= 0.85;
return Math.round(total / 10) * 10;
},
variant: 'large'
}, '1fr');
row.addTextPanel('pricePerHourResult', {
label: 'Per Hour',
computedValue: () => {
const hours = courseSection.integer('courseHours')?.value() || 20;
const category = courseSection.dropdown('courseCategory')?.value() || 'tech';
const level = courseSection.dropdown('courseLevel')?.value() || 'intermediate';
const format = formatSection.radioButton('courseFormat')?.value() || 'self-paced';
const access = formatSection.dropdown('accessDuration')?.value() || 'lifetime';
const updates = formatSection.dropdown('updates')?.value() || '12months';
const categoryMultiplier: Record<string, number> = {
tech: 15, business: 12, marketing: 10, design: 11, personal: 8,
health: 9, language: 10, academic: 12, professional: 18, hobby: 6
};
const levelMultiplier: Record<string, number> = {
beginner: 0.7, intermediate: 1, advanced: 1.4, professional: 1.8
};
const formatPremium: Record<string, number> = {
'self-paced': 0, 'cohort': hours * 8, 'hybrid': hours * 5, 'live-only': hours * 12
};
let baseValue = hours * (categoryMultiplier[category] || 10) * (levelMultiplier[level] || 1);
baseValue += formatPremium[format] || 0;
if (access === 'lifetime') baseValue *= 1.4;
else if (access === '12months') baseValue *= 1.2;
if (updates === 'lifetime') baseValue *= 1.2;
const perHour = baseValue / hours;
return `$${Math.round(perHour)}/hr`;
},
customStyles: { 'font-size': '1.3rem', 'font-weight': '600', 'text-align': 'center', 'color': '#059669' }
}, '1fr');
});
summarySection.addRow(row => {
row.addTextPanel('paymentPlanPrice', {
computedValue: () => {
const model = pricingSection.radioButton('pricingModel')?.value() || 'one-time';
const months = pricingSection.integer('paymentPlanMonths')?.value() || 3;
const hours = courseSection.integer('courseHours')?.value() || 20;
const category = courseSection.dropdown('courseCategory')?.value() || 'tech';
const level = courseSection.dropdown('courseLevel')?.value() || 'intermediate';
const categoryMultiplier: Record<string, number> = {
tech: 15, business: 12, marketing: 10, design: 11, personal: 8,
health: 9, language: 10, academic: 12, professional: 18, hobby: 6
};
const levelMultiplier: Record<string, number> = {
beginner: 0.7, intermediate: 1, advanced: 1.4, professional: 1.8
};
let baseValue = hours * (categoryMultiplier[category] || 10) * (levelMultiplier[level] || 1);
baseValue = Math.round(baseValue / 10) * 10;
if (model === 'payment-plan') {
const planTotal = baseValue * 1.15;
const perPayment = Math.round(planTotal / months);
return `Payment plan: ${months}x $${perPayment} ($${Math.round(planTotal)} total)`;
}
if (model === 'subscription') {
return `Subscription: $${Math.round(baseValue / 6)}/month (6 months minimum)`;
}
return '';
},
customStyles: { 'font-size': '0.9rem', 'text-align': 'center', 'color': '#475569' },
isVisible: () => pricingSection.radioButton('pricingModel')?.value() !== 'one-time'
});
});
summarySection.addRow(row => {
row.addTextPanel('courseSummary', {
computedValue: () => {
const hours = courseSection.integer('courseHours')?.value() || 20;
const modules = courseSection.integer('modules')?.value() || 8;
const level = courseSection.dropdown('courseLevel')?.value() || 'intermediate';
const levelNames: Record<string, string> = {
beginner: 'Beginner', intermediate: 'Intermediate', advanced: 'Advanced', professional: 'Professional'
};
return `${levelNames[level]} course • ${hours} hours • ${modules} modules`;
},
customStyles: { 'font-size': '0.95rem', 'text-align': 'center', 'color': '#475569' }
});
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Prices are suggestions based on market data. Actual pricing should consider your audience, competition, and brand positioning.',
customStyles: { 'font-size': '0.8rem', 'color': '#94a3b8', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Create Course Listing'
});
}