export function sportsCoachingCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Sports Coaching Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Sport Selection Section
const sportSection = form.addSubform('sport', { title: '⚽ Sport Selection' });
sportSection.addRow(row => {
row.addDropdown('sport', {
label: 'Sport',
options: [
{ id: 'soccer', name: 'Soccer/Football' },
{ id: 'basketball', name: 'Basketball' },
{ id: 'tennis', name: 'Tennis' },
{ id: 'golf', name: 'Golf' },
{ id: 'swimming', name: 'Swimming' },
{ id: 'baseball', name: 'Baseball/Softball' },
{ id: 'volleyball', name: 'Volleyball' },
{ id: 'hockey', name: 'Hockey' },
{ id: 'gymnastics', name: 'Gymnastics' },
{ id: 'martial-arts', name: 'Martial Arts' },
{ id: 'track', name: 'Track & Field' },
{ id: 'skiing', name: 'Skiing/Snowboarding' },
{ id: 'other', name: 'Other Sport' }
],
defaultValue: 'soccer',
isRequired: true
}, '1fr');
row.addDropdown('skillLevel', {
label: 'Current Skill Level',
options: [
{ id: 'beginner', name: 'Beginner' },
{ id: 'intermediate', name: 'Intermediate' },
{ id: 'advanced', name: 'Advanced' },
{ id: 'competitive', name: 'Competitive/Travel' },
{ id: 'elite', name: 'Elite/Pre-Professional' }
],
defaultValue: 'beginner',
isRequired: true
}, '1fr');
});
sportSection.addRow(row => {
row.addDropdown('ageGroup', {
label: 'Age Group',
options: [
{ id: 'youth', name: 'Youth (5-10)' },
{ id: 'preteen', name: 'Pre-Teen (11-13)' },
{ id: 'teen', name: 'Teen (14-17)' },
{ id: 'college', name: 'College (18-22)' },
{ id: 'adult', name: 'Adult (23+)' }
],
defaultValue: 'youth',
isRequired: true
}, '1fr');
row.addDropdown('goals', {
label: 'Training Goal',
options: [
{ id: 'recreation', name: 'Recreation/Fun' },
{ id: 'skill-building', name: 'Skill Development' },
{ id: 'team-prep', name: 'Team/Tryout Prep' },
{ id: 'competition', name: 'Competition Prep' },
{ id: 'college-prep', name: 'College Recruitment' },
{ id: 'professional', name: 'Professional Development' }
],
defaultValue: 'skill-building'
}, '1fr');
});
// Coaching Format Section
const formatSection = form.addSubform('format', { title: '👥 Coaching Format' });
formatSection.addRow(row => {
row.addRadioButton('coachingType', {
label: 'Coaching Type',
options: [
{ id: 'private', name: 'Private (1-on-1)' },
{ id: 'semi-private', name: 'Semi-Private (2-3)' },
{ id: 'small-group', name: 'Small Group (4-8)' },
{ id: 'team', name: 'Team Training' },
{ id: 'camp', name: 'Camp/Clinic' }
],
defaultValue: 'private',
isRequired: true
});
});
formatSection.addRow(row => {
row.addInteger('participants', {
label: 'Number of Participants',
min: 2,
max: 30,
defaultValue: 2,
isVisible: () => ['semi-private', 'small-group', 'team'].includes(formatSection.radioButton('coachingType')?.value() || ''),
tooltip: 'Cost is split among participants'
}, '1fr');
row.addDropdown('coachLevel', {
label: 'Coach Experience',
options: [
{ id: 'assistant', name: 'Assistant Coach' },
{ id: 'certified', name: 'Certified Coach' },
{ id: 'experienced', name: 'Experienced (5+ years)' },
{ id: 'elite', name: 'Elite/Former Pro' },
{ id: 'professional', name: 'Professional Coach' }
],
defaultValue: 'certified'
}, '1fr');
});
// Session Details Section
const sessionSection = form.addSubform('session', { title: '⏰ Session Details' });
sessionSection.addRow(row => {
row.addDropdown('sessionLength', {
label: 'Session Length',
options: [
{ id: '30', name: '30 Minutes' },
{ id: '45', name: '45 Minutes' },
{ id: '60', name: '1 Hour' },
{ id: '90', name: '1.5 Hours' },
{ id: '120', name: '2 Hours' }
],
defaultValue: '60',
isRequired: true
}, '1fr');
row.addDropdown('frequency', {
label: 'Sessions per Week',
options: [
{ id: '1', name: '1x per week' },
{ id: '2', name: '2x per week' },
{ id: '3', name: '3x per week' },
{ id: '4', name: '4x per week' },
{ id: '5', name: '5x per week' }
],
defaultValue: '1'
}, '1fr');
});
sessionSection.addRow(row => {
row.addDropdown('packageType', {
label: 'Package Type',
options: [
{ id: 'single', name: 'Single Session' },
{ id: '5-pack', name: '5 Session Pack (5% off)' },
{ id: '10-pack', name: '10 Session Pack (10% off)' },
{ id: '20-pack', name: '20 Session Pack (15% off)' },
{ id: 'monthly', name: 'Monthly Unlimited' }
],
defaultValue: 'single'
}, '1fr');
row.addDropdown('location', {
label: 'Training Location',
options: [
{ id: 'facility', name: 'Training Facility' },
{ id: 'school', name: 'School/Park' },
{ id: 'home', name: 'At Your Location' },
{ id: 'virtual', name: 'Virtual/Online' }
],
defaultValue: 'facility'
}, '1fr');
});
// Additional Services Section
const servicesSection = form.addSubform('services', { title: '✨ Additional Services' });
servicesSection.addRow(row => {
row.addCheckbox('videoAnalysis', {
label: 'Video Analysis',
defaultValue: false,
tooltip: 'Film review and technique analysis'
}, '1fr');
row.addCheckbox('strengthConditioning', {
label: 'Strength & Conditioning',
defaultValue: false,
tooltip: 'Sport-specific fitness training'
}, '1fr');
});
servicesSection.addRow(row => {
row.addCheckbox('mentalCoaching', {
label: 'Mental Performance Coaching',
defaultValue: false,
tooltip: 'Sports psychology and mindset training'
}, '1fr');
row.addCheckbox('nutritionGuidance', {
label: 'Nutrition Guidance',
defaultValue: false,
tooltip: 'Sport-specific nutrition advice'
}, '1fr');
});
servicesSection.addRow(row => {
row.addCheckbox('gameAnalysis', {
label: 'Game/Competition Analysis',
defaultValue: false,
tooltip: 'Review of game footage and strategy'
}, '1fr');
row.addCheckbox('equipmentProvided', {
label: 'Equipment Provided',
defaultValue: false,
tooltip: 'Coach provides training equipment'
}, '1fr');
});
// Camp/Clinic Options (conditional)
const campSection = form.addSubform('camp', {
title: '🏕️ Camp/Clinic Details',
isVisible: () => formatSection.radioButton('coachingType')?.value() === 'camp'
});
campSection.addRow(row => {
row.addDropdown('campType', {
label: 'Camp Type',
options: [
{ id: 'half-day', name: 'Half Day (3-4 hours)' },
{ id: 'full-day', name: 'Full Day (6-8 hours)' },
{ id: 'overnight', name: 'Overnight Camp' }
],
defaultValue: 'half-day'
}, '1fr');
row.addInteger('campDays', {
label: 'Number of Days',
min: 1,
max: 14,
defaultValue: 5
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Results Section
const resultsSection = form.addSubform('results', { title: '📊 Pricing Breakdown', isCollapsible: false });
const calculatePricing = () => {
const sport = sportSection.dropdown('sport')?.value() || 'soccer';
const skillLevel = sportSection.dropdown('skillLevel')?.value() || 'beginner';
const coachingType = formatSection.radioButton('coachingType')?.value() || 'private';
const coachLevel = formatSection.dropdown('coachLevel')?.value() || 'certified';
const sessionLength = parseInt(sessionSection.dropdown('sessionLength')?.value() || '60');
const frequency = parseInt(sessionSection.dropdown('frequency')?.value() || '1');
const packageType = sessionSection.dropdown('packageType')?.value() || 'single';
const location = sessionSection.dropdown('location')?.value() || 'facility';
const participants = formatSection.integer('participants')?.value() || 2;
// Base hourly rate by coach level
const coachRates = {
'assistant': 35,
'certified': 55,
'experienced': 80,
'elite': 120,
'professional': 175
};
let baseRate = coachRates[coachLevel];
// Sport premium
const sportPremiums = {
'golf': 1.4,
'tennis': 1.2,
'skiing': 1.5,
'gymnastics': 1.3,
'swimming': 1.1,
'hockey': 1.2,
'soccer': 1.0,
'basketball': 1.0,
'baseball': 1.0,
'volleyball': 1.0,
'martial-arts': 1.1,
'track': 1.0,
'other': 1.0
};
baseRate *= sportPremiums[sport];
// Skill level adjustment
const skillMultipliers = {
'beginner': 1.0,
'intermediate': 1.1,
'advanced': 1.2,
'competitive': 1.3,
'elite': 1.5
};
baseRate *= skillMultipliers[skillLevel];
// Coaching type adjustment
let sessionRate = baseRate;
if (coachingType === 'semi-private') {
sessionRate = (baseRate * 1.4) / participants; // Per person
} else if (coachingType === 'small-group') {
sessionRate = (baseRate * 2.0) / participants; // Per person
} else if (coachingType === 'team') {
sessionRate = baseRate * 2.5 / Math.max(participants, 10); // Team rate per person
}
// Session length adjustment
const lengthMultiplier = sessionLength / 60;
let perSessionCost = sessionRate * lengthMultiplier;
// Location adjustment
if (location === 'home') perSessionCost += 25;
if (location === 'virtual') perSessionCost *= 0.8;
// Additional services
let addOnsCost = 0;
if (servicesSection.checkbox('videoAnalysis')?.value()) addOnsCost += 30;
if (servicesSection.checkbox('strengthConditioning')?.value()) addOnsCost += 40;
if (servicesSection.checkbox('mentalCoaching')?.value()) addOnsCost += 50;
if (servicesSection.checkbox('nutritionGuidance')?.value()) addOnsCost += 25;
if (servicesSection.checkbox('gameAnalysis')?.value()) addOnsCost += 35;
if (servicesSection.checkbox('equipmentProvided')?.value()) addOnsCost += 15;
perSessionCost += addOnsCost;
// Camp pricing
if (coachingType === 'camp') {
const campType = campSection.dropdown('campType')?.value() || 'half-day';
const campDays = campSection.integer('campDays')?.value() || 5;
const campDailyRates = {
'half-day': 85,
'full-day': 150,
'overnight': 250
};
perSessionCost = campDailyRates[campType] * campDays;
}
// Package discounts
const packageDiscounts = {
'single': 0,
'5-pack': 0.05,
'10-pack': 0.10,
'20-pack': 0.15,
'monthly': 0.20
};
const discount = packageDiscounts[packageType];
const discountedRate = perSessionCost * (1 - discount);
// Package quantities
const packageQuantities = {
'single': 1,
'5-pack': 5,
'10-pack': 10,
'20-pack': 20,
'monthly': frequency * 4
};
const sessions = packageQuantities[packageType];
const packageTotal = discountedRate * sessions;
const weeklyTotal = discountedRate * frequency;
const monthlyTotal = weeklyTotal * 4;
return {
perSession: Math.round(perSessionCost),
discountedSession: Math.round(discountedRate),
packageTotal: Math.round(packageTotal),
weeklyTotal: Math.round(weeklyTotal),
monthlyTotal: Math.round(monthlyTotal),
discount: discount * 100,
sessions,
addOnsCost: Math.round(addOnsCost)
};
};
resultsSection.addRow(row => {
row.addPriceDisplay('perSession', {
label: 'Per Session (Base)',
computedValue: () => calculatePricing().perSession,
variant: 'default'
}, '1fr');
row.addPriceDisplay('discountedSession', {
label: 'Per Session (After Discount)',
computedValue: () => calculatePricing().discountedSession,
variant: 'success',
isVisible: () => calculatePricing().discount > 0
}, '1fr');
});
resultsSection.addRow(row => {
row.addTextPanel('discountInfo', {
computedValue: () => {
const discount = calculatePricing().discount;
return discount > 0 ? `${discount}% package discount applied` : 'No package discount';
},
customStyles: { 'font-size': '0.9rem', 'color': '#059669', 'text-align': 'center' }
});
});
resultsSection.addRow(row => {
row.addPriceDisplay('addOns', {
label: 'Add-On Services (per session)',
computedValue: () => calculatePricing().addOnsCost,
variant: 'default',
isVisible: () => calculatePricing().addOnsCost > 0
});
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '🏆 Investment Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addPriceDisplay('packageTotal', {
label: () => `Package Total (${calculatePricing().sessions} sessions)`,
computedValue: () => calculatePricing().packageTotal,
variant: 'large'
}, '1fr');
row.addPriceDisplay('monthlyTotal', {
label: 'Monthly Estimate',
computedValue: () => calculatePricing().monthlyTotal,
variant: 'success'
}, '1fr');
});
summarySection.addRow(row => {
row.addTextPanel('note', {
computedValue: () => 'Pricing varies by coach availability and specific program requirements.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Find a Coach'
});
}