export function personalTrainingForm(form: FormTs) {
form.setTitle(() => '๐ช Personal Training Package Builder');
form.configureCompletionScreen({
type: 'text',
title: () => '๐ Package Ready!',
message: () => 'Your custom training package has been created. Download your PDF to save the details.'
});
// Pricing data
const sessionPrices: Record<string, number> = {
'oneOnOne': 75,
'partner': 50,
'smallGroup': 35
};
const trainerMultipliers: Record<string, number> = {
'certified': 1.0,
'senior': 1.25,
'master': 1.5
};
const packageDiscounts: Record<string, number> = {
'4': 0,
'8': 5,
'12': 10,
'24': 15
};
const addonPrices: Record<string, number> = {
'nutritionBasic': 99,
'nutritionPremium': 199,
'bodyComp': 49,
'programDesign': 149,
'accountability': 79,
'mealPrep': 129
};
// Training Details
const trainingDetails = form.addSubform('trainingDetails', {
title: () => '๐๏ธ Training Details',
mobileBreakpoint: 0
});
trainingDetails.addRow(row => {
row.addRadioButton('trainingType', {
label: 'Training Type',
defaultValue: 'oneOnOne',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'oneOnOne', name: '๐ค 1-on-1 Training ($75/session)' },
{ id: 'partner', name: '๐ฅ Partner Training ($50/person)' },
{ id: 'smallGroup', name: '๐จโ๐ฉโ๐งโ๐ฆ Small Group ($35/person)' }
]
});
});
trainingDetails.addRow(row => {
row.addDropdown('frequency', {
label: 'Sessions Per Week',
defaultValue: '2',
isRequired: true,
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' }
]
}, '1fr');
row.addDropdown('packageLength', {
label: 'Package Length',
defaultValue: '8',
isRequired: true,
options: [
{ id: '4', name: '4 weeks' },
{ id: '8', name: '8 weeks (5% off)' },
{ id: '12', name: '12 weeks (10% off)' },
{ id: '24', name: '24 weeks (15% off)' }
]
}, '1fr');
});
// Trainer Level
const trainerSection = form.addSubform('trainer', {
title: () => '๐ฏ Trainer Selection',
mobileBreakpoint: 0
});
trainerSection.addRow(row => {
row.addRadioButton('trainerLevel', {
label: 'Trainer Experience',
defaultValue: 'certified',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'certified', name: 'โ
Certified Trainer' },
{ id: 'senior', name: 'โญ Senior Trainer (+25%)' },
{ id: 'master', name: '๐ Master Trainer (+50%)' }
]
});
});
// Fitness Goals
const goalsSection = form.addSubform('goals', {
title: () => '๐ฏ Your Fitness Goals',
mobileBreakpoint: 0
});
goalsSection.addRow(row => {
row.addCheckboxList('fitnessGoals', {
label: 'Select Your Goals',
orientation: 'vertical',
options: [
{ id: 'weightLoss', name: '๐ฅ Weight Loss' },
{ id: 'muscleGain', name: '๐ช Muscle Building' },
{ id: 'endurance', name: '๐ Cardio & Endurance' },
{ id: 'flexibility', name: '๐ง Flexibility' },
{ id: 'athletic', name: '๐ Athletic Performance' },
{ id: 'rehab', name: '๐ฉน Injury Recovery' }
]
});
});
// Add-ons
const addonsSection = form.addSubform('addons', {
title: () => 'โจ Program Enhancements',
mobileBreakpoint: 500
});
addonsSection.addRow(row => {
row.addCheckboxList('nutritionAddons', {
label: 'Nutrition Support',
orientation: 'vertical',
options: [
{ id: 'nutritionBasic', name: '๐ฅ Basic Nutrition Guide (+$99)' },
{ id: 'nutritionPremium', name: '๐ฝ๏ธ Premium Coaching (+$199)' },
{ id: 'mealPrep', name: '๐ Meal Prep Guide (+$129)' }
]
}, '1fr');
row.addCheckboxList('supportAddons', {
label: 'Additional Support',
orientation: 'vertical',
options: [
{ id: 'bodyComp', name: '๐ Body Composition (+$49)' },
{ id: 'programDesign', name: '๐ Custom Program (+$149)' },
{ id: 'accountability', name: '๐ฑ Daily Check-ins (+$79)' }
]
}, '1fr');
});
// Calculate functions
const getSessionPrice = () => {
const type = trainingDetails.radioButton('trainingType')?.value() || 'oneOnOne';
return sessionPrices[type] ?? 75;
};
const getTrainerMultiplier = () => {
const level = trainerSection.radioButton('trainerLevel')?.value() || 'certified';
return trainerMultipliers[level] ?? 1.0;
};
const getTotalSessions = () => {
const frequency = parseInt(trainingDetails.dropdown('frequency')?.value() || '2');
const weeks = parseInt(trainingDetails.dropdown('packageLength')?.value() || '8');
return frequency * weeks;
};
const getPackageDiscount = () => {
const weeks = trainingDetails.dropdown('packageLength')?.value() || '8';
return packageDiscounts[weeks] ?? 0;
};
const getAddonsTotal = () => {
let total = 0;
const nutritionAddons = addonsSection.checkboxList('nutritionAddons')?.value() || [];
const supportAddons = addonsSection.checkboxList('supportAddons')?.value() || [];
const allSelected = [...nutritionAddons, ...supportAddons];
for (const addonId of allSelected) {
total += addonPrices[addonId] ?? 0;
}
return total;
};
const getSelectedAddons = () => {
const nutritionAddons = addonsSection.checkboxList('nutritionAddons')?.value() || [];
const supportAddons = addonsSection.checkboxList('supportAddons')?.value() || [];
return [...nutritionAddons, ...supportAddons];
};
const getTrainingSubtotal = () => {
const sessions = getTotalSessions();
const pricePerSession = getSessionPrice() * getTrainerMultiplier();
return Math.round(sessions * pricePerSession);
};
const getDiscountAmount = () => {
const subtotal = getTrainingSubtotal();
const discountPercent = getPackageDiscount();
return Math.round(subtotal * (discountPercent / 100));
};
const getTotalPrice = () => {
const trainingCost = getTrainingSubtotal() - getDiscountAmount();
const addons = getAddonsTotal();
return trainingCost + addons;
};
const getPricePerSession = () => {
const sessions = getTotalSessions();
if (sessions === 0) return 0;
const trainingCost = getTrainingSubtotal() - getDiscountAmount();
return Math.round(trainingCost / sessions);
};
// Quote Summary
const summary = form.addSubform('summary', {
title: () => '๐ฐ Your Training Investment',
isCollapsible: false,
});
summary.addRow(row => {
row.addPriceDisplay('totalPrice', {
label: 'Total Package Price',
computedValue: () => getTotalPrice(),
alignment: 'center',
variant: 'large'
});
});
summary.addRow(row => {
row.addTextPanel('perSession', {
computedValue: () => {
const sessions = getTotalSessions();
const perSession = getPricePerSession();
return `๐ ${sessions} sessions total โข $${perSession}/session effective rate`;
},
customStyles: {
fontSize: '0.95rem',
color: '#059669',
textAlign: 'center',
fontWeight: '500'
}
});
});
summary.addRow(row => {
row.addTextPanel('savings', {
computedValue: () => {
const discount = getDiscountAmount();
if (discount > 0) {
return `๐ You save $${discount} with your package commitment!`;
}
return '๐ก Tip: Longer packages unlock bigger savings!';
},
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
textAlign: 'center'
}
});
});
form.configureSubmitButton({
label: () => 'Get Started Today'
});
// Configure PDF
form.configurePdf('quoteDocument', (pdf) => {
pdf.configure({
filename: 'personal-training-package.pdf',
pageSize: 'A4',
allowUserDownload: true,
downloadButtonLabel: 'Download Your Package',
header: {
title: 'Personal Training Package',
subtitle: 'Custom Fitness Program'
},
footer: {
text: 'Thank you for choosing us for your fitness journey!',
showPageNumbers: true
}
});
pdf.addSection('Training Details', (section) => {
section.addRow((row) => {
const type = trainingDetails.radioButton('trainingType')?.value() || 'oneOnOne';
const typeLabels: Record<string, string> = {
'oneOnOne': '1-on-1 Personal Training',
'partner': 'Partner Training',
'smallGroup': 'Small Group Training'
};
row.addField('Training Type', typeLabels[type] ?? type);
row.addField('Price Per Session', `$${getSessionPrice()}`);
});
section.addRow((row) => {
const frequency = trainingDetails.dropdown('frequency')?.value() || '2';
row.addField('Sessions Per Week', `${frequency}x weekly`);
const weeks = trainingDetails.dropdown('packageLength')?.value() || '8';
row.addField('Package Length', `${weeks} weeks`);
});
section.addRow((row) => {
row.addField('Total Sessions', `${getTotalSessions()} sessions`);
});
});
pdf.addSection('Trainer Selection', (section) => {
section.addRow((row) => {
const level = trainerSection.radioButton('trainerLevel')?.value() || 'certified';
const levelLabels: Record<string, string> = {
'certified': 'Certified Trainer',
'senior': 'Senior Trainer (+25%)',
'master': 'Master Trainer (+50%)'
};
row.addField('Trainer Level', levelLabels[level] ?? level);
});
});
const goals = goalsSection.checkboxList('fitnessGoals')?.value() || [];
if (goals.length > 0) {
pdf.addSection('Fitness Goals', (section) => {
const goalLabels: Record<string, string> = {
'weightLoss': 'Weight Loss & Fat Burning',
'muscleGain': 'Muscle Building & Strength',
'endurance': 'Cardio & Endurance',
'flexibility': 'Flexibility & Mobility',
'athletic': 'Athletic Performance',
'rehab': 'Injury Recovery & Prevention'
};
goals.forEach(goal => {
section.addText(`โข ${goalLabels[goal] ?? goal}`);
});
});
}
const selectedAddons = getSelectedAddons();
if (selectedAddons.length > 0) {
pdf.addSection('Program Enhancements', (section) => {
const addonLabels: Record<string, string> = {
'nutritionBasic': 'Basic Nutrition Guide',
'nutritionPremium': 'Premium Nutrition Coaching',
'mealPrep': 'Meal Prep Guide',
'bodyComp': 'Body Composition Analysis',
'programDesign': 'Custom Program Design',
'accountability': 'Daily Accountability'
};
const tableRows = selectedAddons.map(addonId => [
addonLabels[addonId] ?? addonId,
`$${addonPrices[addonId] ?? 0}`
]);
section.addTable(['Enhancement', 'Price'], tableRows);
});
}
pdf.addSection('Investment Summary', (section) => {
section.addRow((row) => {
row.addField('Training Sessions', `$${getTrainingSubtotal()}`);
});
const discount = getDiscountAmount();
if (discount > 0) {
section.addRow((row) => {
row.addField('Package Discount', `-$${discount}`);
});
}
if (selectedAddons.length > 0) {
section.addRow((row) => {
row.addField('Enhancements', `$${getAddonsTotal()}`);
});
}
section.addDivider();
section.addSpacer(10);
section.addRow((row) => {
row.addField('TOTAL INVESTMENT', `$${getTotalPrice()}`);
});
section.addRow((row) => {
row.addField('Effective Rate', `$${getPricePerSession()}/session`);
});
});
pdf.addSection('What\'s Included', (section) => {
const type = trainingDetails.radioButton('trainingType')?.value() || 'oneOnOne';
const includes: Record<string, string[]> = {
'oneOnOne': [
'Personalized workout programming',
'Form correction and technique coaching',
'Progress tracking and adjustments',
'Flexible scheduling',
'Direct trainer communication'
],
'partner': [
'Semi-private training environment',
'Shared motivation and accountability',
'Customized exercises for both partners',
'Cost-effective personal attention',
'Fun, social workout experience'
],
'smallGroup': [
'Community-driven motivation',
'Structured group workouts',
'Individual attention within group',
'Most affordable option',
'Meet like-minded fitness enthusiasts'
]
};
const items = includes[type] ?? includes['oneOnOne'] ?? [];
items.forEach(item => {
section.addText(`โข ${item}`);
});
});
pdf.addSection('Next Steps', (section) => {
section.addText('1. Schedule your complimentary fitness assessment');
section.addText('2. Meet your trainer and discuss your goals');
section.addText('3. Begin your transformation journey!');
section.addSpacer(10);
section.addText('Questions? Contact us at hello@personaltraining.com');
});
});
}