export function subscriptionBoxCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Subscription Box Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Box Type Section
const boxSection = form.addSubform('box', { title: '📦 Box Details' });
boxSection.addRow(row => {
row.addDropdown('boxCategory', {
label: 'Box Category',
options: [
{ id: 'beauty', name: 'Beauty & Skincare' },
{ id: 'food', name: 'Food & Snacks' },
{ id: 'lifestyle', name: 'Lifestyle & Home' },
{ id: 'fitness', name: 'Fitness & Wellness' },
{ id: 'kids', name: 'Kids & Family' },
{ id: 'pets', name: 'Pet Products' },
{ id: 'books', name: 'Books & Media' },
{ id: 'hobby', name: 'Hobby & Craft' },
{ id: 'apparel', name: 'Fashion & Apparel' },
{ id: 'tech', name: 'Tech & Gadgets' }
],
defaultValue: 'lifestyle',
isRequired: true
}, '1fr');
row.addDropdown('boxTier', {
label: 'Box Tier',
options: [
{ id: 'budget', name: 'Budget ($15-25)' },
{ id: 'standard', name: 'Standard ($25-45)' },
{ id: 'premium', name: 'Premium ($45-75)' },
{ id: 'luxury', name: 'Luxury ($75+)' }
],
defaultValue: 'standard'
}, '1fr');
});
boxSection.addRow(row => {
row.addInteger('itemCount', {
label: 'Items per Box',
min: 1,
max: 20,
defaultValue: 5,
isRequired: true
}, '1fr');
row.addDropdown('frequency', {
label: 'Delivery Frequency',
options: [
{ id: 'weekly', name: 'Weekly' },
{ id: 'biweekly', name: 'Bi-Weekly' },
{ id: 'monthly', name: 'Monthly' },
{ id: 'bimonthly', name: 'Every 2 Months' },
{ id: 'quarterly', name: 'Quarterly' }
],
defaultValue: 'monthly'
}, '1fr');
});
// Product Costs Section
const productSection = form.addSubform('products', { title: '🛍️ Product Costs' });
productSection.addRow(row => {
row.addMoney('productCost', {
label: 'Total Product Cost (per box)',
min: 0,
max: 500,
defaultValue: 15,
currency: '$',
isRequired: true,
tooltip: 'Wholesale cost of all products in box'
}, '1fr');
row.addMoney('samplesCost', {
label: 'Samples/Extras Cost',
min: 0,
max: 50,
defaultValue: 2,
currency: '$',
tooltip: 'Cost of sample items, promotional materials'
}, '1fr');
});
productSection.addRow(row => {
row.addTextPanel('productPerItem', {
label: 'Average Cost per Item',
computedValue: () => {
const totalProduct = (productSection.money('productCost')?.value() ?? 15) +
(productSection.money('samplesCost')?.value() ?? 2);
const items = boxSection.integer('itemCount')?.value() ?? 5;
return `$${(Number(totalProduct / items) || 0).toFixed(2)}`;
},
customStyles: { 'font-size': '1rem', 'color': '#64748b' }
});
});
// Packaging Section
const packagingSection = form.addSubform('packaging', { title: '📦 Packaging' });
packagingSection.addRow(row => {
row.addDropdown('boxQuality', {
label: 'Box Quality',
options: [
{ id: 'basic', name: 'Basic Brown Box' },
{ id: 'printed', name: 'Printed Box' },
{ id: 'custom', name: 'Custom Branded Box' },
{ id: 'premium', name: 'Premium Gift Box' }
],
defaultValue: 'printed'
}, '1fr');
row.addMoney('boxCost', {
label: 'Box Cost',
min: 0,
max: 20,
defaultValue: 2.50,
currency: '$',
tooltip: 'Cost of outer shipping box'
}, '1fr');
});
packagingSection.addRow(row => {
row.addMoney('packingMaterials', {
label: 'Packing Materials',
min: 0,
max: 10,
defaultValue: 1,
currency: '$',
tooltip: 'Tissue paper, crinkle, void fill'
}, '1fr');
row.addMoney('insertsStickers', {
label: 'Inserts & Stickers',
min: 0,
max: 5,
defaultValue: 0.75,
currency: '$',
tooltip: 'Info cards, stickers, coupons'
}, '1fr');
});
// Shipping Section
const shippingSection = form.addSubform('shipping', { title: '🚚 Shipping & Fulfillment' });
shippingSection.addRow(row => {
row.addDropdown('shippingMethod', {
label: 'Primary Shipping',
options: [
{ id: 'usps-firstclass', name: 'USPS First Class (<1lb)' },
{ id: 'usps-priority', name: 'USPS Priority Mail' },
{ id: 'ups-ground', name: 'UPS Ground' },
{ id: 'fedex-ground', name: 'FedEx Ground' },
{ id: 'regional', name: 'Regional Carrier' }
],
defaultValue: 'usps-priority'
}, '1fr');
row.addMoney('avgShippingCost', {
label: 'Average Shipping Cost',
min: 0,
max: 50,
defaultValue: 8,
currency: '$',
tooltip: 'Average cost across all zones'
}, '1fr');
});
shippingSection.addRow(row => {
row.addDropdown('fulfillmentType', {
label: 'Fulfillment',
options: [
{ id: 'self', name: 'Self-Fulfillment' },
{ id: '3pl', name: '3PL/Fulfillment Center' },
{ id: 'hybrid', name: 'Hybrid' }
],
defaultValue: 'self'
}, '1fr');
row.addMoney('fulfillmentFee', {
label: 'Fulfillment Fee (per box)',
min: 0,
max: 20,
defaultValue: 3,
currency: '$',
tooltip: 'Pick, pack, and labor costs'
}, '1fr');
});
// Operational Costs Section
const operationsSection = form.addSubform('operations', { title: '⚙️ Operational Costs' });
operationsSection.addRow(row => {
row.addDecimal('paymentProcessing', {
label: 'Payment Processing (%)',
min: 0,
max: 10,
defaultValue: 2.9,
tooltip: 'Stripe, PayPal, etc. (typically 2.9% + $0.30)'
}, '1fr');
row.addMoney('platformFees', {
label: 'Platform/Software Fees',
min: 0,
max: 10,
defaultValue: 1,
currency: '$',
tooltip: 'Cratejoy, Subbly, etc. per order'
}, '1fr');
});
operationsSection.addRow(row => {
row.addMoney('customerService', {
label: 'Customer Service (per box)',
min: 0,
max: 5,
defaultValue: 0.50,
currency: '$',
tooltip: 'Allocated CS costs per order'
}, '1fr');
row.addDecimal('returns', {
label: 'Returns/Replacements (%)',
min: 0,
max: 20,
defaultValue: 3,
tooltip: 'Percentage for damaged/lost boxes'
}, '1fr');
});
// Pricing Strategy Section
const pricingSection = form.addSubform('pricing', { title: '💲 Pricing Strategy' });
pricingSection.addRow(row => {
row.addDropdown('pricingModel', {
label: 'Pricing Model',
options: [
{ id: 'margin', name: 'Set Target Margin' },
{ id: 'price', name: 'Set Retail Price' }
],
defaultValue: 'margin'
});
});
pricingSection.addRow(row => {
row.addDecimal('targetMargin', {
label: 'Target Gross Margin (%)',
min: 10,
max: 80,
defaultValue: 50,
isVisible: () => pricingSection.dropdown('pricingModel')?.value() === 'margin'
}, '1fr');
row.addMoney('retailPrice', {
label: 'Retail Price',
min: 10,
max: 500,
defaultValue: 39.99,
currency: '$',
isVisible: () => pricingSection.dropdown('pricingModel')?.value() === 'price'
}, '1fr');
});
pricingSection.addRow(row => {
row.addCheckbox('freeShipping', {
label: 'Include Free Shipping',
defaultValue: true,
tooltip: 'Shipping included in subscription price'
}, '1fr');
row.addDecimal('subscriptionDiscount', {
label: 'Prepaid Subscription Discount (%)',
min: 0,
max: 30,
defaultValue: 10,
tooltip: 'Discount for 3/6/12 month prepaid'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Results Section
const resultsSection = form.addSubform('results', { title: '📊 Cost Analysis', isCollapsible: false });
const calculateCosts = () => {
// Product costs
const productCost = productSection.money('productCost')?.value() || 15;
const samplesCost = productSection.money('samplesCost')?.value() || 2;
const totalProductCost = productCost + samplesCost;
// Packaging costs
const boxCost = packagingSection.money('boxCost')?.value() || 2.50;
const packingMaterials = packagingSection.money('packingMaterials')?.value() || 1;
const insertsStickers = packagingSection.money('insertsStickers')?.value() || 0.75;
const totalPackagingCost = boxCost + packingMaterials + insertsStickers;
// Shipping & fulfillment
const shippingCost = shippingSection.money('avgShippingCost')?.value() || 8;
const fulfillmentFee = shippingSection.money('fulfillmentFee')?.value() || 3;
const totalShippingCost = shippingCost + fulfillmentFee;
// Base cost before operations
const baseCost = totalProductCost + totalPackagingCost + totalShippingCost;
// Operational costs
const customerService = operationsSection.money('customerService')?.value() || 0.50;
const platformFees = operationsSection.money('platformFees')?.value() || 1;
const returnsRate = (operationsSection.decimal('returns')?.value() || 3) / 100;
const returnsAllocation = baseCost * returnsRate;
const operationalCosts = customerService + platformFees + returnsAllocation;
// Total cost before payment processing
const costBeforeProcessing = baseCost + operationalCosts;
// Pricing calculation
const pricingModel = pricingSection.dropdown('pricingModel')?.value() || 'margin';
const freeShipping = pricingSection.checkbox('freeShipping')?.value() || false;
const processingRate = (operationsSection.decimal('paymentProcessing')?.value() || 2.9) / 100;
let retailPrice = 0;
let grossMargin = 0;
if (pricingModel === 'margin') {
const targetMargin = (pricingSection.decimal('targetMargin')?.value() || 50) / 100;
// Price = Cost / (1 - margin - processing)
retailPrice = costBeforeProcessing / (1 - targetMargin - processingRate);
grossMargin = targetMargin;
} else {
retailPrice = pricingSection.money('retailPrice')?.value() || 39.99;
const processingFee = retailPrice * processingRate + 0.30;
const totalCost = costBeforeProcessing + processingFee;
grossMargin = (retailPrice - totalCost) / retailPrice;
}
const processingFee = retailPrice * processingRate + 0.30;
const totalCostPerBox = costBeforeProcessing + processingFee;
const profitPerBox = retailPrice - totalCostPerBox;
// Prepaid pricing
const subscriptionDiscount = (pricingSection.decimal('subscriptionDiscount')?.value() || 10) / 100;
const prepaidPrice = retailPrice * (1 - subscriptionDiscount);
const prepaidProfit = prepaidPrice - totalCostPerBox;
return {
productCost: totalProductCost,
packagingCost: totalPackagingCost,
shippingCost: totalShippingCost,
operationalCosts,
processingFee,
totalCostPerBox: Math.round(totalCostPerBox * 100) / 100,
retailPrice: Math.round(retailPrice * 100) / 100,
profitPerBox: Math.round(profitPerBox * 100) / 100,
grossMargin: Math.round(grossMargin * 1000) / 10,
prepaidPrice: Math.round(prepaidPrice * 100) / 100,
prepaidProfit: Math.round(prepaidProfit * 100) / 100
};
};
resultsSection.addRow(row => {
row.addPriceDisplay('productCost', {
label: 'Product Cost',
computedValue: () => calculateCosts().productCost,
variant: 'default'
}, '1fr');
row.addPriceDisplay('packagingCost', {
label: 'Packaging Cost',
computedValue: () => calculateCosts().packagingCost,
variant: 'default'
}, '1fr');
});
resultsSection.addRow(row => {
row.addPriceDisplay('shippingCost', {
label: 'Shipping & Fulfillment',
computedValue: () => calculateCosts().shippingCost,
variant: 'default'
}, '1fr');
row.addPriceDisplay('operationalCosts', {
label: 'Operational Costs',
computedValue: () => calculateCosts().operationalCosts,
variant: 'default'
}, '1fr');
});
resultsSection.addRow(row => {
row.addPriceDisplay('totalCost', {
label: 'Total Cost per Box',
computedValue: () => calculateCosts().totalCostPerBox,
variant: 'default'
});
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '💰 Pricing Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addPriceDisplay('retailPrice', {
label: 'Recommended Price',
computedValue: () => calculateCosts().retailPrice,
variant: 'large'
}, '1fr');
row.addTextPanel('margin', {
label: 'Gross Margin',
computedValue: () => `${calculateCosts().grossMargin}%`,
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'text-align': 'center', 'color': '#059669' }
}, '1fr');
});
summarySection.addRow(row => {
row.addPriceDisplay('profitPerBox', {
label: 'Profit per Box',
computedValue: () => calculateCosts().profitPerBox,
variant: 'success'
}, '1fr');
row.addPriceDisplay('prepaidPrice', {
label: 'Prepaid Price (discounted)',
computedValue: () => calculateCosts().prepaidPrice,
variant: 'default'
}, '1fr');
});
summarySection.addRow(row => {
row.addTextPanel('note', {
computedValue: () => 'Remember to account for marketing costs (typically 10-20% of revenue) in your overall business plan.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Create Business Plan'
});
}