export function gymMembershipCalculator(form: FormTs) {
// Monthly rates by membership tier
const tierRates: Record<string, number> = {
'basic': 29.99,
'standard': 49.99,
'premium': 79.99,
'vip': 129.99
};
// Contract length discounts
const contractDiscounts: Record<string, number> = {
'monthly': 0,
'6-month': 10,
'12-month': 20,
'24-month': 25
};
// Initiation fees by tier
const initiationFees: Record<string, number> = {
'basic': 49,
'standard': 99,
'premium': 149,
'vip': 199
};
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Membership Cost Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Membership Type Section
const membershipSection = form.addSubform('membershipType', { title: '๐๏ธ Membership Options' });
membershipSection.addRow(row => {
row.addRadioButton('tier', {
label: 'Membership Level',
options: [
{ id: 'basic', name: 'Basic - Gym floor access, cardio & weights ($29.99/mo)' },
{ id: 'standard', name: 'Standard - Basic + Group classes, locker room ($49.99/mo)' },
{ id: 'premium', name: 'Premium - Standard + Pool, sauna, towel service ($79.99/mo)' },
{ id: 'vip', name: 'VIP - All Access + Guest passes, priority booking ($129.99/mo)' }
],
defaultValue: 'standard',
orientation: 'vertical',
isRequired: true
});
});
membershipSection.addRow(row => {
row.addDropdown('memberType', {
label: 'Membership Type',
options: [
{ id: 'individual', name: 'Individual' },
{ id: 'couple', name: 'Couple (+75% for 2nd member)' },
{ id: 'family', name: 'Family (up to 4 members, +50% each additional)' },
{ id: 'student', name: 'Student (-20%, ID required)' },
{ id: 'senior', name: 'Senior 65+ (-15%)' },
{ id: 'corporate', name: 'Corporate (-10%, employer verification)' }
],
defaultValue: 'individual',
isRequired: true
}, '1fr');
row.addInteger('familyMembers', {
label: 'Additional Family Members',
min: 0,
max: 3,
defaultValue: 0,
isVisible: () => membershipSection.dropdown('memberType')?.value() === 'family'
}, '1fr');
});
membershipSection.addRow(row => {
row.addRadioButton('contract', {
label: 'Contract Length',
options: [
{ id: 'monthly', name: 'Month-to-Month (No commitment)' },
{ id: '6-month', name: '6-Month Contract (-10%)' },
{ id: '12-month', name: '12-Month Contract (-20%)' },
{ id: '24-month', name: '24-Month Contract (-25%)' }
],
defaultValue: '12-month',
orientation: 'vertical'
});
});
// Add-ons Section
const addonsSection = form.addSubform('addons', { title: 'โจ Add-on Services' });
addonsSection.addRow(row => {
row.addCheckbox('personalTraining', {
label: 'Personal Training Pack (4 sessions/mo, +$200)',
defaultValue: false
}, '1fr');
row.addCheckbox('nutritionCoaching', {
label: 'Nutrition Coaching (+$75/mo)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('lockerRental', {
label: 'Premium Locker Rental (+$15/mo)',
defaultValue: false
}, '1fr');
row.addCheckbox('parking', {
label: 'Reserved Parking (+$25/mo)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('kidsClub', {
label: "Kids' Club Childcare (+$50/mo)",
defaultValue: false
}, '1fr');
row.addCheckbox('tanning', {
label: 'Unlimited Tanning (+$30/mo)',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('massage', {
label: 'Monthly Massage (1 session, +$60/mo)',
defaultValue: false
}, '1fr');
row.addCheckbox('appPremium', {
label: 'Premium App Features (+$10/mo)',
defaultValue: false
}, '1fr');
});
// Promotions Section
const promoSection = form.addSubform('promotions', { title: '๐ Promotions' });
promoSection.addRow(row => {
row.addCheckbox('waiveInitiation', {
label: 'Waive initiation fee (New Year Special)',
defaultValue: false
}, '1fr');
row.addCheckbox('firstMonthFree', {
label: 'First month free (12+ month contracts)',
defaultValue: false,
isVisible: () => {
const contract = membershipSection.radioButton('contract')?.value();
return contract === '12-month' || contract === '24-month';
}
}, '1fr');
});
promoSection.addRow(row => {
row.addCheckbox('referralDiscount', {
label: 'Referral discount (-$10/mo for 3 months)',
defaultValue: false
}, '1fr');
row.addTextbox('promoCode', {
label: 'Promo Code',
placeholder: 'Enter code (optional)'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Price Summary Section
const summarySection = form.addSubform('summary', { title: '๐ฐ Price Summary', isCollapsible: false });
const getMemberTypeMultiplier = () => {
const memberType = membershipSection.dropdown('memberType')?.value() || 'individual';
const familyMembers = membershipSection.integer('familyMembers')?.value() || 0;
const multipliers: Record<string, number> = {
'individual': 1.0,
'couple': 1.75,
'family': 1 + (familyMembers * 0.5),
'student': 0.8,
'senior': 0.85,
'corporate': 0.9
};
return multipliers[memberType] || 1;
};
const getMonthlyBase = () => {
const tier = membershipSection.radioButton('tier')?.value() || 'standard';
const contract = membershipSection.radioButton('contract')?.value() || '12-month';
const baseRate = tierRates[tier] || 49.99;
const discount = contractDiscounts[contract] || 0;
const memberMultiplier = getMemberTypeMultiplier();
return baseRate * memberMultiplier * (1 - discount / 100);
};
const getAddonsTotal = () => {
let total = 0;
if (addonsSection.checkbox('personalTraining')?.value()) total += 200;
if (addonsSection.checkbox('nutritionCoaching')?.value()) total += 75;
if (addonsSection.checkbox('lockerRental')?.value()) total += 15;
if (addonsSection.checkbox('parking')?.value()) total += 25;
if (addonsSection.checkbox('kidsClub')?.value()) total += 50;
if (addonsSection.checkbox('tanning')?.value()) total += 30;
if (addonsSection.checkbox('massage')?.value()) total += 60;
if (addonsSection.checkbox('appPremium')?.value()) total += 10;
return total;
};
summarySection.addRow(row => {
row.addPriceDisplay('monthlyBase', {
label: 'Monthly Membership',
computedValue: () => Math.round(getMonthlyBase() * 100) / 100,
variant: 'default',
suffix: '/mo'
}, '1fr');
row.addPriceDisplay('monthlyAddons', {
label: 'Monthly Add-ons',
computedValue: getAddonsTotal,
variant: 'default',
prefix: '+',
suffix: '/mo'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('monthlyTotal', {
label: 'Total Monthly Cost',
computedValue: () => {
let monthly = getMonthlyBase() + getAddonsTotal();
// Apply referral discount
if (promoSection.checkbox('referralDiscount')?.value()) {
monthly -= 10;
}
return Math.round(monthly * 100) / 100;
},
variant: 'large',
suffix: '/mo'
});
});
summarySection.addSpacer({ showLine: true, lineStyle: 'dashed', lineColor: '#e2e8f0' });
summarySection.addRow(row => {
row.addPriceDisplay('initiationFee', {
label: 'Initiation Fee',
computedValue: () => {
if (promoSection.checkbox('waiveInitiation')?.value()) return 0;
const tier = membershipSection.radioButton('tier')?.value() || 'standard';
return initiationFees[tier] || 99;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('annualCost', {
label: 'Annual Investment',
computedValue: () => {
let monthly = getMonthlyBase() + getAddonsTotal();
if (promoSection.checkbox('referralDiscount')?.value()) {
// Discount applies for 3 months only
monthly = (monthly - 10) * 3 + monthly * 9;
monthly = monthly / 12;
}
let annual = monthly * 12;
// Add initiation fee
if (!promoSection.checkbox('waiveInitiation')?.value()) {
const tier = membershipSection.radioButton('tier')?.value() || 'standard';
annual += initiationFees[tier] || 99;
}
// Subtract first month if free
if (promoSection.checkbox('firstMonthFree')?.value()) {
annual -= monthly;
}
return Math.round(annual * 100) / 100;
},
variant: 'default',
suffix: '/year'
}, '1fr');
});
summarySection.addRow(row => {
row.addTextPanel('savings', {
computedValue: () => {
const contract = membershipSection.radioButton('contract')?.value() || '12-month';
const tier = membershipSection.radioButton('tier')?.value() || 'standard';
const baseRate = tierRates[tier] || 49.99;
const memberMultiplier = getMemberTypeMultiplier();
const monthlyAtFull = baseRate * memberMultiplier * 12;
const discount = contractDiscounts[contract] || 0;
if (discount === 0) return 'Switch to an annual plan to save more!';
const savings = monthlyAtFull * (discount / 100);
return `You save $${Math.round(savings)} per year with your ${contract.replace('-', ' ')} contract!`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#059669', 'font-weight': '500' }
});
});
summarySection.addRow(row => {
row.addTextPanel('perks', {
computedValue: () => {
const tier = membershipSection.radioButton('tier')?.value() || 'standard';
const perks: Record<string, string> = {
'basic': 'Includes: 24/7 gym access, cardio & weight equipment, free WiFi',
'standard': 'Includes: All Basic perks + unlimited group classes, locker room access',
'premium': 'Includes: All Standard perks + pool, sauna, steam room, towel service',
'vip': 'Includes: All Premium perks + 2 guest passes/mo, priority class booking, spa discounts'
};
return perks[tier] || '';
},
customStyles: { 'font-size': '0.85rem', 'color': '#475569' }
});
});
const finalSection = form.addSubform('final', {
title: '๐งพ Summary',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('monthlyTotalFinal', {
label: 'Monthly Cost',
computedValue: () => {
let monthly = getMonthlyBase() + getAddonsTotal();
if (promoSection.checkbox('referralDiscount')?.value()) {
monthly -= 10;
}
return Math.round(monthly * 100) / 100;
},
variant: 'default',
suffix: '/mo'
}, '1fr');
row.addPriceDisplay('dueToday', {
label: 'Due Today',
computedValue: () => {
let dueToday = 0;
// Initiation fee
if (!promoSection.checkbox('waiveInitiation')?.value()) {
const tier = membershipSection.radioButton('tier')?.value() || 'standard';
dueToday += initiationFees[tier] || 99;
}
// First month (unless free)
if (!promoSection.checkbox('firstMonthFree')?.value()) {
let monthly = getMonthlyBase() + getAddonsTotal();
if (promoSection.checkbox('referralDiscount')?.value()) monthly -= 10;
dueToday += monthly;
}
return Math.round(dueToday * 100) / 100;
},
variant: 'large'
}, '1fr');
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Membership subject to facility rules and availability. Contract cancellation terms apply.',
customStyles: { 'font-size': '0.85rem', 'color': '#94a3b8', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Start Membership'
});
}