export function lawnCareCalculator(form: FormTs) {
// Base rates per service
const serviceRates: Record<string, number> = {
'mowing': 0.02, // per sq ft
'fertilization': 0.015, // per sq ft
'weed-control': 0.012, // per sq ft
'aeration': 0.025, // per sq ft
'overseeding': 0.03, // per sq ft
'leaf-removal': 0.01 // per sq ft
};
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Lawn Care Service Quote',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Service Location Section
const locationSection = form.addSubform('serviceLocation', { title: '๐ Service Location' });
locationSection.addRow(row => {
row.addAddress('serviceAddress', {
label: 'Property Address',
placeholder: 'Enter your property address...',
showMap: true,
showDistance: true,
referenceAddress: {
formattedAddress: 'Service Center, Denver, CO',
coordinates: { lat: 39.7392, lng: -104.9903 }
},
restrictToCountries: ['US', 'CA'],
distanceUnit: 'miles',
isRequired: true
});
});
locationSection.addRow(row => {
row.addTextPanel('travelZoneInfo', {
computedValue: () => {
const addressField = locationSection.address('serviceAddress');
const miles = addressField?.distance();
if (miles == null) return '๐ Enter address to check service area';
if (miles <= 10) return '๐ Within primary service area - Standard rates';
if (miles <= 20) return '๐ Extended area - $20 per visit travel fee';
if (miles <= 35) return '๐ Remote area - $40 per visit travel fee';
return '๐ Long distance - Custom quote required';
},
customStyles: { 'font-size': '0.9rem', 'color': '#15803d', 'background': '#dcfce7', 'padding': '10px', 'border-radius': '6px' }
});
});
// Property Details Section
const propertySection = form.addSubform('propertyDetails', { title: '๐ก Property Information' });
propertySection.addRow(row => {
row.addInteger('lawnSize', {
label: 'Lawn Size (sq ft)',
min: 500,
max: 100000,
defaultValue: 5000,
placeholder: 'e.g. 5000',
isRequired: true
}, '1fr');
row.addDropdown('lawnCondition', {
label: 'Current Lawn Condition',
options: [
{ id: 'excellent', name: 'Excellent - Well maintained' },
{ id: 'good', name: 'Good - Minor issues' },
{ id: 'fair', name: 'Fair - Needs work' },
{ id: 'poor', name: 'Poor - Major renovation needed' }
],
defaultValue: 'good',
isRequired: true
}, '1fr');
});
propertySection.addRow(row => {
row.addDropdown('grassType', {
label: 'Grass Type',
options: [
{ id: 'cool-season', name: 'Cool Season (Fescue, Bluegrass, Rye)' },
{ id: 'warm-season', name: 'Warm Season (Bermuda, Zoysia, St. Augustine)' },
{ id: 'mixed', name: 'Mixed / Not Sure' }
],
defaultValue: 'cool-season'
}, '1fr');
row.addDropdown('terrain', {
label: 'Terrain Type',
options: [
{ id: 'flat', name: 'Flat - Easy mowing' },
{ id: 'slight-slope', name: 'Slight Slope (+10%)' },
{ id: 'hilly', name: 'Hilly/Uneven (+25%)' },
{ id: 'obstacles', name: 'Many Obstacles (+15%)' }
],
defaultValue: 'flat'
}, '1fr');
});
// Core Services Section
const coreSection = form.addSubform('coreServices', { title: '๐ฟ Lawn Mowing Service' });
coreSection.addRow(row => {
row.addRadioButton('mowingFrequency', {
label: 'Mowing Frequency',
options: [
{ id: 'weekly', name: 'Weekly (Best results)' },
{ id: 'biweekly', name: 'Bi-Weekly' },
{ id: 'monthly', name: 'Monthly' },
{ id: 'one-time', name: 'One-Time Service' }
],
defaultValue: 'weekly',
orientation: 'vertical',
isRequired: true
});
});
coreSection.addRow(row => {
row.addCheckbox('edging', {
label: 'Include Edging (+$15)',
defaultValue: true
}, '1fr');
row.addCheckbox('trimming', {
label: 'String Trimming (+$10)',
defaultValue: true
}, '1fr');
});
coreSection.addRow(row => {
row.addCheckbox('blowing', {
label: 'Blow Clippings (+$5)',
defaultValue: true
}, '1fr');
row.addCheckbox('bagging', {
label: 'Bag & Remove Clippings (+$20)',
defaultValue: false
}, '1fr');
});
// Treatment Services Section
const treatmentSection = form.addSubform('treatmentServices', { title: '๐ง Lawn Treatment Programs' });
treatmentSection.addRow(row => {
row.addCheckbox('fertilization', {
label: 'Fertilization Program',
defaultValue: false
}, '1fr');
row.addCheckbox('weedControl', {
label: 'Weed Control Program',
defaultValue: false
}, '1fr');
});
treatmentSection.addRow(row => {
row.addDropdown('fertilizerFrequency', {
label: 'Fertilization Frequency',
options: [
{ id: 'quarterly', name: '4 Applications/Year' },
{ id: 'bimonthly', name: '6 Applications/Year' },
{ id: 'monthly', name: 'Monthly Applications' }
],
defaultValue: 'quarterly',
isVisible: () => treatmentSection.checkbox('fertilization')?.value() === true
}, '1fr');
row.addDropdown('weedFrequency', {
label: 'Weed Control Frequency',
options: [
{ id: 'quarterly', name: '4 Applications/Year' },
{ id: 'bimonthly', name: '6 Applications/Year' },
{ id: 'as-needed', name: 'As Needed' }
],
defaultValue: 'quarterly',
isVisible: () => treatmentSection.checkbox('weedControl')?.value() === true
}, '1fr');
});
// Seasonal Services Section
const seasonalSection = form.addSubform('seasonalServices', { title: '๐ Seasonal Services' });
seasonalSection.addRow(row => {
row.addCheckbox('aeration', {
label: 'Core Aeration (Annual)',
defaultValue: false
}, '1fr');
row.addCheckbox('overseeding', {
label: 'Overseeding (Annual)',
defaultValue: false
}, '1fr');
});
seasonalSection.addRow(row => {
row.addCheckbox('leafRemoval', {
label: 'Fall Leaf Removal',
defaultValue: false
}, '1fr');
row.addCheckbox('springCleanup', {
label: 'Spring Cleanup',
defaultValue: false
}, '1fr');
});
seasonalSection.addRow(row => {
row.addInteger('leafRemovalVisits', {
label: 'Leaf Removal Visits',
min: 1,
max: 10,
defaultValue: 3,
isVisible: () => seasonalSection.checkbox('leafRemoval')?.value() === true
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Helper to calculate travel fee per visit
const getTravelFeePerVisit = () => {
const addressField = locationSection.address('serviceAddress');
const miles = addressField?.distance();
if (miles == null || miles <= 10) return 0;
if (miles <= 20) return 20;
if (miles <= 35) return 40;
return 60 + Math.floor((miles - 35) / 10) * 10;
};
// Price Summary Section
const summarySection = form.addSubform('summary', { title: '๐ฐ Service Quote', isCollapsible: false });
const getTerrainMultiplier = () => {
const terrain = propertySection.dropdown('terrain')?.value() || 'flat';
const multipliers: Record<string, number> = {
'flat': 1.0,
'slight-slope': 1.1,
'hilly': 1.25,
'obstacles': 1.15
};
return multipliers[terrain] || 1;
};
const getConditionMultiplier = () => {
const condition = propertySection.dropdown('lawnCondition')?.value() || 'good';
const multipliers: Record<string, number> = {
'excellent': 0.9,
'good': 1.0,
'fair': 1.15,
'poor': 1.35
};
return multipliers[condition] || 1;
};
summarySection.addRow(row => {
row.addPriceDisplay('mowingPrice', {
label: 'Mowing Service (per visit)',
computedValue: () => {
const sqft = propertySection.integer('lawnSize')?.value() || 5000;
let base = Math.max(35, sqft * (serviceRates['mowing'] || 0.02)); // Minimum $35
base *= getTerrainMultiplier();
if (coreSection.checkbox('edging')?.value()) base += 15;
if (coreSection.checkbox('trimming')?.value()) base += 10;
if (coreSection.checkbox('blowing')?.value()) base += 5;
if (coreSection.checkbox('bagging')?.value()) base += 20;
return Math.round(base);
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('mowingMonthly', {
label: 'Monthly Mowing Cost',
computedValue: () => {
const sqft = propertySection.integer('lawnSize')?.value() || 5000;
const frequency = coreSection.radioButton('mowingFrequency')?.value() || 'weekly';
let base = Math.max(35, sqft * (serviceRates['mowing'] || 0.02));
base *= getTerrainMultiplier();
if (coreSection.checkbox('edging')?.value()) base += 15;
if (coreSection.checkbox('trimming')?.value()) base += 10;
if (coreSection.checkbox('blowing')?.value()) base += 5;
if (coreSection.checkbox('bagging')?.value()) base += 20;
const visitsPerMonth: Record<string, number> = {
'weekly': 4,
'biweekly': 2,
'monthly': 1,
'one-time': 0
};
const visits = visitsPerMonth[frequency] || 4;
return Math.round(base * visits);
},
variant: 'default'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('treatmentPrice', {
label: 'Treatment Programs (Annual)',
computedValue: () => {
const sqft = propertySection.integer('lawnSize')?.value() || 5000;
let total = 0;
if (treatmentSection.checkbox('fertilization')?.value()) {
const freq = treatmentSection.dropdown('fertilizerFrequency')?.value() || 'quarterly';
const apps = freq === 'quarterly' ? 4 : freq === 'bimonthly' ? 6 : 12;
total += Math.max(50, sqft * (serviceRates['fertilization'] || 0.015)) * apps;
}
if (treatmentSection.checkbox('weedControl')?.value()) {
const freq = treatmentSection.dropdown('weedFrequency')?.value() || 'quarterly';
const apps = freq === 'quarterly' ? 4 : freq === 'bimonthly' ? 6 : 3;
total += Math.max(40, sqft * (serviceRates['weed-control'] || 0.012)) * apps;
}
return Math.round(total * getConditionMultiplier());
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('seasonalPrice', {
label: 'Seasonal Services (Annual)',
computedValue: () => {
const sqft = propertySection.integer('lawnSize')?.value() || 5000;
let total = 0;
if (seasonalSection.checkbox('aeration')?.value()) {
total += Math.max(75, sqft * (serviceRates['aeration'] || 0.025));
}
if (seasonalSection.checkbox('overseeding')?.value()) {
total += Math.max(100, sqft * (serviceRates['overseeding'] || 0.03));
}
if (seasonalSection.checkbox('leafRemoval')?.value()) {
const visits = seasonalSection.integer('leafRemovalVisits')?.value() || 3;
total += Math.max(75, sqft * (serviceRates['leaf-removal'] || 0.01)) * visits;
}
if (seasonalSection.checkbox('springCleanup')?.value()) {
total += Math.max(100, sqft * 0.015);
}
return Math.round(total);
},
variant: 'default'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('travelFee', {
label: 'Travel Fee (Annual)',
computedValue: () => {
const frequency = coreSection.radioButton('mowingFrequency')?.value() || 'weekly';
const visitsPerMonth: Record<string, number> = {
'weekly': 4, 'biweekly': 2, 'monthly': 1, 'one-time': 0
};
const annualVisits = (visitsPerMonth[frequency] || 4) * 8;
return getTravelFeePerVisit() * annualVisits;
},
variant: 'default',
prefix: '+'
});
});
const finalSection = form.addSubform('final', {
title: '๐งพ Summary',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('annualTotal', {
label: 'Estimated Annual Total',
computedValue: () => {
const sqft = propertySection.integer('lawnSize')?.value() || 5000;
const frequency = coreSection.radioButton('mowingFrequency')?.value() || 'weekly';
let total = 0;
// Mowing (assume 8 months of mowing season)
let mowingBase = Math.max(35, sqft * (serviceRates['mowing'] || 0.02));
mowingBase *= getTerrainMultiplier();
if (coreSection.checkbox('edging')?.value()) mowingBase += 15;
if (coreSection.checkbox('trimming')?.value()) mowingBase += 10;
if (coreSection.checkbox('blowing')?.value()) mowingBase += 5;
if (coreSection.checkbox('bagging')?.value()) mowingBase += 20;
const visitsPerMonth: Record<string, number> = {
'weekly': 4, 'biweekly': 2, 'monthly': 1, 'one-time': 0
};
total += mowingBase * (visitsPerMonth[frequency] || 4) * 8;
// Treatments
if (treatmentSection.checkbox('fertilization')?.value()) {
const freq = treatmentSection.dropdown('fertilizerFrequency')?.value() || 'quarterly';
const apps = freq === 'quarterly' ? 4 : freq === 'bimonthly' ? 6 : 12;
total += Math.max(50, sqft * (serviceRates['fertilization'] || 0.015)) * apps * getConditionMultiplier();
}
if (treatmentSection.checkbox('weedControl')?.value()) {
const freq = treatmentSection.dropdown('weedFrequency')?.value() || 'quarterly';
const apps = freq === 'quarterly' ? 4 : freq === 'bimonthly' ? 6 : 3;
total += Math.max(40, sqft * (serviceRates['weed-control'] || 0.012)) * apps * getConditionMultiplier();
}
// Seasonal
if (seasonalSection.checkbox('aeration')?.value()) {
total += Math.max(75, sqft * (serviceRates['aeration'] || 0.025));
}
if (seasonalSection.checkbox('overseeding')?.value()) {
total += Math.max(100, sqft * (serviceRates['overseeding'] || 0.03));
}
if (seasonalSection.checkbox('leafRemoval')?.value()) {
const visits = seasonalSection.integer('leafRemovalVisits')?.value() || 3;
total += Math.max(75, sqft * (serviceRates['leaf-removal'] || 0.01)) * visits;
}
if (seasonalSection.checkbox('springCleanup')?.value()) {
total += Math.max(100, sqft * 0.015);
}
// Travel fee for mowing visits
const annualVisits = (visitsPerMonth[frequency] || 4) * 8;
total += getTravelFeePerVisit() * annualVisits;
return Math.round(total);
},
variant: 'large'
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Final quote provided after property assessment.',
customStyles: { 'font-size': '0.85rem', 'color': '#64748b', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Get Free Quote'
});
}