export function conferencePlanningCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Conference Planning Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Event Basics Section
const basicsSection = form.addSubform('basics', { title: '📋 Event Basics' });
basicsSection.addRow(row => {
row.addDropdown('conferenceType', {
label: 'Conference Type',
options: [
{ id: 'corporate', name: 'Corporate Conference' },
{ id: 'industry', name: 'Industry Trade Show' },
{ id: 'academic', name: 'Academic/Research Conference' },
{ id: 'training', name: 'Training/Workshop' },
{ id: 'seminar', name: 'Seminar/Symposium' },
{ id: 'product-launch', name: 'Product Launch Event' },
{ id: 'networking', name: 'Networking Event' }
],
defaultValue: 'corporate',
isRequired: true
}, '1fr');
row.addDropdown('eventScale', {
label: 'Event Scale',
options: [
{ id: 'small', name: 'Small (25-50 attendees)' },
{ id: 'medium', name: 'Medium (50-150 attendees)' },
{ id: 'large', name: 'Large (150-500 attendees)' },
{ id: 'major', name: 'Major (500-1000 attendees)' },
{ id: 'mega', name: 'Mega (1000+ attendees)' }
],
defaultValue: 'medium',
isRequired: true
}, '1fr');
});
basicsSection.addRow(row => {
row.addInteger('attendees', {
label: 'Expected Attendees',
min: 10,
max: 10000,
defaultValue: 100,
isRequired: true
}, '1fr');
row.addInteger('days', {
label: 'Number of Days',
min: 1,
max: 7,
defaultValue: 1
}, '1fr');
});
// Venue Section
const venueSection = form.addSubform('venue', { title: '🏛️ Venue & Space' });
venueSection.addRow(row => {
row.addDropdown('venueType', {
label: 'Venue Type',
options: [
{ id: 'hotel', name: 'Hotel Conference Center' },
{ id: 'convention', name: 'Convention Center' },
{ id: 'corporate', name: 'Corporate Office Space' },
{ id: 'university', name: 'University/Academic' },
{ id: 'unique', name: 'Unique Venue (museum, etc.)' },
{ id: 'virtual', name: 'Virtual Only' },
{ id: 'hybrid', name: 'Hybrid (In-person + Virtual)' }
],
defaultValue: 'hotel',
isRequired: true
}, '1fr');
row.addDropdown('location', {
label: 'Location Type',
options: [
{ id: 'local', name: 'Local/Regional' },
{ id: 'major-city', name: 'Major City' },
{ id: 'destination', name: 'Destination/Resort' },
{ id: 'international', name: 'International' }
],
defaultValue: 'major-city',
isVisible: () => venueSection.dropdown('venueType')?.value() !== 'virtual'
}, '1fr');
});
venueSection.addRow(row => {
row.addInteger('breakoutRooms', {
label: 'Breakout Rooms Needed',
min: 0,
max: 20,
defaultValue: 2,
isVisible: () => venueSection.dropdown('venueType')?.value() !== 'virtual'
}, '1fr');
row.addCheckbox('exhibitSpace', {
label: 'Exhibition/Vendor Space',
defaultValue: false,
isVisible: () => venueSection.dropdown('venueType')?.value() !== 'virtual'
}, '1fr');
});
venueSection.addRow(row => {
row.addInteger('exhibitors', {
label: 'Number of Exhibitor Booths',
min: 1,
max: 200,
defaultValue: 10,
isVisible: () => venueSection.checkbox('exhibitSpace')?.value() === true
}, '1fr');
});
// Catering Section
const cateringSection = form.addSubform('catering', { title: '🍽️ Food & Beverage' });
cateringSection.addRow(row => {
row.addDropdown('cateringLevel', {
label: 'Catering Level',
options: [
{ id: 'none', name: 'No Catering' },
{ id: 'basic', name: 'Basic (Coffee/Snacks)' },
{ id: 'standard', name: 'Standard (Buffet Meals)' },
{ id: 'premium', name: 'Premium (Plated Service)' },
{ id: 'luxury', name: 'Luxury (Full Service)' }
],
defaultValue: 'standard'
}, '1fr');
row.addInteger('mealsPerDay', {
label: 'Meals per Day',
min: 0,
max: 3,
defaultValue: 2,
isVisible: () => !['none', 'basic'].includes(cateringSection.dropdown('cateringLevel')?.value() || '')
}, '1fr');
});
cateringSection.addRow(row => {
row.addCheckbox('welcomeReception', {
label: 'Welcome Reception',
defaultValue: false
}, '1fr');
row.addCheckbox('galaDinner', {
label: 'Gala/Awards Dinner',
defaultValue: false
}, '1fr');
});
cateringSection.addRow(row => {
row.addCheckbox('openBar', {
label: 'Open Bar at Events',
defaultValue: false
}, '1fr');
row.addCheckbox('dietaryOptions', {
label: 'Special Dietary Options',
defaultValue: true
}, '1fr');
});
// AV & Technology Section
const techSection = form.addSubform('tech', { title: '🎬 AV & Technology' });
techSection.addRow(row => {
row.addDropdown('avPackage', {
label: 'AV Package',
options: [
{ id: 'basic', name: 'Basic (Screen/Projector)' },
{ id: 'standard', name: 'Standard (Full AV setup)' },
{ id: 'professional', name: 'Professional (Multi-screen, staging)' },
{ id: 'broadcast', name: 'Broadcast Quality' }
],
defaultValue: 'standard'
}, '1fr');
row.addCheckbox('livestreaming', {
label: 'Livestreaming',
defaultValue: false
}, '1fr');
});
techSection.addRow(row => {
row.addCheckbox('eventApp', {
label: 'Conference App',
defaultValue: false
}, '1fr');
row.addCheckbox('registrationSystem', {
label: 'Online Registration System',
defaultValue: true
}, '1fr');
});
techSection.addRow(row => {
row.addCheckbox('simultTranslation', {
label: 'Simultaneous Translation',
defaultValue: false
}, '1fr');
row.addCheckbox('recordingSessions', {
label: 'Session Recording',
defaultValue: false
}, '1fr');
});
// Speakers & Content Section
const speakersSection = form.addSubform('speakers', { title: '🎤 Speakers & Content' });
speakersSection.addRow(row => {
row.addInteger('keynoteSpeakers', {
label: 'Keynote Speakers',
min: 0,
max: 10,
defaultValue: 1
}, '1fr');
row.addDropdown('speakerLevel', {
label: 'Speaker Caliber',
options: [
{ id: 'internal', name: 'Internal/Industry Peers' },
{ id: 'expert', name: 'Industry Experts' },
{ id: 'celebrity', name: 'Celebrity/Famous Speakers' },
{ id: 'thought-leader', name: 'Thought Leaders' }
],
defaultValue: 'expert'
}, '1fr');
});
speakersSection.addRow(row => {
row.addInteger('sessions', {
label: 'Breakout Sessions',
min: 0,
max: 50,
defaultValue: 6
}, '1fr');
row.addInteger('workshops', {
label: 'Hands-on Workshops',
min: 0,
max: 20,
defaultValue: 2
}, '1fr');
});
// Marketing & Materials Section
const marketingSection = form.addSubform('marketing', { title: '📢 Marketing & Materials' });
marketingSection.addRow(row => {
row.addCheckbox('printedMaterials', {
label: 'Printed Programs/Materials',
defaultValue: true
}, '1fr');
row.addCheckbox('nameBadges', {
label: 'Custom Name Badges',
defaultValue: true
}, '1fr');
});
marketingSection.addRow(row => {
row.addCheckbox('swagBags', {
label: 'Attendee Swag Bags',
defaultValue: false
}, '1fr');
row.addCheckbox('signage', {
label: 'Event Signage & Banners',
defaultValue: true
}, '1fr');
});
marketingSection.addRow(row => {
row.addCheckbox('photographer', {
label: 'Professional Photography',
defaultValue: false
}, '1fr');
row.addCheckbox('videographer', {
label: 'Professional Videography',
defaultValue: false
}, '1fr');
});
// Staffing Section
const staffingSection = form.addSubform('staffing', { title: '👥 Staffing & Services' });
staffingSection.addRow(row => {
row.addDropdown('staffingLevel', {
label: 'Event Staff',
options: [
{ id: 'minimal', name: 'Minimal (self-service)' },
{ id: 'standard', name: 'Standard (registration + support)' },
{ id: 'full', name: 'Full Service (dedicated team)' },
{ id: 'premium', name: 'Premium (white-glove service)' }
],
defaultValue: 'standard'
}, '1fr');
row.addCheckbox('eventPlanner', {
label: 'Professional Event Planner',
defaultValue: false
}, '1fr');
});
staffingSection.addRow(row => {
row.addCheckbox('security', {
label: 'Security Personnel',
defaultValue: false
}, '1fr');
row.addCheckbox('transportation', {
label: 'Shuttle/Transportation',
defaultValue: false
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Budget Breakdown Section
const budgetSection = form.addSubform('budget', { title: '💰 Budget Breakdown', isCollapsible: false });
const calculateBudget = () => {
const attendees = basicsSection.integer('attendees')?.value() || 100;
const days = basicsSection.integer('days')?.value() || 1;
const eventScale = basicsSection.dropdown('eventScale')?.value() || 'medium';
const venueType = venueSection.dropdown('venueType')?.value() || 'hotel';
const location = venueSection.dropdown('location')?.value() || 'major-city';
const breakoutRooms = venueSection.integer('breakoutRooms')?.value() || 2;
const cateringLevel = cateringSection.dropdown('cateringLevel')?.value() || 'standard';
const mealsPerDay = cateringSection.integer('mealsPerDay')?.value() || 2;
const avPackage = techSection.dropdown('avPackage')?.value() || 'standard';
const keynoteSpeakers = speakersSection.integer('keynoteSpeakers')?.value() || 1;
const speakerLevel = speakersSection.dropdown('speakerLevel')?.value() || 'expert';
const staffingLevel = staffingSection.dropdown('staffingLevel')?.value() || 'standard';
// Venue costs
let venueCostPerDay = 0;
if (venueType !== 'virtual') {
const venueBase: Record<string, number> = {
'hotel': 3000,
'convention': 5000,
'corporate': 1500,
'university': 2000,
'unique': 6000
};
venueCostPerDay = venueBase[venueType] || 3000;
// Location multiplier
const locationMult: Record<string, number> = {
'local': 0.8,
'major-city': 1.0,
'destination': 1.5,
'international': 2.0
};
venueCostPerDay *= locationMult[location] || 1.0;
// Scale multiplier
const scaleMult: Record<string, number> = {
'small': 0.5,
'medium': 1.0,
'large': 2.0,
'major': 3.5,
'mega': 6.0
};
venueCostPerDay *= scaleMult[eventScale] || 1.0;
// Breakout rooms
venueCostPerDay += breakoutRooms * 500;
}
// Virtual/hybrid costs
let virtualCost = 0;
if (venueType === 'virtual' || venueType === 'hybrid') {
virtualCost = 2000 + (attendees * 5);
}
// Exhibition space
let exhibitCost = 0;
if (venueSection.checkbox('exhibitSpace')?.value()) {
const exhibitors = venueSection.integer('exhibitors')?.value() || 10;
exhibitCost = exhibitors * 500 * days;
}
// Catering costs
let cateringCost = 0;
const cateringRates: Record<string, number> = {
'none': 0,
'basic': 15,
'standard': 50,
'premium': 85,
'luxury': 150
};
cateringCost = (cateringRates[cateringLevel] ?? 0) * attendees * days;
if (cateringLevel !== 'none' && cateringLevel !== 'basic') {
cateringCost = (cateringRates[cateringLevel] ?? 0) * attendees * mealsPerDay * days;
}
// Special events
if (cateringSection.checkbox('welcomeReception')?.value()) {
cateringCost += attendees * 40;
}
if (cateringSection.checkbox('galaDinner')?.value()) {
cateringCost += attendees * 100;
}
if (cateringSection.checkbox('openBar')?.value()) {
cateringCost += attendees * 30 * days;
}
// AV & Tech costs
let techCost = 0;
const avRates: Record<string, number> = {
'basic': 1500,
'standard': 4000,
'professional': 10000,
'broadcast': 25000
};
techCost = (avRates[avPackage] ?? 0) * days;
if (techSection.checkbox('livestreaming')?.value()) techCost += 3000 * days;
if (techSection.checkbox('eventApp')?.value()) techCost += 5000;
if (techSection.checkbox('registrationSystem')?.value()) techCost += 1000;
if (techSection.checkbox('simultTranslation')?.value()) techCost += 5000 * days;
if (techSection.checkbox('recordingSessions')?.value()) techCost += 2000 * days;
// Speaker costs
let speakerCost = 0;
const speakerFees: Record<string, number> = {
'internal': 500,
'expert': 5000,
'celebrity': 25000,
'thought-leader': 15000
};
speakerCost = keynoteSpeakers * (speakerFees[speakerLevel] ?? 0);
speakerCost += (speakersSection.integer('sessions')?.value() || 0) * 300;
speakerCost += (speakersSection.integer('workshops')?.value() || 0) * 500;
// Marketing & Materials
let marketingCost = 0;
if (marketingSection.checkbox('printedMaterials')?.value()) marketingCost += attendees * 5;
if (marketingSection.checkbox('nameBadges')?.value()) marketingCost += attendees * 3;
if (marketingSection.checkbox('swagBags')?.value()) marketingCost += attendees * 25;
if (marketingSection.checkbox('signage')?.value()) marketingCost += 2000;
if (marketingSection.checkbox('photographer')?.value()) marketingCost += 1500 * days;
if (marketingSection.checkbox('videographer')?.value()) marketingCost += 3000 * days;
// Staffing costs
let staffingCost = 0;
const staffRates: Record<string, number> = {
'minimal': 500,
'standard': 2000,
'full': 5000,
'premium': 10000
};
staffingCost = (staffRates[staffingLevel] ?? 0) * days;
if (staffingSection.checkbox('eventPlanner')?.value()) staffingCost += 5000;
if (staffingSection.checkbox('security')?.value()) staffingCost += 500 * days;
if (staffingSection.checkbox('transportation')?.value()) staffingCost += attendees * 20;
const venueTotalCost = (venueCostPerDay * days) + virtualCost + exhibitCost;
const totalCost = venueTotalCost + cateringCost + techCost + speakerCost + marketingCost + staffingCost;
const perAttendeeCost = totalCost / attendees;
return {
venue: Math.round(venueTotalCost),
catering: Math.round(cateringCost),
tech: Math.round(techCost),
speakers: Math.round(speakerCost),
marketing: Math.round(marketingCost),
staffing: Math.round(staffingCost),
total: Math.round(totalCost),
perAttendee: Math.round(perAttendeeCost),
attendees,
days
};
};
budgetSection.addRow(row => {
row.addPriceDisplay('venue', {
label: 'Venue & Space',
computedValue: () => calculateBudget().venue,
variant: 'default'
}, '1fr');
row.addPriceDisplay('catering', {
label: 'Food & Beverage',
computedValue: () => calculateBudget().catering,
variant: 'default'
}, '1fr');
});
budgetSection.addRow(row => {
row.addPriceDisplay('tech', {
label: 'AV & Technology',
computedValue: () => calculateBudget().tech,
variant: 'default'
}, '1fr');
row.addPriceDisplay('speakers', {
label: 'Speakers & Content',
computedValue: () => calculateBudget().speakers,
variant: 'default'
}, '1fr');
});
budgetSection.addRow(row => {
row.addPriceDisplay('marketing', {
label: 'Marketing & Materials',
computedValue: () => calculateBudget().marketing,
variant: 'default'
}, '1fr');
row.addPriceDisplay('staffing', {
label: 'Staffing & Services',
computedValue: () => calculateBudget().staffing,
variant: 'default'
}, '1fr');
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '📊 Total Budget',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addPriceDisplay('total', {
label: () => `Total (${calculateBudget().days} day${calculateBudget().days > 1 ? 's' : ''}, ${calculateBudget().attendees} attendees)`,
computedValue: () => calculateBudget().total,
variant: 'large'
}, '1fr');
row.addPriceDisplay('perAttendee', {
label: 'Cost per Attendee',
computedValue: () => calculateBudget().perAttendee,
variant: 'success'
}, '1fr');
});
summarySection.addRow(row => {
row.addTextPanel('note', {
computedValue: () => 'Budget estimate. Actual costs vary by location, vendors, and specific requirements.',
customStyles: { 'font-size': '0.85rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Get Detailed Quote'
});
}