export function laserHairRemovalCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Laser Hair Removal Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Treatment Areas Section
const areasSection = form.addSubform('areas', { title: '๐ Treatment Areas' });
areasSection.addRow(row => {
row.addTextPanel('faceLabel', {
computedValue: () => 'Face & Neck',
customStyles: { 'font-weight': '600', 'color': '#475569' }
});
});
areasSection.addRow(row => {
row.addCheckbox('upperLip', { label: 'Upper Lip', defaultValue: false }, '1fr');
row.addCheckbox('chin', { label: 'Chin', defaultValue: false }, '1fr');
row.addCheckbox('sideburns', { label: 'Sideburns', defaultValue: false }, '1fr');
});
areasSection.addRow(row => {
row.addCheckbox('fullFace', { label: 'Full Face', defaultValue: false }, '1fr');
row.addCheckbox('neck', { label: 'Neck', defaultValue: false }, '1fr');
row.addCheckbox('neckBack', { label: 'Back of Neck', defaultValue: false }, '1fr');
});
areasSection.addSpacer({ height: 10 });
areasSection.addRow(row => {
row.addTextPanel('bodyLabel', {
computedValue: () => 'Body',
customStyles: { 'font-weight': '600', 'color': '#475569' }
});
});
areasSection.addRow(row => {
row.addCheckbox('underarms', { label: 'Underarms', defaultValue: true }, '1fr');
row.addCheckbox('arms', { label: 'Full Arms', defaultValue: false }, '1fr');
row.addCheckbox('halfArms', { label: 'Half Arms', defaultValue: false }, '1fr');
});
areasSection.addRow(row => {
row.addCheckbox('chest', { label: 'Chest', defaultValue: false }, '1fr');
row.addCheckbox('stomach', { label: 'Stomach/Abdomen', defaultValue: false }, '1fr');
row.addCheckbox('fullBack', { label: 'Full Back', defaultValue: false }, '1fr');
});
areasSection.addRow(row => {
row.addCheckbox('shoulders', { label: 'Shoulders', defaultValue: false }, '1fr');
row.addCheckbox('lowerBack', { label: 'Lower Back', defaultValue: false }, '1fr');
row.addCheckbox('hands', { label: 'Hands/Fingers', defaultValue: false }, '1fr');
});
areasSection.addSpacer({ height: 10 });
areasSection.addRow(row => {
row.addTextPanel('lowerLabel', {
computedValue: () => 'Lower Body',
customStyles: { 'font-weight': '600', 'color': '#475569' }
});
});
areasSection.addRow(row => {
row.addCheckbox('bikini', { label: 'Bikini Line', defaultValue: false }, '1fr');
row.addCheckbox('brazilian', { label: 'Brazilian', defaultValue: false }, '1fr');
row.addCheckbox('buttocks', { label: 'Buttocks', defaultValue: false }, '1fr');
});
areasSection.addRow(row => {
row.addCheckbox('fullLegs', { label: 'Full Legs', defaultValue: false }, '1fr');
row.addCheckbox('upperLegs', { label: 'Upper Legs/Thighs', defaultValue: false }, '1fr');
row.addCheckbox('lowerLegs', { label: 'Lower Legs', defaultValue: false }, '1fr');
});
areasSection.addRow(row => {
row.addCheckbox('feet', { label: 'Feet/Toes', defaultValue: false }, '1fr');
});
// Client Profile Section
const profileSection = form.addSubform('profile', { title: '๐ค Client Profile' });
profileSection.addRow(row => {
row.addDropdown('skinType', {
label: 'Skin Type (Fitzpatrick Scale)',
options: [
{ id: 'type1', name: 'Type I - Very Fair (always burns)' },
{ id: 'type2', name: 'Type II - Fair (usually burns)' },
{ id: 'type3', name: 'Type III - Medium (sometimes burns)' },
{ id: 'type4', name: 'Type IV - Olive (rarely burns)' },
{ id: 'type5', name: 'Type V - Brown (very rarely burns)' },
{ id: 'type6', name: 'Type VI - Dark Brown/Black (never burns)' }
],
defaultValue: 'type3',
isRequired: true
}, '1fr');
});
profileSection.addRow(row => {
row.addDropdown('hairColor', {
label: 'Hair Color',
options: [
{ id: 'black', name: 'Black' },
{ id: 'dark-brown', name: 'Dark Brown' },
{ id: 'light-brown', name: 'Light Brown' },
{ id: 'red', name: 'Red/Auburn' },
{ id: 'blonde', name: 'Blonde' },
{ id: 'grey', name: 'Grey/White' }
],
defaultValue: 'dark-brown',
isRequired: true
}, '1fr');
row.addDropdown('hairDensity', {
label: 'Hair Density',
options: [
{ id: 'sparse', name: 'Sparse/Fine' },
{ id: 'moderate', name: 'Moderate' },
{ id: 'dense', name: 'Dense/Coarse' }
],
defaultValue: 'moderate'
}, '1fr');
});
// Package Section
const packageSection = form.addSubform('package', { title: '๐ฆ Treatment Package' });
packageSection.addRow(row => {
row.addDropdown('sessions', {
label: 'Number of Sessions',
options: [
{ id: '1', name: 'Single Session' },
{ id: '3', name: '3 Sessions Package (10% off)' },
{ id: '6', name: '6 Sessions Package (20% off)' },
{ id: '8', name: '8 Sessions Package (25% off)' },
{ id: '12', name: '12 Sessions Package (30% off)' }
],
defaultValue: '6',
isRequired: true
}, '1fr');
});
packageSection.addRow(row => {
row.addDropdown('technology', {
label: 'Laser Technology',
options: [
{ id: 'diode', name: 'Diode Laser (Standard)' },
{ id: 'alexandrite', name: 'Alexandrite (Light Skin)' },
{ id: 'ndyag', name: 'Nd:YAG (Dark Skin Safe)' },
{ id: 'ipl', name: 'IPL (Intense Pulsed Light)' }
],
defaultValue: 'diode'
}, '1fr');
});
// Add-ons Section
const addonsSection = form.addSubform('addons', { title: 'โจ Additional Services' });
addonsSection.addRow(row => {
row.addCheckbox('consultation', {
label: 'Initial Consultation (credited to treatment)',
defaultValue: false
}, '1fr');
row.addCheckbox('testPatch', {
label: 'Test Patch Session',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('numbing', {
label: 'Topical Numbing Cream',
defaultValue: false
}, '1fr');
row.addCheckbox('cooling', {
label: 'Advanced Cooling System',
defaultValue: false
}, '1fr');
});
addonsSection.addRow(row => {
row.addCheckbox('aftercare', {
label: 'Aftercare Kit',
defaultValue: false
}, '1fr');
row.addCheckbox('maintenance', {
label: 'Annual Maintenance Plan',
defaultValue: false
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Pricing Section
const pricingSection = form.addSubform('pricing', { title: '๐ฐ Pricing', isCollapsible: false });
const calculatePrice = () => {
const sessions = parseInt(packageSection.dropdown('sessions')?.value() || '6');
const technology = packageSection.dropdown('technology')?.value() || 'diode';
const skinType = profileSection.dropdown('skinType')?.value() || 'type3';
const hairColor = profileSection.dropdown('hairColor')?.value() || 'dark-brown';
const hairDensity = profileSection.dropdown('hairDensity')?.value() || 'moderate';
// Area prices per session
const areaPrices: Record<string, number> = {
'upperLip': 75,
'chin': 75,
'sideburns': 85,
'fullFace': 250,
'neck': 125,
'neckBack': 100,
'underarms': 125,
'arms': 300,
'halfArms': 175,
'chest': 275,
'stomach': 225,
'fullBack': 400,
'shoulders': 175,
'lowerBack': 200,
'hands': 75,
'bikini': 175,
'brazilian': 275,
'buttocks': 200,
'fullLegs': 450,
'upperLegs': 275,
'lowerLegs': 250,
'feet': 75
};
// Calculate selected areas total
let areasTotal = 0;
let selectedAreas: string[] = [];
Object.keys(areaPrices).forEach(area => {
if (areasSection.checkbox(area)?.value()) {
areasTotal += areaPrices[area] || 0;
selectedAreas.push(area);
}
});
// Technology multiplier
const techMult: Record<string, number> = {
'diode': 1.0,
'alexandrite': 1.1,
'ndyag': 1.15,
'ipl': 0.85
};
areasTotal *= techMult[technology] || 1.0;
// Hair color effectiveness (lighter hair needs more sessions)
const hairMult: Record<string, number> = {
'black': 0.95,
'dark-brown': 1.0,
'light-brown': 1.1,
'red': 1.2,
'blonde': 1.3,
'grey': 1.4
};
// Density multiplier
const densityMult: Record<string, number> = {
'sparse': 0.9,
'moderate': 1.0,
'dense': 1.15
};
// Per session price adjusted
let perSessionPrice = areasTotal * (hairMult[hairColor] || 1.0) * (densityMult[hairDensity] || 1.0);
// Package discount
const packageDiscount: Record<string, number> = {
'1': 0,
'3': 0.10,
'6': 0.20,
'8': 0.25,
'12': 0.30
};
const discount = packageDiscount[sessions.toString()] || 0;
// Full package price
let packagePrice = perSessionPrice * sessions * (1 - discount);
// Add-ons
let addonsPrice = 0;
if (addonsSection.checkbox('consultation')?.value()) addonsPrice += 50; // Usually credited
if (addonsSection.checkbox('testPatch')?.value()) addonsPrice += 25;
if (addonsSection.checkbox('numbing')?.value()) addonsPrice += 25 * sessions;
if (addonsSection.checkbox('cooling')?.value()) addonsPrice += 15 * sessions;
if (addonsSection.checkbox('aftercare')?.value()) addonsPrice += 45;
if (addonsSection.checkbox('maintenance')?.value()) addonsPrice += 299;
const total = packagePrice + addonsPrice;
return {
perSessionPrice: Math.round(perSessionPrice),
sessions,
discount: Math.round(discount * 100),
packagePrice: Math.round(packagePrice),
addonsPrice: Math.round(addonsPrice),
total: Math.round(total),
pricePerSession: Math.round(packagePrice / sessions),
selectedAreasCount: selectedAreas.length
};
};
pricingSection.addRow(row => {
row.addPriceDisplay('perSession', {
label: 'Per Session (before discount)',
computedValue: () => calculatePrice().perSessionPrice,
variant: 'default',
isVisible: () => calculatePrice().selectedAreasCount > 0
}, '1fr');
row.addTextPanel('sessions', {
computedValue: () => {
const price = calculatePrice();
return `ร ${price.sessions} sessions`;
},
customStyles: { 'font-size': '1rem', 'color': '#64748b', 'align-self': 'center' },
isVisible: () => calculatePrice().selectedAreasCount > 0
}, '1fr');
});
pricingSection.addRow(row => {
row.addTextPanel('discount', {
computedValue: () => {
const price = calculatePrice();
if (price.discount > 0) {
return `Package Discount: ${price.discount}% off`;
}
return '';
},
customStyles: { 'font-size': '0.95rem', 'color': '#16a34a', 'font-weight': '500' },
isVisible: () => calculatePrice().discount > 0
});
});
pricingSection.addRow(row => {
row.addPriceDisplay('package', {
label: 'Package Total',
computedValue: () => calculatePrice().packagePrice,
variant: 'default',
isVisible: () => calculatePrice().selectedAreasCount > 0
}, '1fr');
row.addPriceDisplay('addons', {
label: 'Add-ons',
computedValue: () => calculatePrice().addonsPrice,
variant: 'default',
isVisible: () => calculatePrice().addonsPrice > 0
}, '1fr');
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '๐งพ Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addPriceDisplay('total', {
label: 'Total Investment',
computedValue: () => calculatePrice().total,
variant: 'large'
}, '1fr');
row.addTextPanel('perSessionFinal', {
computedValue: () => {
const price = calculatePrice();
if (price.selectedAreasCount > 0) {
return `$${price.pricePerSession}/session`;
}
return 'Select areas above';
},
customStyles: { 'font-size': '1rem', 'color': '#64748b', 'text-align': 'center', 'align-self': 'center' }
}, '1fr');
});
summarySection.addRow(row => {
row.addTextPanel('note', {
computedValue: () => 'Results vary by individual. A consultation is recommended to determine the optimal treatment plan for your skin and hair type. Financing options may be available.',
customStyles: { 'font-size': '0.85rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Book Consultation'
});
}