export function packageDimensionCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Package Dimension Calculator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Package Dimensions Section
const dimensionsSection = form.addSubform('dimensions', { title: '📦 Package Dimensions' });
dimensionsSection.addRow(row => {
row.addDropdown('unitSystem', {
label: 'Unit System',
options: [
{ id: 'imperial', name: 'Imperial (inches/lbs)' },
{ id: 'metric', name: 'Metric (cm/kg)' }
],
defaultValue: 'imperial',
isRequired: true
}, '1fr');
row.addDropdown('packageShape', {
label: 'Package Shape',
options: [
{ id: 'box', name: 'Box/Rectangular' },
{ id: 'tube', name: 'Tube/Cylinder' },
{ id: 'irregular', name: 'Irregular Shape' }
],
defaultValue: 'box'
}, '1fr');
});
dimensionsSection.addRow(row => {
row.addDecimal('length', {
label: () => dimensionsSection.dropdown('unitSystem')?.value() === 'metric' ? 'Length (cm)' : 'Length (inches)',
min: 0.1,
max: 300,
defaultValue: 12,
step: 0.1,
isRequired: true
}, '1fr');
row.addDecimal('width', {
label: () => dimensionsSection.dropdown('unitSystem')?.value() === 'metric' ? 'Width (cm)' : 'Width (inches)',
min: 0.1,
max: 300,
defaultValue: 10,
step: 0.1,
isRequired: true
}, '1fr');
row.addDecimal('height', {
label: () => dimensionsSection.dropdown('unitSystem')?.value() === 'metric' ? 'Height (cm)' : 'Height (inches)',
min: 0.1,
max: 300,
defaultValue: 8,
step: 0.1,
isRequired: true
}, '1fr');
});
dimensionsSection.addRow(row => {
row.addDecimal('actualWeight', {
label: () => dimensionsSection.dropdown('unitSystem')?.value() === 'metric' ? 'Actual Weight (kg)' : 'Actual Weight (lbs)',
min: 0.01,
max: 150,
defaultValue: 2,
step: 0.01,
isRequired: true
}, '1fr');
row.addInteger('quantity', {
label: 'Number of Packages',
min: 1,
max: 1000,
defaultValue: 1
}, '1fr');
});
// Carrier Settings Section
const carrierSection = form.addSubform('carrier', { title: '🚚 Carrier Settings' });
carrierSection.addRow(row => {
row.addRadioButton('carrier', {
label: 'Carrier/Divisor Standard',
options: [
{ id: 'ups-fedex', name: 'UPS/FedEx (139 divisor)' },
{ id: 'usps', name: 'USPS (166 divisor)' },
{ id: 'dhl', name: 'DHL International (5000 metric)' },
{ id: 'freight', name: 'Freight/LTL (194 divisor)' },
{ id: 'custom', name: 'Custom Divisor' }
],
defaultValue: 'ups-fedex',
orientation: 'vertical'
});
});
carrierSection.addRow(row => {
row.addDecimal('customDivisor', {
label: 'Custom DIM Divisor',
min: 1,
max: 10000,
defaultValue: 139,
step: 1,
isVisible: () => carrierSection.radioButton('carrier')?.value() === 'custom',
tooltip: 'Enter your carrier\'s dimensional weight divisor'
});
});
// Size Limits Check Section
const limitsSection = form.addSubform('limits', { title: '⚠️ Size Limit Checks' });
limitsSection.addRow(row => {
row.addCheckbox('checkUPS', {
label: 'Check UPS Limits',
defaultValue: true,
tooltip: 'Max: 165" length+girth, 150 lbs'
}, '1fr');
row.addCheckbox('checkFedEx', {
label: 'Check FedEx Limits',
defaultValue: true,
tooltip: 'Max: 165" length+girth, 150 lbs'
}, '1fr');
});
limitsSection.addRow(row => {
row.addCheckbox('checkUSPS', {
label: 'Check USPS Limits',
defaultValue: false,
tooltip: 'Max: 130" length+girth, 70 lbs'
}, '1fr');
row.addCheckbox('checkFreight', {
label: 'Check for Freight Required',
defaultValue: false,
tooltip: 'Over 150 lbs or oversized'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Calculations Section
const resultsSection = form.addSubform('results', { title: '📊 Calculated Dimensions', isCollapsible: false });
const getConvertedDimensions = () => {
const unitSystem = dimensionsSection.dropdown('unitSystem')?.value() || 'imperial';
let length = dimensionsSection.decimal('length')?.value() ?? 12;
let width = dimensionsSection.decimal('width')?.value() ?? 10;
let height = dimensionsSection.decimal('height')?.value() ?? 8;
let weight = dimensionsSection.decimal('actualWeight')?.value() ?? 2;
// Convert to imperial if metric
if (unitSystem === 'metric') {
length = length / 2.54;
width = width / 2.54;
height = height / 2.54;
weight = weight * 2.20462;
}
// Sort dimensions (longest = length)
const sorted = [length, width, height].sort((a, b) => b - a);
return {
length: sorted[0] ?? 12,
width: sorted[1] ?? 10,
height: sorted[2] ?? 8,
weight,
isMetric: unitSystem === 'metric'
};
};
const getDivisor = () => {
const carrier = carrierSection.radioButton('carrier')?.value() || 'ups-fedex';
const unitSystem = dimensionsSection.dropdown('unitSystem')?.value() || 'imperial';
const divisors = {
'ups-fedex': 139,
'usps': 166,
'dhl': unitSystem === 'metric' ? 5000 : 139,
'freight': 194,
'custom': carrierSection.decimal('customDivisor')?.value() || 139
};
return divisors[carrier];
};
const calculateAll = () => {
const dims = getConvertedDimensions();
const divisor = getDivisor();
const quantity = dimensionsSection.integer('quantity')?.value() || 1;
const unitSystem = dimensionsSection.dropdown('unitSystem')?.value() || 'imperial';
// Calculate cubic inches/cm
const cubicInches = dims.length * dims.width * dims.height;
const cubicCm = cubicInches * 16.387;
const cubicFeet = cubicInches / 1728;
// Dimensional weight
let dimWeight = cubicInches / divisor;
if (unitSystem === 'metric' && carrierSection.radioButton('carrier')?.value() === 'dhl') {
dimWeight = (dims.length * 2.54 * dims.width * 2.54 * dims.height * 2.54) / 5000;
dimWeight = dimWeight * 2.20462; // Convert to lbs for comparison
}
// Billable weight
const billableWeight = Math.max(dims.weight, dimWeight);
// Girth calculation (2 * width + 2 * height)
const girth = 2 * (dims.width + dims.height);
const lengthPlusGirth = dims.length + girth;
// Package density (lbs per cubic foot)
const density = dims.weight / cubicFeet;
// Freight class estimation based on density
let freightClass = '500';
if (density >= 50) freightClass = '50';
else if (density >= 35) freightClass = '55';
else if (density >= 30) freightClass = '60';
else if (density >= 22.5) freightClass = '65';
else if (density >= 15) freightClass = '70';
else if (density >= 13.5) freightClass = '77.5';
else if (density >= 12) freightClass = '85';
else if (density >= 10.5) freightClass = '92.5';
else if (density >= 9) freightClass = '100';
else if (density >= 8) freightClass = '110';
else if (density >= 7) freightClass = '125';
else if (density >= 6) freightClass = '150';
else if (density >= 5) freightClass = '175';
else if (density >= 4) freightClass = '200';
else if (density >= 3) freightClass = '250';
else if (density >= 2) freightClass = '300';
else if (density >= 1) freightClass = '400';
// Size limit checks
const warnings: string[] = [];
if (limitsSection.checkbox('checkUPS')?.value()) {
if (lengthPlusGirth > 165) warnings.push('Exceeds UPS max length+girth (165")');
if (dims.weight > 150) warnings.push('Exceeds UPS max weight (150 lbs)');
if (dims.length > 108) warnings.push('Exceeds UPS max length (108")');
}
if (limitsSection.checkbox('checkFedEx')?.value()) {
if (lengthPlusGirth > 165) warnings.push('Exceeds FedEx max length+girth (165")');
if (dims.weight > 150) warnings.push('Exceeds FedEx max weight (150 lbs)');
}
if (limitsSection.checkbox('checkUSPS')?.value()) {
if (lengthPlusGirth > 130) warnings.push('Exceeds USPS max length+girth (130")');
if (dims.weight > 70) warnings.push('Exceeds USPS max weight (70 lbs)');
}
if (limitsSection.checkbox('checkFreight')?.value()) {
if (dims.weight > 150 || lengthPlusGirth > 165) {
warnings.push('May require freight shipping');
}
}
return {
cubicInches: Math.round(cubicInches * 100) / 100,
cubicCm: Math.round(cubicCm * 100) / 100,
cubicFeet: Math.round(cubicFeet * 1000) / 1000,
dimWeight: Math.round(dimWeight * 100) / 100,
actualWeight: Math.round(dims.weight * 100) / 100,
billableWeight: Math.round(billableWeight * 100) / 100,
girth: Math.round(girth * 100) / 100,
lengthPlusGirth: Math.round(lengthPlusGirth * 100) / 100,
density: Math.round(density * 100) / 100,
freightClass,
totalBillableWeight: Math.round(billableWeight * quantity * 100) / 100,
warnings,
quantity
};
};
resultsSection.addRow(row => {
row.addPriceDisplay('cubicInches', {
label: 'Volume (cubic inches)',
computedValue: () => calculateAll().cubicInches,
prefix: '',
suffix: ' in³',
variant: 'default'
}, '1fr');
row.addPriceDisplay('cubicFeet', {
label: 'Volume (cubic feet)',
computedValue: () => calculateAll().cubicFeet,
prefix: '',
suffix: ' ft³',
variant: 'default'
}, '1fr');
});
resultsSection.addRow(row => {
row.addPriceDisplay('girth', {
label: 'Girth',
computedValue: () => calculateAll().girth,
prefix: '',
suffix: '"',
variant: 'default'
}, '1fr');
row.addPriceDisplay('lengthGirth', {
label: 'Length + Girth',
computedValue: () => calculateAll().lengthPlusGirth,
prefix: '',
suffix: '"',
variant: 'default'
}, '1fr');
});
resultsSection.addRow(row => {
row.addPriceDisplay('density', {
label: 'Package Density',
computedValue: () => calculateAll().density,
prefix: '',
suffix: ' lbs/ft³',
variant: 'default'
}, '1fr');
row.addTextPanel('freightClass', {
label: 'Estimated Freight Class',
computedValue: () => `Class ${calculateAll().freightClass}`,
customStyles: { 'font-weight': '600', 'color': '#3b82f6' }
}, '1fr');
});
// Weight Comparison Section
const weightSection = form.addSubform('weight', { title: '⚖️ Weight Comparison', isCollapsible: false });
weightSection.addRow(row => {
row.addPriceDisplay('actualWeight', {
label: 'Actual Weight',
computedValue: () => calculateAll().actualWeight,
prefix: '',
suffix: ' lbs',
variant: 'default'
}, '1fr');
row.addPriceDisplay('dimWeight', {
label: 'Dimensional Weight',
computedValue: () => calculateAll().dimWeight,
prefix: '',
suffix: ' lbs',
variant: 'default'
}, '1fr');
});
weightSection.addRow(row => {
row.addTextPanel('weightNote', {
computedValue: () => {
const calc = calculateAll();
if (calc.dimWeight > calc.actualWeight) {
return `⚠️ DIM weight is ${Math.round((calc.dimWeight - calc.actualWeight) * 10) / 10} lbs higher - you'll be charged for DIM weight`;
}
return '✅ Actual weight is higher - standard weight pricing applies';
},
customStyles: { 'font-size': '0.9rem', 'text-align': 'center' }
});
});
// Warnings Section
resultsSection.addRow(row => {
row.addTextPanel('warnings', {
computedValue: () => {
const warnings = calculateAll().warnings;
if (warnings.length === 0) return '';
return '⚠️ ' + warnings.join('\n⚠️ ');
},
customStyles: { 'font-size': '0.9rem', 'color': '#dc2626', 'white-space': 'pre-line' },
isVisible: () => calculateAll().warnings.length > 0
});
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '📋 Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addPriceDisplay('billableWeight', {
label: 'Billable Weight (per package)',
computedValue: () => calculateAll().billableWeight,
prefix: '',
suffix: ' lbs',
variant: 'large'
}, '1fr');
row.addPriceDisplay('totalWeight', {
label: () => `Total Billable (${calculateAll().quantity} packages)`,
computedValue: () => calculateAll().totalBillableWeight,
prefix: '',
suffix: ' lbs',
variant: 'success',
isVisible: () => calculateAll().quantity > 1
}, '1fr');
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Dimensional weight may vary by carrier. Always verify with your shipping provider.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Get Shipping Quote'
});
}