export function websiteCostCalculator(form: FormTs) {
// Base prices by website type
const websiteTypePrices: Record<string, number> = {
'landing': 1500,
'business': 3500,
'ecommerce': 8000,
'webapp': 15000,
'custom': 25000
};
// Feature costs
const featureCosts: Record<string, number> = {
'cms': 1500,
'blog': 800,
'contact': 300,
'newsletter': 500,
'search': 1000,
'multilingual': 2000,
'analytics': 400,
'seo': 1200,
'socialIntegration': 600,
'chat': 800,
'booking': 2500,
'membership': 3000,
'api': 2500,
'payment': 1500
};
// Pages included by type
const includedPages: Record<string, number> = {
'landing': 1,
'business': 5,
'ecommerce': 8,
'webapp': 10,
'custom': 15
};
// Design multipliers
const designMultipliers: Record<string, number> = {
'template': 0.8,
'semi-custom': 1,
'custom': 1.4,
'premium': 2.0
};
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Website Development Cost Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Project Type Section
const projectSection = form.addSubform('project', { title: '๐ Project Type' });
projectSection.addRow(row => {
row.addRadioButton('websiteType', {
label: 'What type of website do you need?',
options: [
{ id: 'landing', name: 'Landing Page - Single page, marketing focused ($1,500+)' },
{ id: 'business', name: 'Business Website - Multi-page company site ($3,500+)' },
{ id: 'ecommerce', name: 'E-commerce Store - Online shop with products ($8,000+)' },
{ id: 'webapp', name: 'Web Application - Interactive app with user accounts ($15,000+)' },
{ id: 'custom', name: 'Custom/Enterprise - Complex, tailored solution ($25,000+)' }
],
defaultValue: 'business',
orientation: 'vertical',
isRequired: true
});
});
// Pages & Content Section
const contentSection = form.addSubform('content', { title: '๐ Pages & Content' });
contentSection.addRow(row => {
row.addSlider('pageCount', {
label: 'Number of Pages',
min: 1,
max: 50,
step: 1,
defaultValue: 5,
showValue: true,
unit: 'pages'
}, '1fr');
row.addDropdown('contentSource', {
label: 'Content Provided By',
options: [
{ id: 'client', name: 'Client provides all content' },
{ id: 'partial', name: 'Client provides some, we write rest (+30%)' },
{ id: 'agency', name: 'Full copywriting needed (+50%)' }
],
defaultValue: 'client'
}, '1fr');
});
contentSection.addRow(row => {
row.addDropdown('designLevel', {
label: 'Design Level',
options: [
{ id: 'template', name: 'Template-based design' },
{ id: 'semi-custom', name: 'Semi-custom design (+40%)' },
{ id: 'custom', name: 'Fully custom design (+80%)' },
{ id: 'premium', name: 'Premium/Award-worthy (+150%)' }
],
defaultValue: 'semi-custom'
}, '1fr');
row.addCheckbox('responsive', {
label: 'Mobile Responsive (Required)',
defaultValue: true,
isReadOnly: true
}, '1fr');
});
// Features Section
const featuresSection = form.addSubform('features', { title: 'โ๏ธ Features & Functionality' });
featuresSection.addRow(row => {
row.addCheckbox('cms', {
label: 'Content Management System (+$1,500)',
defaultValue: true
}, '1fr');
row.addCheckbox('blog', {
label: 'Blog / News Section (+$800)',
defaultValue: false
}, '1fr');
});
featuresSection.addRow(row => {
row.addCheckbox('contact', {
label: 'Contact Form (+$300)',
defaultValue: true
}, '1fr');
row.addCheckbox('newsletter', {
label: 'Newsletter Signup (+$500)',
defaultValue: false
}, '1fr');
});
featuresSection.addRow(row => {
row.addCheckbox('search', {
label: 'Site Search (+$1,000)',
defaultValue: false
}, '1fr');
row.addCheckbox('multilingual', {
label: 'Multi-language Support (+$2,000)',
defaultValue: false
}, '1fr');
});
featuresSection.addRow(row => {
row.addCheckbox('analytics', {
label: 'Analytics Setup (+$400)',
defaultValue: true
}, '1fr');
row.addCheckbox('seo', {
label: 'SEO Optimization (+$1,200)',
defaultValue: true
}, '1fr');
});
featuresSection.addRow(row => {
row.addCheckbox('socialIntegration', {
label: 'Social Media Integration (+$600)',
defaultValue: false
}, '1fr');
row.addCheckbox('chat', {
label: 'Live Chat Widget (+$800)',
defaultValue: false
}, '1fr');
});
// Advanced Features (conditional)
const advancedSection = form.addSubform('advanced', {
title: '๐ Advanced Features',
isVisible: () => {
const type = projectSection.radioButton('websiteType')?.value();
return type === 'ecommerce' || type === 'webapp' || type === 'custom';
}
});
advancedSection.addRow(row => {
row.addCheckbox('booking', {
label: 'Booking/Scheduling System (+$2,500)',
defaultValue: false
}, '1fr');
row.addCheckbox('membership', {
label: 'User Accounts/Membership (+$3,000)',
defaultValue: false
}, '1fr');
});
advancedSection.addRow(row => {
row.addCheckbox('api', {
label: 'API Integration (+$2,500)',
defaultValue: false
}, '1fr');
row.addCheckbox('payment', {
label: 'Payment Processing (+$1,500)',
defaultValue: false
}, '1fr');
});
// E-commerce specific
const ecommerceSection = form.addSubform('ecommerce', {
title: '๐ E-commerce Details',
isVisible: () => projectSection.radioButton('websiteType')?.value() === 'ecommerce'
});
ecommerceSection.addRow(row => {
row.addSlider('productCount', {
label: 'Number of Products',
min: 1,
max: 500,
step: 10,
defaultValue: 50,
showValue: true,
unit: 'products'
}, '1fr');
row.addDropdown('ecommercePlatform', {
label: 'Preferred Platform',
options: [
{ id: 'shopify', name: 'Shopify' },
{ id: 'woocommerce', name: 'WooCommerce' },
{ id: 'magento', name: 'Magento (+$5,000)' },
{ id: 'custom', name: 'Custom Solution (+$10,000)' }
],
defaultValue: 'shopify'
}, '1fr');
});
// Timeline Section
const timelineSection = form.addSubform('timeline', { title: '๐
Project Timeline' });
timelineSection.addRow(row => {
row.addRadioButton('urgency', {
label: 'How soon do you need it?',
options: [
{ id: 'flexible', name: 'Flexible timeline (Standard pricing)' },
{ id: 'standard', name: '4-8 weeks (Standard pricing)' },
{ id: 'rush', name: '2-4 weeks (Rush +25%)' },
{ id: 'urgent', name: 'Under 2 weeks (Urgent +50%)' }
],
defaultValue: 'standard',
orientation: 'vertical'
});
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Price Summary
const summarySection = form.addSubform('summary', { title: '๐ฐ Estimated Investment', isCollapsible: false });
summarySection.addRow(row => {
row.addPriceDisplay('basePrice', {
label: 'Base Website Price',
computedValue: () => {
const type = projectSection.radioButton('websiteType')?.value() || 'business';
return websiteTypePrices[type] || 3500;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('pagesPrice', {
label: 'Additional Pages',
computedValue: () => {
const type = projectSection.radioButton('websiteType')?.value() || 'business';
const pageCount = contentSection.slider('pageCount')?.value() || 5;
const included = includedPages[type] || 5;
const extraPages = Math.max(0, pageCount - included);
const pricePerPage = type === 'custom' ? 400 : type === 'webapp' ? 350 : 250;
return extraPages * pricePerPage;
},
variant: 'default',
prefix: '+'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('designPrice', {
label: 'Design Level Adjustment',
computedValue: () => {
const type = projectSection.radioButton('websiteType')?.value() || 'business';
const basePrice = websiteTypePrices[type] || 3500;
const designLevel = contentSection.dropdown('designLevel')?.value() || 'semi-custom';
const designAdjustments: Record<string, number> = {
'template': -0.2,
'semi-custom': 0,
'custom': 0.4,
'premium': 1.0
};
return Math.round(basePrice * (designAdjustments[designLevel] || 0));
},
variant: 'default',
prefix: () => {
const designLevel = contentSection.dropdown('designLevel')?.value();
return designLevel === 'template' ? '' : '+';
}
}, '1fr');
row.addPriceDisplay('contentPrice', {
label: 'Content Writing',
computedValue: () => {
const pageCount = contentSection.slider('pageCount')?.value() || 5;
const contentSource = contentSection.dropdown('contentSource')?.value() || 'client';
if (contentSource === 'client') return 0;
const pricePerPage = contentSource === 'partial' ? 150 : 300;
return pageCount * pricePerPage;
},
variant: 'default',
prefix: '+'
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('featuresPrice', {
label: 'Features & Add-ons',
computedValue: () => {
let total = 0;
if (featuresSection.checkbox('cms')?.value()) total += featureCosts['cms'];
if (featuresSection.checkbox('blog')?.value()) total += featureCosts['blog'];
if (featuresSection.checkbox('contact')?.value()) total += featureCosts['contact'];
if (featuresSection.checkbox('newsletter')?.value()) total += featureCosts['newsletter'];
if (featuresSection.checkbox('search')?.value()) total += featureCosts['search'];
if (featuresSection.checkbox('multilingual')?.value()) total += featureCosts['multilingual'];
if (featuresSection.checkbox('analytics')?.value()) total += featureCosts['analytics'];
if (featuresSection.checkbox('seo')?.value()) total += featureCosts['seo'];
if (featuresSection.checkbox('socialIntegration')?.value()) total += featureCosts['socialIntegration'];
if (featuresSection.checkbox('chat')?.value()) total += featureCosts['chat'];
if (advancedSection.checkbox('booking')?.value()) total += featureCosts['booking'];
if (advancedSection.checkbox('membership')?.value()) total += featureCosts['membership'];
if (advancedSection.checkbox('api')?.value()) total += featureCosts['api'];
if (advancedSection.checkbox('payment')?.value()) total += featureCosts['payment'];
return total;
},
variant: 'default',
prefix: '+'
}, '1fr');
row.addPriceDisplay('ecommercePrice', {
label: 'E-commerce Add-ons',
computedValue: () => {
const type = projectSection.radioButton('websiteType')?.value();
if (type !== 'ecommerce') return 0;
let total = 0;
const productCount = ecommerceSection.slider('productCount')?.value() || 50;
const platform = ecommerceSection.dropdown('ecommercePlatform')?.value() || 'shopify';
total += Math.max(0, productCount - 20) * 15;
if (platform === 'magento') total += 5000;
if (platform === 'custom') total += 10000;
return total;
},
variant: 'default',
prefix: '+',
isVisible: () => projectSection.radioButton('websiteType')?.value() === 'ecommerce'
}, '1fr');
});
const finalSection = form.addSubform('final', {
title: '๐งพ Summary',
isCollapsible: false,
sticky: 'bottom'
});
finalSection.addRow(row => {
row.addPriceDisplay('totalEstimate', {
label: 'Total Estimated Cost',
computedValue: () => {
const type = projectSection.radioButton('websiteType')?.value() || 'business';
let total = websiteTypePrices[type] || 3500;
// Pages
const pageCount = contentSection.slider('pageCount')?.value() || 5;
const extraPages = Math.max(0, pageCount - (includedPages[type] || 5));
const pricePerPage = type === 'custom' ? 400 : type === 'webapp' ? 350 : 250;
total += extraPages * pricePerPage;
// Design level
const designLevel = contentSection.dropdown('designLevel')?.value() || 'semi-custom';
total *= designMultipliers[designLevel] || 1;
// Content
const contentSource = contentSection.dropdown('contentSource')?.value() || 'client';
if (contentSource === 'partial') total += pageCount * 150;
if (contentSource === 'agency') total += pageCount * 300;
// Features
if (featuresSection.checkbox('cms')?.value()) total += featureCosts['cms'];
if (featuresSection.checkbox('blog')?.value()) total += featureCosts['blog'];
if (featuresSection.checkbox('contact')?.value()) total += featureCosts['contact'];
if (featuresSection.checkbox('newsletter')?.value()) total += featureCosts['newsletter'];
if (featuresSection.checkbox('search')?.value()) total += featureCosts['search'];
if (featuresSection.checkbox('multilingual')?.value()) total += featureCosts['multilingual'];
if (featuresSection.checkbox('analytics')?.value()) total += featureCosts['analytics'];
if (featuresSection.checkbox('seo')?.value()) total += featureCosts['seo'];
if (featuresSection.checkbox('socialIntegration')?.value()) total += featureCosts['socialIntegration'];
if (featuresSection.checkbox('chat')?.value()) total += featureCosts['chat'];
if (advancedSection.checkbox('booking')?.value()) total += featureCosts['booking'];
if (advancedSection.checkbox('membership')?.value()) total += featureCosts['membership'];
if (advancedSection.checkbox('api')?.value()) total += featureCosts['api'];
if (advancedSection.checkbox('payment')?.value()) total += featureCosts['payment'];
// E-commerce extras
if (type === 'ecommerce') {
const productCount = ecommerceSection.slider('productCount')?.value() || 50;
const platform = ecommerceSection.dropdown('ecommercePlatform')?.value() || 'shopify';
total += Math.max(0, productCount - 20) * 15;
if (platform === 'magento') total += 5000;
if (platform === 'custom') total += 10000;
}
// Rush delivery
const urgency = timelineSection.radioButton('urgency')?.value() || 'standard';
if (urgency === 'rush') total *= 1.25;
if (urgency === 'urgent') total *= 1.50;
return Math.round(total);
},
variant: 'large'
});
});
finalSection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Final pricing confirmed after discovery call.',
customStyles: { 'font-size': '0.85rem', 'color': '#64748b', 'font-style': 'italic' }
});
});
form.configureSubmitButton({
label: 'Get Detailed Quote'
});
}