export function weddingBudgetForm(form: FormTs) {
form.setTitle(() => '💒 Wedding Budget Calculator');
form.configureCompletionScreen({
type: 'text',
title: () => '🎉 Budget Ready!',
message: () => 'Your wedding budget estimate has been created. Download the PDF to share with your partner!'
});
const venueRates: Record<string, number> = {
'backyard': 500,
'restaurant': 2500,
'hotel': 5000,
'barn': 3500,
'estate': 8000
};
const seasonMultipliers: Record<string, number> = {
'peak': 1.3,
'shoulder': 1.0,
'off-peak': 0.8
};
const eventDetails = form.addSubform('eventDetails', {
title: () => '📅 Event Details',
mobileBreakpoint: 0
});
eventDetails.addRow(row => {
row.addInteger('guestCount', {
label: 'Number of Guests',
min: 20,
max: 500,
defaultValue: 100,
isRequired: true
}, '1fr');
row.addDropdown('season', {
label: 'Season',
options: [
{ id: 'peak', name: 'Peak (Jun-Sep) +30%' },
{ id: 'shoulder', name: 'Shoulder (Apr-May, Oct)' },
{ id: 'off-peak', name: 'Off-Peak (Nov-Mar) -20%' }
],
defaultValue: 'shoulder',
isRequired: true
}, '1fr');
});
const venueSection = form.addSubform('venue', {
title: () => '🏛️ Venue Selection',
mobileBreakpoint: 0
});
venueSection.addRow(row => {
row.addRadioButton('venueType', {
label: 'Venue Type',
options: [
{ id: 'backyard', name: '🏡 Backyard ($500)' },
{ id: 'restaurant', name: '🍽️ Restaurant ($2,500)' },
{ id: 'barn', name: '🌾 Barn/Rustic ($3,500)' },
{ id: 'hotel', name: '🏨 Hotel ($5,000)' },
{ id: 'estate', name: '🏰 Estate ($8,000)' }
],
defaultValue: 'hotel',
orientation: 'vertical',
isRequired: true
});
});
const servicesSection = form.addSubform('services', {
title: () => '✨ Services',
mobileBreakpoint: 500
});
servicesSection.addRow(row => {
row.addDropdown('catering', {
label: 'Catering Style',
options: [
{ id: 'buffet', name: 'Buffet ($45/person)' },
{ id: 'plated', name: 'Plated ($65/person)' },
{ id: 'stations', name: 'Stations ($75/person)' }
],
defaultValue: 'plated',
isRequired: true
}, '1fr');
row.addDropdown('bar', {
label: 'Bar Service',
options: [
{ id: 'none', name: 'No Bar ($0)' },
{ id: 'beer-wine', name: 'Beer & Wine ($25/pp)' },
{ id: 'full', name: 'Open Bar ($50/pp)' }
],
defaultValue: 'beer-wine'
}, '1fr');
});
servicesSection.addRow(row => {
row.addDropdown('photography', {
label: 'Photography',
options: [
{ id: 'none', name: 'None ($0)' },
{ id: 'basic', name: 'Basic ($1,500)' },
{ id: 'standard', name: 'Standard ($3,000)' },
{ id: 'premium', name: 'Premium ($5,000)' }
],
defaultValue: 'standard'
}, '1fr');
row.addDropdown('music', {
label: 'Music',
options: [
{ id: 'playlist', name: 'DIY Playlist ($0)' },
{ id: 'dj', name: 'DJ ($1,200)' },
{ id: 'band', name: 'Live Band ($3,500)' }
],
defaultValue: 'dj'
}, '1fr');
});
const extrasSection = form.addSubform('extras', {
title: () => '💐 Extras',
mobileBreakpoint: 500
});
extrasSection.addRow(row => {
row.addCheckboxList('extras', {
label: 'Select Extras',
options: [
{ id: 'flowers', name: '💐 Flowers & Decor (+$1,500)' },
{ id: 'cake', name: '🎂 Wedding Cake (+$500)' },
{ id: 'planner', name: '📋 Wedding Planner (+$2,000)' },
{ id: 'photobooth', name: '📸 Photo Booth (+$800)' }
],
defaultValue: ['flowers', 'cake'],
orientation: 'vertical'
});
});
const getVenueCost = () => {
const venueType = venueSection.radioButton('venueType')?.value() || 'hotel';
const season = eventDetails.dropdown('season')?.value() || 'shoulder';
const base = venueRates[venueType] || 5000;
const mult = seasonMultipliers[season] || 1;
return Math.round(base * mult);
};
const getCateringCost = () => {
const guests = eventDetails.integer('guestCount')?.value() || 100;
const catering = servicesSection.dropdown('catering')?.value() || 'plated';
const bar = servicesSection.dropdown('bar')?.value() || 'beer-wine';
const cateringPrices: Record<string, number> = { buffet: 45, plated: 65, stations: 75 };
const barPrices: Record<string, number> = { none: 0, 'beer-wine': 25, full: 50 };
return guests * ((cateringPrices[catering] || 65) + (barPrices[bar] || 25));
};
const getServicesCost = () => {
const photoPrices: Record<string, number> = { none: 0, basic: 1500, standard: 3000, premium: 5000 };
const musicPrices: Record<string, number> = { playlist: 0, dj: 1200, band: 3500 };
const photo = servicesSection.dropdown('photography')?.value() || 'standard';
const music = servicesSection.dropdown('music')?.value() || 'dj';
return (photoPrices[photo] || 0) + (musicPrices[music] || 0);
};
const getExtrasCost = () => {
const selected = extrasSection.checkboxList('extras')?.value() || [];
const prices: Record<string, number> = {
flowers: 1500,
cake: 500,
planner: 2000,
photobooth: 800
};
return selected.reduce((total, id) => total + (prices[id] || 0), 0);
};
const getTotalCost = () => getVenueCost() + getCateringCost() + getServicesCost() + getExtrasCost();
const summary = form.addSubform('summary', {
title: () => '💰 Budget Estimate',
isCollapsible: false
});
summary.addRow(row => {
row.addPriceDisplay('total', {
label: 'Estimated Total',
computedValue: () => getTotalCost(),
alignment: 'center',
variant: 'large'
});
});
summary.addRow(row => {
row.addTextPanel('perGuest', {
computedValue: () => {
const guests = eventDetails.integer('guestCount')?.value() || 100;
const perGuest = Math.round(getTotalCost() / guests);
return `👥 ${guests} guests • $${perGuest}/guest`;
},
customStyles: {
fontSize: '0.95rem',
color: '#059669',
textAlign: 'center',
fontWeight: '500'
}
});
});
form.configureSubmitButton({
label: () => 'Get Vendor Recommendations'
});
}