export function autoDetailingForm(form: FormTs) {
form.setTitle(() => 'โจ Auto Detailing Quote Calculator');
form.configureCompletionScreen({
type: 'text',
title: () => '๐ Quote Ready!',
message: () => 'Your custom detailing quote has been generated. Download your PDF to save the details.'
});
// Pricing data
const vehicleSizePrices: Record<string, number> = {
'sedan': 0,
'coupe': 0,
'suv': 40,
'truck': 50,
'van': 60,
'xl': 80
};
const packagePrices: Record<string, number> = {
'exterior': 80,
'interior': 90,
'full': 150,
'premium': 250
};
const addonPrices: Record<string, number> = {
'clayBar': 50,
'paintCorrection': 150,
'ceramicSpray': 80,
'headlightRestore': 60,
'engineBay': 45,
'ozoneTreatment': 75,
'leatherCondition': 40,
'fabricProtect': 35,
'petHairRemoval': 50,
'wheelPolish': 40
};
// Vehicle Details
const vehicleDetails = form.addSubform('vehicleDetails', {
title: () => '๐ Vehicle Details',
mobileBreakpoint: 0
});
vehicleDetails.addRow(row => {
row.addDropdown('vehicleSize', {
label: 'Vehicle Size',
defaultValue: 'sedan',
isRequired: true,
options: [
{ id: 'sedan', name: '๐ Sedan/Compact (no extra)' },
{ id: 'coupe', name: '๐๏ธ Coupe/Sports Car (no extra)' },
{ id: 'suv', name: '๐ SUV/Crossover (+$40)' },
{ id: 'truck', name: '๐ป Truck (+$50)' },
{ id: 'van', name: '๐ Van/Minivan (+$60)' },
{ id: 'xl', name: '๐ XL Vehicle (+$80)' }
]
}, '1fr');
});
vehicleDetails.addRow(row => {
row.addDropdown('condition', {
label: 'Current Condition',
defaultValue: 'normal',
isRequired: true,
options: [
{ id: 'good', name: 'โจ Good - Regular maintenance' },
{ id: 'normal', name: '๐ Normal - Some dirt/dust' },
{ id: 'dirty', name: '๐
Dirty - Needs attention' },
{ id: 'veryDirty', name: '๐ฌ Very Dirty - Heavy cleaning needed' }
]
}, '1fr');
});
// Detailing Package
const packageSection = form.addSubform('package', {
title: () => '๐ฆ Detailing Package',
mobileBreakpoint: 0
});
packageSection.addRow(row => {
row.addRadioButton('detailPackage', {
label: 'Select Package',
defaultValue: 'full',
isRequired: true,
orientation: 'vertical',
options: [
{ id: 'exterior', name: '๐ฟ Exterior Only ($80) - Wash, clay, wax, tires, windows' },
{ id: 'interior', name: '๐งน Interior Only ($90) - Vacuum, wipe, glass, air freshener' },
{ id: 'full', name: 'โญ Full Detail ($150) - Complete interior + exterior' },
{ id: 'premium', name: '๐ Premium Detail ($250) - Full detail + paint correction + ceramic spray' }
]
});
});
// Add-ons
const addonsSection = form.addSubform('addons', {
title: () => 'โจ Premium Add-Ons',
mobileBreakpoint: 500
});
addonsSection.addRow(row => {
row.addCheckboxList('exteriorAddons', {
label: 'Exterior Add-Ons',
orientation: 'vertical',
options: [
{ id: 'clayBar', name: '๐งฑ Clay Bar Treatment (+$50)' },
{ id: 'paintCorrection', name: '๐ง Paint Correction (+$150)' },
{ id: 'ceramicSpray', name: '๐ก๏ธ Ceramic Spray Coating (+$80)' },
{ id: 'headlightRestore', name: '๐ก Headlight Restoration (+$60)' },
{ id: 'wheelPolish', name: '๐ Wheel Polish & Seal (+$40)' }
]
}, '1fr');
row.addCheckboxList('interiorAddons', {
label: 'Interior Add-Ons',
orientation: 'vertical',
options: [
{ id: 'engineBay', name: '๐ง Engine Bay Cleaning (+$45)' },
{ id: 'ozoneTreatment', name: '๐จ Ozone Odor Treatment (+$75)' },
{ id: 'leatherCondition', name: '๐๏ธ Leather Conditioning (+$40)' },
{ id: 'fabricProtect', name: '๐งด Fabric Protection (+$35)' },
{ id: 'petHairRemoval', name: '๐ Pet Hair Removal (+$50)' }
]
}, '1fr');
});
// Calculate functions
const getVehicleSizePrice = () => {
const size = vehicleDetails.dropdown('vehicleSize')?.value() || 'sedan';
return vehicleSizePrices[size] ?? 0;
};
const getConditionMultiplier = () => {
const condition = vehicleDetails.dropdown('condition')?.value() || 'normal';
const multipliers: Record<string, number> = {
'good': 1.0,
'normal': 1.0,
'dirty': 1.15,
'veryDirty': 1.3
};
return multipliers[condition] ?? 1.0;
};
const getPackagePrice = () => {
const pkg = packageSection.radioButton('detailPackage')?.value() || 'full';
return packagePrices[pkg] ?? 150;
};
const getAddonsTotal = () => {
let total = 0;
const exteriorAddons = addonsSection.checkboxList('exteriorAddons')?.value() || [];
const interiorAddons = addonsSection.checkboxList('interiorAddons')?.value() || [];
const allSelected = [...exteriorAddons, ...interiorAddons];
for (const addonId of allSelected) {
total += addonPrices[addonId] ?? 0;
}
return total;
};
const getSelectedAddons = () => {
const exteriorAddons = addonsSection.checkboxList('exteriorAddons')?.value() || [];
const interiorAddons = addonsSection.checkboxList('interiorAddons')?.value() || [];
return [...exteriorAddons, ...interiorAddons];
};
const getTotalPrice = () => {
const basePackage = getPackagePrice();
const vehicleSize = getVehicleSizePrice();
const conditionMultiplier = getConditionMultiplier();
const addons = getAddonsTotal();
return Math.round((basePackage + vehicleSize) * conditionMultiplier) + addons;
};
// Quote Summary
const summary = form.addSubform('summary', {
title: () => '๐ฐ Your Detailing Quote',
isCollapsible: false,
});
summary.addRow(row => {
row.addPriceDisplay('totalPrice', {
label: 'Total Price',
computedValue: () => getTotalPrice(),
alignment: 'center',
variant: 'large'
});
});
summary.addRow(row => {
row.addTextPanel('includes', {
computedValue: () => {
const pkg = packageSection.radioButton('detailPackage')?.value() || 'full';
const packageNames: Record<string, string> = {
'exterior': 'Exterior Detail package',
'interior': 'Interior Detail package',
'full': 'Full Detail package',
'premium': 'Premium Detail package'
};
return `โจ Includes: ${packageNames[pkg] ?? 'Full Detail package'} with professional care`;
},
customStyles: {
fontSize: '0.9rem',
color: '#6b7280',
textAlign: 'center'
}
});
});
form.configureSubmitButton({
label: () => 'Book This Detail'
});
// Configure PDF
form.configurePdf('quoteDocument', (pdf) => {
pdf.configure({
filename: 'auto-detailing-quote.pdf',
pageSize: 'A4',
allowUserDownload: true,
downloadButtonLabel: 'Download Your Quote',
header: {
title: 'Auto Detailing Quote',
subtitle: 'Custom Service Package'
},
footer: {
text: 'Thank you for choosing us for your auto detailing needs!',
showPageNumbers: true
}
});
pdf.addSection('Vehicle Details', (section) => {
section.addRow((row) => {
const size = vehicleDetails.dropdown('vehicleSize')?.value() || 'sedan';
const sizeLabels: Record<string, string> = {
'sedan': 'Sedan/Compact',
'coupe': 'Coupe/Sports Car',
'suv': 'SUV/Crossover',
'truck': 'Truck',
'van': 'Van/Minivan',
'xl': 'XL Vehicle'
};
row.addField('Vehicle Size', sizeLabels[size] ?? size);
const condition = vehicleDetails.dropdown('condition')?.value() || 'normal';
const conditionLabels: Record<string, string> = {
'good': 'Good - Regular maintenance',
'normal': 'Normal - Some dirt/dust',
'dirty': 'Dirty - Needs attention',
'veryDirty': 'Very Dirty - Heavy cleaning'
};
row.addField('Condition', conditionLabels[condition] ?? condition);
});
});
pdf.addSection('Detailing Package', (section) => {
section.addRow((row) => {
const pkg = packageSection.radioButton('detailPackage')?.value() || 'full';
const packageLabels: Record<string, string> = {
'exterior': 'Exterior Only',
'interior': 'Interior Only',
'full': 'Full Detail',
'premium': 'Premium Detail'
};
row.addField('Package', packageLabels[pkg] ?? pkg);
row.addField('Package Price', `$${getPackagePrice()}`);
});
});
const selectedAddons = getSelectedAddons();
if (selectedAddons.length > 0) {
pdf.addSection('Premium Add-Ons', (section) => {
const addonLabels: Record<string, string> = {
'clayBar': 'Clay Bar Treatment',
'paintCorrection': 'Paint Correction',
'ceramicSpray': 'Ceramic Spray Coating',
'headlightRestore': 'Headlight Restoration',
'engineBay': 'Engine Bay Cleaning',
'ozoneTreatment': 'Ozone Odor Treatment',
'leatherCondition': 'Leather Conditioning',
'fabricProtect': 'Fabric Protection',
'petHairRemoval': 'Pet Hair Removal',
'wheelPolish': 'Wheel Polish & Seal'
};
const tableRows = selectedAddons.map(addonId => [
addonLabels[addonId] ?? addonId,
`$${addonPrices[addonId] ?? 0}`
]);
section.addTable(['Service', 'Price'], tableRows);
});
}
pdf.addSection('Quote Summary', (section) => {
section.addRow((row) => {
row.addField('Base Package', `$${getPackagePrice()}`);
});
const vehicleSizePrice = getVehicleSizePrice();
if (vehicleSizePrice > 0) {
section.addRow((row) => {
row.addField('Vehicle Size Adjustment', `$${vehicleSizePrice}`);
});
}
const conditionMultiplier = getConditionMultiplier();
if (conditionMultiplier > 1) {
section.addRow((row) => {
const extraPercent = Math.round((conditionMultiplier - 1) * 100);
row.addField('Condition Adjustment', `+${extraPercent}%`);
});
}
if (selectedAddons.length > 0) {
section.addRow((row) => {
row.addField('Add-ons', `$${getAddonsTotal()}`);
});
}
section.addDivider();
section.addSpacer(10);
section.addRow((row) => {
row.addField('TOTAL', `$${getTotalPrice()}`);
});
});
pdf.addSection('What\'s Included', (section) => {
const pkg = packageSection.radioButton('detailPackage')?.value() || 'full';
const includes: Record<string, string[]> = {
'exterior': ['Hand wash & dry', 'Clay bar decontamination', 'Wax/sealant application', 'Tire & wheel cleaning', 'Window cleaning', 'Trim dressing'],
'interior': ['Full vacuum', 'Dashboard & console wipe', 'Door panels cleaning', 'Glass cleaning', 'Air freshener', 'Floor mat cleaning'],
'full': ['Complete exterior detail', 'Complete interior detail', 'Trunk cleaning', 'Door jambs', 'Cup holder cleaning', 'Vent cleaning'],
'premium': ['Everything in Full Detail', 'One-step paint correction', 'Ceramic spray coating', 'Leather/vinyl conditioning', 'Engine bay cleaning', '30-day protection guarantee']
};
const items = includes[pkg] ?? includes['full'] ?? [];
items.forEach(item => {
section.addText(`โข ${item}`);
});
});
pdf.addSection('Important Information', (section) => {
section.addText('โข This quote is valid for 14 days from the date of generation.');
section.addText('โข Appointment required - walk-ins subject to availability.');
section.addText('โข Please remove personal items before your appointment.');
section.addText('โข Additional charges may apply for excessive pet hair or stains.');
section.addSpacer(10);
section.addText('Questions? Contact us at hello@autodetailing.com');
});
});
}