export function hvacPlumbingForm(form: FormTs) {
form.setTitle(() => '🔧 Service Quote Calculator');
form.configureCompletionScreen({
type: 'text',
title: () => '📋 Quote Ready!',
message: () => 'Your service estimate is ready. We\'ll call you to schedule an appointment!'
});
const serviceSection = form.addSubform('service', {
title: () => '🔧 Service Type',
mobileBreakpoint: 0
});
serviceSection.addRow(row => {
row.addRadioButton('category', {
label: 'Category',
options: [
{ id: 'hvac', name: '❄️ HVAC/Heating & Cooling' },
{ id: 'plumbing', name: '🚿 Plumbing' },
{ id: 'electrical', name: '⚡ Electrical' }
],
defaultValue: 'hvac',
orientation: 'vertical',
isRequired: true
});
});
const hvacSection = form.addSubform('hvac', {
title: () => '❄️ HVAC Service',
isVisible: () => serviceSection.radioButton('category')?.value() === 'hvac',
mobileBreakpoint: 0
});
hvacSection.addRow(row => {
row.addDropdown('hvacService', {
label: 'Service Needed',
options: [
{ id: 'diagnostic', name: 'Diagnostic/Inspection ($89)' },
{ id: 'tune-up', name: 'Seasonal Tune-Up ($149)' },
{ id: 'repair', name: 'Repair ($150-$500)' },
{ id: 'replace-unit', name: 'Unit Replacement (Quote)' },
{ id: 'duct-cleaning', name: 'Duct Cleaning ($299+)' }
],
defaultValue: 'diagnostic'
}, '1fr');
});
const plumbingSection = form.addSubform('plumbing', {
title: () => '🚿 Plumbing Service',
isVisible: () => serviceSection.radioButton('category')?.value() === 'plumbing',
mobileBreakpoint: 0
});
plumbingSection.addRow(row => {
row.addDropdown('plumbingService', {
label: 'Service Needed',
options: [
{ id: 'diagnostic', name: 'Diagnostic ($79)' },
{ id: 'drain', name: 'Drain Cleaning ($125-$250)' },
{ id: 'leak', name: 'Leak Repair ($150-$400)' },
{ id: 'water-heater', name: 'Water Heater ($200-$1500)' },
{ id: 'toilet', name: 'Toilet Repair ($100-$300)' },
{ id: 'faucet', name: 'Faucet Install ($150-$250)' }
],
defaultValue: 'diagnostic'
}, '1fr');
});
const electricalSection = form.addSubform('electrical', {
title: () => '⚡ Electrical Service',
isVisible: () => serviceSection.radioButton('category')?.value() === 'electrical',
mobileBreakpoint: 0
});
electricalSection.addRow(row => {
row.addDropdown('electricalService', {
label: 'Service Needed',
options: [
{ id: 'diagnostic', name: 'Diagnostic ($89)' },
{ id: 'outlet', name: 'Outlet Install ($125-$200)' },
{ id: 'switch', name: 'Switch/Dimmer ($100-$175)' },
{ id: 'panel', name: 'Panel Upgrade (Quote)' },
{ id: 'lighting', name: 'Light Fixture ($100-$250)' }
],
defaultValue: 'diagnostic'
}, '1fr');
});
const timingSection = form.addSubform('timing', {
title: () => '⏰ Timing',
mobileBreakpoint: 0
});
timingSection.addRow(row => {
row.addRadioButton('urgency', {
label: 'When do you need service?',
options: [
{ id: 'standard', name: 'Standard (Next available)' },
{ id: 'same-day', name: 'Same Day (+$50)' },
{ id: 'emergency', name: '🚨 Emergency (+$150)' }
],
defaultValue: 'standard',
orientation: 'vertical'
}, '1fr');
row.addRadioButton('timing', {
label: 'Preferred Time',
options: [
{ id: 'regular', name: 'Weekday 8am-5pm' },
{ id: 'evening', name: 'Evening (+15%)' },
{ id: 'weekend', name: 'Weekend (+20%)' }
],
defaultValue: 'regular',
orientation: 'vertical'
}, '1fr');
});
const propertySection = form.addSubform('property', {
title: () => '🏠 Property Info',
mobileBreakpoint: 0
});
propertySection.addRow(row => {
row.addDropdown('propertyType', {
label: 'Property Type',
options: [
{ id: 'house', name: 'Single Family Home' },
{ id: 'condo', name: 'Condo/Townhouse' },
{ id: 'apartment', name: 'Apartment' },
{ id: 'commercial', name: 'Commercial (+25%)' }
],
defaultValue: 'house'
}, '1fr');
});
const calculateEstimate = () => {
const category = serviceSection.radioButton('category')?.value() || 'hvac';
const urgency = timingSection.radioButton('urgency')?.value() || 'standard';
const timing = timingSection.radioButton('timing')?.value() || 'regular';
const propertyType = propertySection.dropdown('propertyType')?.value() || 'house';
let minPrice = 0;
let maxPrice = 0;
if (category === 'hvac') {
const service = hvacSection.dropdown('hvacService')?.value() || 'diagnostic';
const hvacPrices: Record<string, [number, number]> = {
'diagnostic': [89, 89],
'tune-up': [149, 149],
'repair': [150, 500],
'replace-unit': [3000, 8000],
'duct-cleaning': [299, 599]
};
[minPrice, maxPrice] = hvacPrices[service] || [89, 89];
} else if (category === 'plumbing') {
const service = plumbingSection.dropdown('plumbingService')?.value() || 'diagnostic';
const plumbingPrices: Record<string, [number, number]> = {
'diagnostic': [79, 79],
'drain': [125, 250],
'leak': [150, 400],
'water-heater': [200, 1500],
'toilet': [100, 300],
'faucet': [150, 250]
};
[minPrice, maxPrice] = plumbingPrices[service] || [79, 79];
} else {
const service = electricalSection.dropdown('electricalService')?.value() || 'diagnostic';
const electricalPrices: Record<string, [number, number]> = {
'diagnostic': [89, 89],
'outlet': [125, 200],
'switch': [100, 175],
'panel': [1500, 4000],
'lighting': [100, 250]
};
[minPrice, maxPrice] = electricalPrices[service] || [89, 89];
}
const urgencyFees: Record<string, number> = { standard: 0, 'same-day': 50, emergency: 150 };
const urgencyFee = urgencyFees[urgency] || 0;
const timingMult: Record<string, number> = { regular: 1, evening: 1.15, weekend: 1.2 };
const timeMult = timingMult[timing] || 1;
const propertyMult = propertyType === 'commercial' ? 1.25 : 1;
minPrice = Math.round((minPrice * timeMult * propertyMult) + urgencyFee);
maxPrice = Math.round((maxPrice * timeMult * propertyMult) + urgencyFee);
return { min: minPrice, max: maxPrice };
};
const summary = form.addSubform('summary', {
title: () => '💰 Estimate',
isCollapsible: false
});
summary.addRow(row => {
row.addPriceDisplay('minEstimate', {
label: 'Starting At',
computedValue: () => calculateEstimate().min,
alignment: 'center',
variant: 'large'
});
});
summary.addRow(row => {
row.addTextPanel('range', {
computedValue: () => {
const { min, max } = calculateEstimate();
if (min === max) {
return '✓ Fixed price service';
}
return `📊 Typical range: $${min} - $${max}`;
},
customStyles: {
fontSize: '0.95rem',
color: '#059669',
textAlign: 'center',
fontWeight: '500'
}
});
});
summary.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => '* Final price depends on diagnosis. Service call fee applies.',
customStyles: {
fontSize: '0.85rem',
color: '#6b7280',
textAlign: 'center',
fontStyle: 'italic'
}
});
});
form.configureSubmitButton({
label: () => 'Request Service Call'
});
}