export function mealPrepCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Meal Prep Service Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Meal Plan Section
const planSection = form.addSubform('plan', { title: '🍽️ Meal Plan' });
planSection.addRow(row => {
row.addDropdown('mealsPerDay', {
label: 'Meals per Day',
options: [
{ id: '2', name: '2 meals (lunch & dinner)' },
{ id: '3', name: '3 meals (breakfast, lunch & dinner)' },
{ id: '4', name: '4 meals (includes snack)' },
{ id: '5', name: '5 meals (multiple snacks)' }
],
defaultValue: '3',
isRequired: true
}, '1fr');
row.addDropdown('daysPerWeek', {
label: 'Days per Week',
options: [
{ id: '5', name: '5 days (weekdays)' },
{ id: '6', name: '6 days' },
{ id: '7', name: '7 days (full week)' }
],
defaultValue: '5',
isRequired: true
}, '1fr');
});
planSection.addRow(row => {
row.addDropdown('portionSize', {
label: 'Portion Size',
options: [
{ id: 'small', name: 'Small (300-400 cal)' },
{ id: 'regular', name: 'Regular (400-500 cal)' },
{ id: 'large', name: 'Large (500-600 cal)' },
{ id: 'athlete', name: 'Athlete (600-800 cal)' }
],
defaultValue: 'regular'
}, '1fr');
row.addInteger('numberOfPeople', {
label: 'Number of People',
min: 1,
max: 10,
defaultValue: 1,
tooltip: 'Family/household members'
}, '1fr');
});
// Dietary Section
const dietarySection = form.addSubform('dietary', { title: '🥗 Dietary Preferences' });
dietarySection.addRow(row => {
row.addDropdown('dietType', {
label: 'Diet Type',
options: [
{ id: 'standard', name: 'Standard / Balanced' },
{ id: 'keto', name: 'Keto / Low Carb' },
{ id: 'paleo', name: 'Paleo' },
{ id: 'vegan', name: 'Vegan' },
{ id: 'vegetarian', name: 'Vegetarian' },
{ id: 'mediterranean', name: 'Mediterranean' },
{ id: 'whole30', name: 'Whole30' },
{ id: 'custom', name: 'Custom Macros' }
],
defaultValue: 'standard',
isRequired: true
}, '1fr');
row.addDropdown('ingredientQuality', {
label: 'Ingredient Quality',
options: [
{ id: 'standard', name: 'Standard Quality' },
{ id: 'premium', name: 'Premium Quality' },
{ id: 'organic', name: 'Organic / Pasture-raised' }
],
defaultValue: 'standard'
}, '1fr');
});
dietarySection.addRow(row => {
row.addCheckbox('glutenFree', {
label: 'Gluten-Free',
defaultValue: false
}, '1fr');
row.addCheckbox('dairyFree', {
label: 'Dairy-Free',
defaultValue: false
}, '1fr');
});
dietarySection.addRow(row => {
row.addCheckbox('nutFree', {
label: 'Nut-Free',
defaultValue: false
}, '1fr');
row.addCheckbox('lowSodium', {
label: 'Low Sodium',
defaultValue: false
}, '1fr');
});
// Service Level Section
const serviceSection = form.addSubform('service', { title: '⭐ Service Level' });
serviceSection.addRow(row => {
row.addRadioButton('serviceType', {
label: 'Service Type',
options: [
{ id: 'basic', name: 'Basic - Prepared meals, standard menu' },
{ id: 'premium', name: 'Premium - Custom menu, variety' },
{ id: 'chef', name: 'Personal Chef - In-home cooking' }
],
defaultValue: 'premium',
isRequired: true
});
});
serviceSection.addRow(row => {
row.addCheckbox('mealPlanning', {
label: 'Nutritionist Meal Planning',
defaultValue: false,
tooltip: 'Custom plan by registered dietitian'
}, '1fr');
row.addCheckbox('macroTracking', {
label: 'Macro-counted Labels',
defaultValue: false,
tooltip: 'Detailed nutrition info per meal'
}, '1fr');
});
// Delivery Section
const deliverySection = form.addSubform('delivery', { title: '🚚 Delivery Options' });
deliverySection.addRow(row => {
row.addRadioButton('deliveryType', {
label: 'Delivery Method',
options: [
{ id: 'pickup', name: 'Pickup - No delivery fee' },
{ id: 'local', name: 'Local Delivery (within 10 miles)' },
{ id: 'extended', name: 'Extended Delivery (10-25 miles)' }
],
defaultValue: 'local'
});
});
deliverySection.addRow(row => {
row.addDropdown('deliveryFrequency', {
label: 'Delivery Frequency',
options: [
{ id: 'weekly', name: 'Once per week' },
{ id: 'twice', name: 'Twice per week' },
{ id: 'daily', name: 'Daily delivery' }
],
defaultValue: 'weekly',
isVisible: () => deliverySection.radioButton('deliveryType')?.value() !== 'pickup'
}, '1fr');
row.addCheckbox('ecofriendly', {
label: 'Eco-friendly Containers',
defaultValue: false,
tooltip: 'Reusable/compostable packaging'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Pricing Breakdown
const breakdownSection = form.addSubform('breakdown', { title: '📊 Price Breakdown', isCollapsible: true });
breakdownSection.addRow(row => {
row.addTextPanel('mealsPerWeek', {
label: 'Total Meals/Week',
computedValue: () => {
const mealsPerDay = parseInt(planSection.dropdown('mealsPerDay')?.value() || '3');
const daysPerWeek = parseInt(planSection.dropdown('daysPerWeek')?.value() || '5');
const people = planSection.integer('numberOfPeople')?.value() || 1;
return `${mealsPerDay * daysPerWeek * people} meals`;
},
customStyles: { 'font-size': '1rem', 'text-align': 'center', 'color': '#475569' }
}, '1fr');
row.addPriceDisplay('baseCostPerMeal', {
label: 'Base Cost/Meal',
computedValue: () => {
const serviceType = serviceSection.radioButton('serviceType')?.value() || 'premium';
const ingredientQuality = dietarySection.dropdown('ingredientQuality')?.value() || 'standard';
const portionSize = planSection.dropdown('portionSize')?.value() || 'regular';
// Base rates
const serviceRates: Record<string, number> = { 'basic': 10, 'premium': 14, 'chef': 22 };
let rate = serviceRates[serviceType] || 14;
// Quality multipliers
const qualityMultipliers: Record<string, number> = { 'standard': 1, 'premium': 1.25, 'organic': 1.5 };
rate *= qualityMultipliers[ingredientQuality] || 1;
// Portion size
const portionMultipliers: Record<string, number> = { 'small': 0.85, 'regular': 1, 'large': 1.2, 'athlete': 1.4 };
rate *= portionMultipliers[portionSize] || 1;
return Math.round(rate * 100) / 100;
},
variant: 'default'
}, '1fr');
});
breakdownSection.addRow(row => {
row.addPriceDisplay('dietaryAdjustment', {
label: 'Dietary Adjustments',
computedValue: () => {
const mealsPerDay = parseInt(planSection.dropdown('mealsPerDay')?.value() || '3');
const daysPerWeek = parseInt(planSection.dropdown('daysPerWeek')?.value() || '5');
const people = planSection.integer('numberOfPeople')?.value() || 1;
const totalMeals = mealsPerDay * daysPerWeek * people;
const dietType = dietarySection.dropdown('dietType')?.value() || 'standard';
const dietMultipliers: Record<string, number> = {
'standard': 0, 'keto': 2, 'paleo': 2.5, 'vegan': 1.5,
'vegetarian': 0.5, 'mediterranean': 1, 'whole30': 2, 'custom': 3
};
let adjustment = dietMultipliers[dietType] || 0;
// Allergen accommodations
if (dietarySection.checkbox('glutenFree')?.value()) adjustment += 1;
if (dietarySection.checkbox('dairyFree')?.value()) adjustment += 0.5;
if (dietarySection.checkbox('nutFree')?.value()) adjustment += 0.5;
if (dietarySection.checkbox('lowSodium')?.value()) adjustment += 0.5;
return Math.round(adjustment * totalMeals * 100) / 100;
},
variant: 'default'
}, '1fr');
row.addPriceDisplay('serviceAddons', {
label: 'Service Add-ons',
computedValue: () => {
let addons = 0;
if (serviceSection.checkbox('mealPlanning')?.value()) addons += 50;
if (serviceSection.checkbox('macroTracking')?.value()) addons += 25;
if (deliverySection.checkbox('ecofriendly')?.value()) addons += 15;
return addons;
},
variant: 'default'
}, '1fr');
});
// Quote Section
const quoteSection = form.addSubform('quote', { title: '💰 Your Quote', isCollapsible: false });
quoteSection.addRow(row => {
row.addPriceDisplay('costPerMeal', {
label: 'Cost per Meal',
computedValue: () => {
const serviceType = serviceSection.radioButton('serviceType')?.value() || 'premium';
const ingredientQuality = dietarySection.dropdown('ingredientQuality')?.value() || 'standard';
const portionSize = planSection.dropdown('portionSize')?.value() || 'regular';
const dietType = dietarySection.dropdown('dietType')?.value() || 'standard';
const serviceRates: Record<string, number> = { 'basic': 10, 'premium': 14, 'chef': 22 };
let rate = serviceRates[serviceType] || 14;
const qualityMultipliers: Record<string, number> = { 'standard': 1, 'premium': 1.25, 'organic': 1.5 };
rate *= qualityMultipliers[ingredientQuality] || 1;
const portionMultipliers: Record<string, number> = { 'small': 0.85, 'regular': 1, 'large': 1.2, 'athlete': 1.4 };
rate *= portionMultipliers[portionSize] || 1;
const dietMultipliers: Record<string, number> = {
'standard': 1, 'keto': 1.15, 'paleo': 1.2, 'vegan': 1.1,
'vegetarian': 1.05, 'mediterranean': 1.1, 'whole30': 1.15, 'custom': 1.25
};
rate *= dietMultipliers[dietType] || 1;
// Allergen adjustments
if (dietarySection.checkbox('glutenFree')?.value()) rate *= 1.08;
if (dietarySection.checkbox('dairyFree')?.value()) rate *= 1.05;
return Math.round(rate * 100) / 100;
},
variant: 'success'
}, '1fr');
row.addPriceDisplay('weeklyTotal', {
label: 'Weekly Total',
computedValue: () => {
const mealsPerDay = parseInt(planSection.dropdown('mealsPerDay')?.value() || '3');
const daysPerWeek = parseInt(planSection.dropdown('daysPerWeek')?.value() || '5');
const people = planSection.integer('numberOfPeople')?.value() || 1;
const totalMeals = mealsPerDay * daysPerWeek * people;
const serviceType = serviceSection.radioButton('serviceType')?.value() || 'premium';
const ingredientQuality = dietarySection.dropdown('ingredientQuality')?.value() || 'standard';
const portionSize = planSection.dropdown('portionSize')?.value() || 'regular';
const dietType = dietarySection.dropdown('dietType')?.value() || 'standard';
const deliveryType = deliverySection.radioButton('deliveryType')?.value() || 'local';
const deliveryFrequency = deliverySection.dropdown('deliveryFrequency')?.value() || 'weekly';
const serviceRates: Record<string, number> = { 'basic': 10, 'premium': 14, 'chef': 22 };
let rate = serviceRates[serviceType] || 14;
const qualityMultipliers: Record<string, number> = { 'standard': 1, 'premium': 1.25, 'organic': 1.5 };
rate *= qualityMultipliers[ingredientQuality] || 1;
const portionMultipliers: Record<string, number> = { 'small': 0.85, 'regular': 1, 'large': 1.2, 'athlete': 1.4 };
rate *= portionMultipliers[portionSize] || 1;
const dietMultipliers: Record<string, number> = {
'standard': 1, 'keto': 1.15, 'paleo': 1.2, 'vegan': 1.1,
'vegetarian': 1.05, 'mediterranean': 1.1, 'whole30': 1.15, 'custom': 1.25
};
rate *= dietMultipliers[dietType] || 1;
if (dietarySection.checkbox('glutenFree')?.value()) rate *= 1.08;
if (dietarySection.checkbox('dairyFree')?.value()) rate *= 1.05;
let total = rate * totalMeals;
// Add-ons
if (serviceSection.checkbox('mealPlanning')?.value()) total += 50;
if (serviceSection.checkbox('macroTracking')?.value()) total += 25;
if (deliverySection.checkbox('ecofriendly')?.value()) total += 15;
// Delivery
if (deliveryType === 'local') {
const deliveryFees: Record<string, number> = { 'weekly': 10, 'twice': 18, 'daily': 35 };
total += deliveryFees[deliveryFrequency] || 10;
} else if (deliveryType === 'extended') {
const deliveryFees: Record<string, number> = { 'weekly': 20, 'twice': 35, 'daily': 60 };
total += deliveryFees[deliveryFrequency] || 20;
}
return Math.round(total * 100) / 100;
},
variant: 'large'
}, '1fr');
});
quoteSection.addRow(row => {
row.addPriceDisplay('monthlyEstimate', {
label: 'Monthly Estimate',
computedValue: () => {
const mealsPerDay = parseInt(planSection.dropdown('mealsPerDay')?.value() || '3');
const daysPerWeek = parseInt(planSection.dropdown('daysPerWeek')?.value() || '5');
const people = planSection.integer('numberOfPeople')?.value() || 1;
const totalMeals = mealsPerDay * daysPerWeek * people;
const serviceType = serviceSection.radioButton('serviceType')?.value() || 'premium';
const ingredientQuality = dietarySection.dropdown('ingredientQuality')?.value() || 'standard';
const portionSize = planSection.dropdown('portionSize')?.value() || 'regular';
const dietType = dietarySection.dropdown('dietType')?.value() || 'standard';
const deliveryType = deliverySection.radioButton('deliveryType')?.value() || 'local';
const deliveryFrequency = deliverySection.dropdown('deliveryFrequency')?.value() || 'weekly';
const serviceRates: Record<string, number> = { 'basic': 10, 'premium': 14, 'chef': 22 };
let rate = serviceRates[serviceType] || 14;
const qualityMultipliers: Record<string, number> = { 'standard': 1, 'premium': 1.25, 'organic': 1.5 };
rate *= qualityMultipliers[ingredientQuality] || 1;
const portionMultipliers: Record<string, number> = { 'small': 0.85, 'regular': 1, 'large': 1.2, 'athlete': 1.4 };
rate *= portionMultipliers[portionSize] || 1;
const dietMultipliers: Record<string, number> = {
'standard': 1, 'keto': 1.15, 'paleo': 1.2, 'vegan': 1.1,
'vegetarian': 1.05, 'mediterranean': 1.1, 'whole30': 1.15, 'custom': 1.25
};
rate *= dietMultipliers[dietType] || 1;
if (dietarySection.checkbox('glutenFree')?.value()) rate *= 1.08;
if (dietarySection.checkbox('dairyFree')?.value()) rate *= 1.05;
let weekly = rate * totalMeals;
if (serviceSection.checkbox('mealPlanning')?.value()) weekly += 50;
if (serviceSection.checkbox('macroTracking')?.value()) weekly += 25;
if (deliverySection.checkbox('ecofriendly')?.value()) weekly += 15;
if (deliveryType === 'local') {
const deliveryFees: Record<string, number> = { 'weekly': 10, 'twice': 18, 'daily': 35 };
weekly += deliveryFees[deliveryFrequency] || 10;
} else if (deliveryType === 'extended') {
const deliveryFees: Record<string, number> = { 'weekly': 20, 'twice': 35, 'daily': 60 };
weekly += deliveryFees[deliveryFrequency] || 20;
}
return Math.round(weekly * 4.33 * 100) / 100;
},
variant: 'default'
});
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '🥙 Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addTextPanel('summaryText', {
computedValue: () => {
const mealsPerDay = parseInt(planSection.dropdown('mealsPerDay')?.value() || '3');
const daysPerWeek = parseInt(planSection.dropdown('daysPerWeek')?.value() || '5');
const people = planSection.integer('numberOfPeople')?.value() || 1;
const dietType = dietarySection.dropdown('dietType')?.value() || 'standard';
const dietLabels: Record<string, string> = {
'standard': 'balanced', 'keto': 'keto', 'paleo': 'paleo', 'vegan': 'vegan',
'vegetarian': 'vegetarian', 'mediterranean': 'Mediterranean', 'whole30': 'Whole30', 'custom': 'custom macro'
};
const totalMeals = mealsPerDay * daysPerWeek * people;
return `${totalMeals} ${dietLabels[dietType]} meals per week${people > 1 ? ` for ${people} people` : ''}`;
},
customStyles: { 'font-size': '0.95rem', 'font-weight': '500', 'text-align': 'center', 'color': '#1e293b' }
});
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Prices are estimates. Final cost may vary based on specific menu selections and ingredient availability.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Start My Plan'
});
}