export function coworkingSpaceCalculator(form: FormTs) {
// Membership base prices (monthly)
const membershipPrices: Record<string, number> = {
'hot-desk': 199,
'dedicated-desk': 399,
'private-office-1': 799,
'private-office-2': 1299,
'private-office-4': 2199,
'private-office-6': 2999
};
// Location multipliers
const locationMultipliers: Record<string, number> = {
'downtown': 1.3,
'business-district': 1.2,
'suburban': 1.0,
'tech-hub': 1.25
};
// Commitment discounts
const commitmentDiscounts: Record<string, number> = {
'monthly': 0,
'3-month': 0.05,
'6-month': 0.10,
'12-month': 0.20
};
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Coworking Space Membership Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Membership Type Section
const membershipSection = form.addSubform('membership', { title: '🏢 Membership Type' });
membershipSection.addRow(row => {
row.addRadioButton('membershipType', {
label: 'Select Your Workspace',
options: [
{ id: 'hot-desk', name: 'Hot Desk - $199/mo (Any available desk)' },
{ id: 'dedicated-desk', name: 'Dedicated Desk - $399/mo (Your own desk)' },
{ id: 'private-office-1', name: 'Private Office (1 person) - $799/mo' },
{ id: 'private-office-2', name: 'Private Office (2 people) - $1,299/mo' },
{ id: 'private-office-4', name: 'Private Office (4 people) - $2,199/mo' },
{ id: 'private-office-6', name: 'Private Office (6 people) - $2,999/mo' }
],
defaultValue: 'hot-desk',
orientation: 'vertical',
isRequired: true
});
});
membershipSection.addRow(row => {
row.addDropdown('location', {
label: 'Location',
options: [
{ id: 'downtown', name: 'Downtown (+30%)' },
{ id: 'business-district', name: 'Business District (+20%)' },
{ id: 'tech-hub', name: 'Tech Hub (+25%)' },
{ id: 'suburban', name: 'Suburban (Standard)' }
],
defaultValue: 'suburban',
isRequired: true
}, '1fr');
row.addInteger('teamSize', {
label: 'Team Members',
min: 1,
max: 20,
defaultValue: 1,
isVisible: () => {
const type = membershipSection.radioButton('membershipType')?.value();
return type === 'hot-desk' || type === 'dedicated-desk';
}
}, '1fr');
});
// Commitment Section
const commitmentSection = form.addSubform('commitment', { title: '📅 Commitment Term' });
commitmentSection.addRow(row => {
row.addRadioButton('term', {
label: 'Membership Term',
options: [
{ id: 'monthly', name: 'Month-to-Month' },
{ id: '3-month', name: '3 Months (-5%)' },
{ id: '6-month', name: '6 Months (-10%)' },
{ id: '12-month', name: '12 Months (-20%)' }
],
defaultValue: 'monthly',
orientation: 'vertical',
isRequired: true
});
});
// Access & Amenities Section
const amenitiesSection = form.addSubform('amenities', { title: '✨ Access & Amenities' });
amenitiesSection.addRow(row => {
row.addRadioButton('accessLevel', {
label: 'Access Hours',
options: [
{ id: 'business', name: 'Business Hours (9am-6pm, Mon-Fri)' },
{ id: 'extended', name: 'Extended Hours (7am-10pm) +$50/mo' },
{ id: '24-7', name: '24/7 Access +$100/mo' }
],
defaultValue: 'business',
orientation: 'vertical',
isRequired: true
});
});
amenitiesSection.addRow(row => {
row.addCheckbox('meetingRoom', {
label: 'Meeting Room Credits (10 hrs/mo) +$75',
defaultValue: false
}, '1fr');
row.addCheckbox('phoneRoom', {
label: 'Phone Booth Priority Access +$30',
defaultValue: false
}, '1fr');
});
amenitiesSection.addRow(row => {
row.addCheckbox('printing', {
label: 'Unlimited Printing +$40/mo',
defaultValue: false
}, '1fr');
row.addCheckbox('locker', {
label: 'Personal Locker +$25/mo',
defaultValue: false
}, '1fr');
});
amenitiesSection.addRow(row => {
row.addCheckbox('mailService', {
label: 'Business Mail Service +$35/mo',
defaultValue: false
}, '1fr');
row.addCheckbox('parking', {
label: 'Reserved Parking +$150/mo',
defaultValue: false
}, '1fr');
});
// Additional Services Section
const servicesSection = form.addSubform('services', { title: '🎯 Business Services' });
servicesSection.addRow(row => {
row.addCheckbox('virtualAddress', {
label: 'Virtual Business Address +$50/mo',
defaultValue: false
}, '1fr');
row.addCheckbox('reception', {
label: 'Reception Services +$100/mo',
defaultValue: false
}, '1fr');
});
servicesSection.addRow(row => {
row.addCheckbox('itSupport', {
label: 'IT Support +$75/mo',
defaultValue: false
}, '1fr');
row.addCheckbox('networkAccess', {
label: 'Community Network Access +$25/mo',
defaultValue: false
}, '1fr');
});
servicesSection.addRow(row => {
row.addInteger('guestPasses', {
label: 'Guest Day Passes (per month)',
min: 0,
max: 20,
defaultValue: 0,
placeholder: '0'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Price Summary Section
const summarySection = form.addSubform('summary', { title: '💰 Cost Breakdown', isCollapsible: false });
summarySection.addRow(row => {
row.addPriceDisplay('basePrice', {
label: 'Base Membership',
computedValue: () => {
const membershipType = membershipSection.radioButton('membershipType')?.value() || 'hot-desk';
const location = membershipSection.dropdown('location')?.value() || 'suburban';
const teamSize = membershipSection.integer('teamSize')?.value() || 1;
const basePrice = membershipPrices[membershipType] || 199;
const locationMultiplier = locationMultipliers[location] || 1.0;
const isHotOrDedicated = membershipType === 'hot-desk' || membershipType === 'dedicated-desk';
const multiplier = isHotOrDedicated ? teamSize : 1;
return Math.round(basePrice * locationMultiplier * multiplier);
},
variant: 'default',
suffix: '/mo'
}, '1fr');
row.addPriceDisplay('accessFee', {
label: 'Access Level',
computedValue: () => {
const accessLevel = amenitiesSection.radioButton('accessLevel')?.value() || 'business';
const accessPrices: Record<string, number> = {
'business': 0,
'extended': 50,
'24-7': 100
};
return accessPrices[accessLevel] || 0;
},
variant: 'default',
prefix: '+',
suffix: '/mo'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('amenities', {
label: 'Amenities',
computedValue: () => {
let total = 0;
if (amenitiesSection.checkbox('meetingRoom')?.value()) total += 75;
if (amenitiesSection.checkbox('phoneRoom')?.value()) total += 30;
if (amenitiesSection.checkbox('printing')?.value()) total += 40;
if (amenitiesSection.checkbox('locker')?.value()) total += 25;
if (amenitiesSection.checkbox('mailService')?.value()) total += 35;
if (amenitiesSection.checkbox('parking')?.value()) total += 150;
return total;
},
variant: 'default',
prefix: '+',
suffix: '/mo'
}, '1fr');
row.addPriceDisplay('services', {
label: 'Business Services',
computedValue: () => {
let total = 0;
if (servicesSection.checkbox('virtualAddress')?.value()) total += 50;
if (servicesSection.checkbox('reception')?.value()) total += 100;
if (servicesSection.checkbox('itSupport')?.value()) total += 75;
if (servicesSection.checkbox('networkAccess')?.value()) total += 25;
const guestPasses = servicesSection.integer('guestPasses')?.value() || 0;
total += guestPasses * 25;
return total;
},
variant: 'default',
prefix: '+',
suffix: '/mo'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('termDiscount', {
label: 'Term Discount',
computedValue: () => {
const term = commitmentSection.radioButton('term')?.value() || 'monthly';
if (term === 'monthly') return 0;
const membershipType = membershipSection.radioButton('membershipType')?.value() || 'hot-desk';
const location = membershipSection.dropdown('location')?.value() || 'suburban';
const teamSize = membershipSection.integer('teamSize')?.value() || 1;
const accessLevel = amenitiesSection.radioButton('accessLevel')?.value() || 'business';
const basePrice = membershipPrices[membershipType] || 199;
const locationMultiplier = locationMultipliers[location] || 1.0;
const isHotOrDedicated = membershipType === 'hot-desk' || membershipType === 'dedicated-desk';
const teamMultiplier = isHotOrDedicated ? teamSize : 1;
const membershipTotal = basePrice * locationMultiplier * teamMultiplier;
const accessPrices: Record<string, number> = { 'business': 0, 'extended': 50, '24-7': 100 };
const accessFee = accessPrices[accessLevel] || 0;
let amenitiesTotal = 0;
if (amenitiesSection.checkbox('meetingRoom')?.value()) amenitiesTotal += 75;
if (amenitiesSection.checkbox('phoneRoom')?.value()) amenitiesTotal += 30;
if (amenitiesSection.checkbox('printing')?.value()) amenitiesTotal += 40;
if (amenitiesSection.checkbox('locker')?.value()) amenitiesTotal += 25;
if (amenitiesSection.checkbox('mailService')?.value()) amenitiesTotal += 35;
if (amenitiesSection.checkbox('parking')?.value()) amenitiesTotal += 150;
let servicesTotal = 0;
if (servicesSection.checkbox('virtualAddress')?.value()) servicesTotal += 50;
if (servicesSection.checkbox('reception')?.value()) servicesTotal += 100;
if (servicesSection.checkbox('itSupport')?.value()) servicesTotal += 75;
if (servicesSection.checkbox('networkAccess')?.value()) servicesTotal += 25;
const guestPasses = servicesSection.integer('guestPasses')?.value() || 0;
servicesTotal += guestPasses * 25;
const monthlyTotal = membershipTotal + accessFee + amenitiesTotal + servicesTotal;
const discount = commitmentDiscounts[term] || 0;
return -Math.round(monthlyTotal * discount);
},
variant: 'success',
prefix: '',
suffix: '/mo'
}, '1fr');
});
const finalSection = form.addSubform('final', {
title: '🏢 Your Membership',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('monthlyTotal', {
label: 'Monthly Total',
computedValue: () => {
const membershipType = membershipSection.radioButton('membershipType')?.value() || 'hot-desk';
const location = membershipSection.dropdown('location')?.value() || 'suburban';
const teamSize = membershipSection.integer('teamSize')?.value() || 1;
const term = commitmentSection.radioButton('term')?.value() || 'monthly';
const accessLevel = amenitiesSection.radioButton('accessLevel')?.value() || 'business';
const basePrice = membershipPrices[membershipType] || 199;
const locationMultiplier = locationMultipliers[location] || 1.0;
const isHotOrDedicated = membershipType === 'hot-desk' || membershipType === 'dedicated-desk';
const teamMultiplier = isHotOrDedicated ? teamSize : 1;
const membershipTotal = basePrice * locationMultiplier * teamMultiplier;
const accessPrices: Record<string, number> = { 'business': 0, 'extended': 50, '24-7': 100 };
const accessFee = accessPrices[accessLevel] || 0;
let amenitiesTotal = 0;
if (amenitiesSection.checkbox('meetingRoom')?.value()) amenitiesTotal += 75;
if (amenitiesSection.checkbox('phoneRoom')?.value()) amenitiesTotal += 30;
if (amenitiesSection.checkbox('printing')?.value()) amenitiesTotal += 40;
if (amenitiesSection.checkbox('locker')?.value()) amenitiesTotal += 25;
if (amenitiesSection.checkbox('mailService')?.value()) amenitiesTotal += 35;
if (amenitiesSection.checkbox('parking')?.value()) amenitiesTotal += 150;
let servicesTotal = 0;
if (servicesSection.checkbox('virtualAddress')?.value()) servicesTotal += 50;
if (servicesSection.checkbox('reception')?.value()) servicesTotal += 100;
if (servicesSection.checkbox('itSupport')?.value()) servicesTotal += 75;
if (servicesSection.checkbox('networkAccess')?.value()) servicesTotal += 25;
const guestPasses = servicesSection.integer('guestPasses')?.value() || 0;
servicesTotal += guestPasses * 25;
const monthlyTotal = membershipTotal + accessFee + amenitiesTotal + servicesTotal;
const discount = commitmentDiscounts[term] || 0;
return Math.round(monthlyTotal * (1 - discount));
},
variant: 'large',
suffix: '/mo'
}, '1fr');
row.addPriceDisplay('perPerson', {
label: 'Per Person',
computedValue: () => {
const membershipType = membershipSection.radioButton('membershipType')?.value() || 'hot-desk';
const location = membershipSection.dropdown('location')?.value() || 'suburban';
const teamSize = membershipSection.integer('teamSize')?.value() || 1;
const term = commitmentSection.radioButton('term')?.value() || 'monthly';
const accessLevel = amenitiesSection.radioButton('accessLevel')?.value() || 'business';
const basePrice = membershipPrices[membershipType] || 199;
const locationMultiplier = locationMultipliers[location] || 1.0;
const isHotOrDedicated = membershipType === 'hot-desk' || membershipType === 'dedicated-desk';
const teamMultiplier = isHotOrDedicated ? teamSize : 1;
const membershipTotal = basePrice * locationMultiplier * teamMultiplier;
const accessPrices: Record<string, number> = { 'business': 0, 'extended': 50, '24-7': 100 };
const accessFee = accessPrices[accessLevel] || 0;
let amenitiesTotal = 0;
if (amenitiesSection.checkbox('meetingRoom')?.value()) amenitiesTotal += 75;
if (amenitiesSection.checkbox('phoneRoom')?.value()) amenitiesTotal += 30;
if (amenitiesSection.checkbox('printing')?.value()) amenitiesTotal += 40;
if (amenitiesSection.checkbox('locker')?.value()) amenitiesTotal += 25;
if (amenitiesSection.checkbox('mailService')?.value()) amenitiesTotal += 35;
if (amenitiesSection.checkbox('parking')?.value()) amenitiesTotal += 150;
let servicesTotal = 0;
if (servicesSection.checkbox('virtualAddress')?.value()) servicesTotal += 50;
if (servicesSection.checkbox('reception')?.value()) servicesTotal += 100;
if (servicesSection.checkbox('itSupport')?.value()) servicesTotal += 75;
if (servicesSection.checkbox('networkAccess')?.value()) servicesTotal += 25;
const monthlyTotal = membershipTotal + accessFee + amenitiesTotal + servicesTotal;
const discount = commitmentDiscounts[term] || 0;
const finalMonthly = monthlyTotal * (1 - discount);
const people = isHotOrDedicated ? teamSize : parseInt(membershipType.split('-').pop() || '1');
return Math.round(finalMonthly / people);
},
variant: 'default',
suffix: '/mo',
isVisible: () => {
const membershipType = membershipSection.radioButton('membershipType')?.value();
const teamSize = membershipSection.integer('teamSize')?.value() || 1;
const isHotOrDedicated = membershipType === 'hot-desk' || membershipType === 'dedicated-desk';
return (isHotOrDedicated && teamSize > 1) || (!isHotOrDedicated && membershipType !== 'private-office-1');
}
}, '1fr');
});
finalSection.addRow(row => {
row.addTextPanel('includes', {
computedValue: () => 'Includes: High-speed WiFi, coffee & tea, common areas, community events',
customStyles: { 'font-size': '0.9rem', 'color': '#059669', 'font-weight': '500' }
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Prices subject to availability. First month + security deposit due at signing.',
customStyles: { 'font-size': '0.85rem', 'color': '#64748b', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Schedule Tour'
});
}