export function deliveryTimeCalculator(form: FormTs) {
form.addRow(row => {
row.addTextPanel('header', {
computedValue: () => 'Delivery Time Estimator',
customStyles: { 'font-size': '1.5rem', 'font-weight': '600', 'color': '#1e293b' }
});
});
form.addSpacer({ height: 20 });
// Ship Date Section
const dateSection = form.addSubform('date', { title: '📅 Ship Date' });
dateSection.addRow(row => {
row.addDropdown('shipDay', {
label: 'Ship Day',
options: [
{ id: 'monday', name: 'Monday' },
{ id: 'tuesday', name: 'Tuesday' },
{ id: 'wednesday', name: 'Wednesday' },
{ id: 'thursday', name: 'Thursday' },
{ id: 'friday', name: 'Friday' },
{ id: 'saturday', name: 'Saturday' },
{ id: 'sunday', name: 'Sunday' }
],
defaultValue: 'monday',
isRequired: true
}, '1fr');
row.addDropdown('cutoffTime', {
label: 'Carrier Pickup Cutoff',
options: [
{ id: 'before-noon', name: 'Before 12:00 PM' },
{ id: 'before-3pm', name: 'Before 3:00 PM' },
{ id: 'before-5pm', name: 'Before 5:00 PM' },
{ id: 'after-cutoff', name: 'After Daily Cutoff' }
],
defaultValue: 'before-3pm',
tooltip: 'When package reaches carrier'
}, '1fr');
});
dateSection.addRow(row => {
row.addInteger('processingDays', {
label: 'Processing Time (business days)',
min: 0,
max: 10,
defaultValue: 1,
tooltip: 'Time to prepare and ship order'
});
});
// Route Section
const routeSection = form.addSubform('route', { title: '📍 Origin & Destination' });
routeSection.addRow(row => {
row.addAddress('originAddress', {
label: 'Ship From',
placeholder: 'Enter origin address...',
restrictToCountries: ['US'],
distanceUnit: 'miles',
isRequired: true
});
});
routeSection.addRow(row => {
row.addAddress('destAddress', {
label: 'Ship To',
placeholder: 'Enter destination address...',
showMap: true,
showDistance: true,
referenceAddress: () => routeSection.address('originAddress')?.value() ?? null,
restrictToCountries: ['US'],
distanceUnit: 'miles',
isRequired: true
});
});
// Helper to get zone from distance
const getZoneFromDistance = () => {
const destField = routeSection.address('destAddress');
const miles = destField?.distance();
if (miles == null) return 'zone4'; // default
if (miles < 50) return 'zone1';
if (miles < 150) return 'zone2';
if (miles < 300) return 'zone3';
if (miles < 600) return 'zone4';
if (miles < 1000) return 'zone5';
if (miles < 1400) return 'zone6';
if (miles < 1800) return 'zone7';
return 'zone8';
};
routeSection.addRow(row => {
row.addTextPanel('zoneInfo', {
computedValue: () => {
const destField = routeSection.address('destAddress');
const miles = destField?.distance();
if (miles == null) return 'Enter both addresses to see shipping zone';
const zone = getZoneFromDistance();
const zoneLabels: Record<string, string> = {
'zone1': 'Zone 1 - Local',
'zone2': 'Zone 2 - Regional',
'zone3': 'Zone 3 - Short distance',
'zone4': 'Zone 4 - Medium distance',
'zone5': 'Zone 5 - Long distance',
'zone6': 'Zone 6 - Very long distance',
'zone7': 'Zone 7 - Extended distance',
'zone8': 'Zone 8 - Cross-country'
};
return `📍 ${zoneLabels[zone]} (${Math.round(miles)} miles)`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#0369a1', 'background': '#e0f2fe', 'padding': '10px', 'border-radius': '6px' }
});
});
routeSection.addRow(row => {
row.addDropdown('destType', {
label: 'Destination Type',
options: [
{ id: 'commercial', name: 'Commercial Address' },
{ id: 'residential', name: 'Residential Address' },
{ id: 'pobox', name: 'PO Box' },
{ id: 'rural', name: 'Rural / Remote' }
],
defaultValue: 'residential'
}, '1fr');
});
// Shipping Method Section
const methodSection = form.addSubform('method', { title: '🚚 Shipping Method' });
methodSection.addRow(row => {
row.addDropdown('carrier', {
label: 'Carrier',
options: [
{ id: 'usps', name: 'USPS' },
{ id: 'ups', name: 'UPS' },
{ id: 'fedex', name: 'FedEx' },
{ id: 'dhl', name: 'DHL' },
{ id: 'regional', name: 'Regional Carrier' }
],
defaultValue: 'ups',
isRequired: true
}, '1fr');
row.addDropdown('service', {
label: 'Service Level',
options: [
{ id: 'ground', name: 'Ground / Standard' },
{ id: 'express', name: '3-Day / Express' },
{ id: 'priority', name: '2-Day / Priority' },
{ id: 'overnight', name: 'Overnight / Next Day' },
{ id: 'sameday', name: 'Same Day' }
],
defaultValue: 'ground',
isRequired: true
}, '1fr');
});
methodSection.addRow(row => {
row.addCheckbox('saturdayDelivery', {
label: 'Saturday Delivery',
defaultValue: false,
tooltip: 'Additional fee applies'
}, '1fr');
row.addCheckbox('signatureRequired', {
label: 'Signature Required',
defaultValue: false,
tooltip: 'May affect delivery timing'
}, '1fr');
});
// Factors Section
const factorsSection = form.addSubform('factors', { title: '⚠️ Potential Delay Factors' });
factorsSection.addRow(row => {
row.addCheckbox('peakSeason', {
label: 'Peak Season (Nov-Dec)',
defaultValue: false,
tooltip: 'Holiday shipping delays'
}, '1fr');
row.addCheckbox('weather', {
label: 'Weather Advisory',
defaultValue: false,
tooltip: 'Severe weather in route'
}, '1fr');
});
factorsSection.addRow(row => {
row.addCheckbox('oversized', {
label: 'Oversized Package',
defaultValue: false,
tooltip: 'May require special handling'
}, '1fr');
row.addCheckbox('international', {
label: 'International Destination',
defaultValue: false,
tooltip: 'Customs clearance required'
}, '1fr');
});
form.addSpacer({ height: 20, showLine: true, lineStyle: 'dashed' });
// Delivery Estimate Section
const estimateSection = form.addSubform('estimate', { title: '📦 Delivery Estimate', isCollapsible: false });
estimateSection.addRow(row => {
row.addTextPanel('transitDays', {
computedValue: () => {
const zone = getZoneFromDistance();
const service = methodSection.dropdown('service')?.value() || 'ground';
const destType = routeSection.dropdown('destType')?.value() || 'residential';
const peakSeason = factorsSection.checkbox('peakSeason')?.value();
const weather = factorsSection.checkbox('weather')?.value();
const oversized = factorsSection.checkbox('oversized')?.value();
const international = factorsSection.checkbox('international')?.value();
// Base transit days by service
const baseTransit: Record<string, Record<string, number>> = {
'sameday': { 'zone1': 0, 'zone2': 0, 'zone3': 0, 'zone4': 0, 'zone5': 0, 'zone6': 0, 'zone7': 0, 'zone8': 0 },
'overnight': { 'zone1': 1, 'zone2': 1, 'zone3': 1, 'zone4': 1, 'zone5': 1, 'zone6': 1, 'zone7': 1, 'zone8': 1 },
'priority': { 'zone1': 2, 'zone2': 2, 'zone3': 2, 'zone4': 2, 'zone5': 2, 'zone6': 2, 'zone7': 2, 'zone8': 2 },
'express': { 'zone1': 2, 'zone2': 2, 'zone3': 3, 'zone4': 3, 'zone5': 3, 'zone6': 3, 'zone7': 3, 'zone8': 3 },
'ground': { 'zone1': 1, 'zone2': 2, 'zone3': 3, 'zone4': 4, 'zone5': 5, 'zone6': 5, 'zone7': 6, 'zone8': 7 }
};
let days = baseTransit[service]?.[zone] || 5;
// Adjustments
if (destType === 'rural') days += 1;
if (destType === 'pobox' && service !== 'ground') days += 1;
if (peakSeason) days += 2;
if (weather) days += 1;
if (oversized) days += 1;
if (international) days += 5;
return `Transit Time: ${days} business day${days !== 1 ? 's' : ''}`;
},
customStyles: { 'font-size': '1.2rem', 'font-weight': '600', 'color': '#0284c7', 'text-align': 'center' }
});
});
estimateSection.addRow(row => {
row.addTextPanel('deliveryWindow', {
computedValue: () => {
const zone = getZoneFromDistance();
const service = methodSection.dropdown('service')?.value() || 'ground';
const destType = routeSection.dropdown('destType')?.value() || 'residential';
const peakSeason = factorsSection.checkbox('peakSeason')?.value();
const weather = factorsSection.checkbox('weather')?.value();
const oversized = factorsSection.checkbox('oversized')?.value();
const international = factorsSection.checkbox('international')?.value();
const processingDays = dateSection.integer('processingDays')?.value() || 1;
const cutoff = dateSection.dropdown('cutoffTime')?.value() || 'before-3pm';
const baseTransit: Record<string, Record<string, number>> = {
'sameday': { 'zone1': 0, 'zone2': 0, 'zone3': 0, 'zone4': 0, 'zone5': 0, 'zone6': 0, 'zone7': 0, 'zone8': 0 },
'overnight': { 'zone1': 1, 'zone2': 1, 'zone3': 1, 'zone4': 1, 'zone5': 1, 'zone6': 1, 'zone7': 1, 'zone8': 1 },
'priority': { 'zone1': 2, 'zone2': 2, 'zone3': 2, 'zone4': 2, 'zone5': 2, 'zone6': 2, 'zone7': 2, 'zone8': 2 },
'express': { 'zone1': 2, 'zone2': 2, 'zone3': 3, 'zone4': 3, 'zone5': 3, 'zone6': 3, 'zone7': 3, 'zone8': 3 },
'ground': { 'zone1': 1, 'zone2': 2, 'zone3': 3, 'zone4': 4, 'zone5': 5, 'zone6': 5, 'zone7': 6, 'zone8': 7 }
};
let days = baseTransit[service]?.[zone] || 5;
if (destType === 'rural') days += 1;
if (destType === 'pobox' && service !== 'ground') days += 1;
if (peakSeason) days += 2;
if (weather) days += 1;
if (oversized) days += 1;
if (international) days += 5;
// Add processing days and cutoff adjustment
let totalDays = processingDays + days;
if (cutoff === 'after-cutoff') totalDays += 1;
const minDays = totalDays;
const maxDays = totalDays + (peakSeason || weather ? 2 : 1);
return `Estimated Delivery: ${minDays}-${maxDays} business days from order`;
},
customStyles: { 'font-size': '1rem', 'font-weight': '500', 'color': '#059669', 'text-align': 'center' }
});
});
estimateSection.addRow(row => {
row.addTextPanel('deliveryTime', {
computedValue: () => {
const service = methodSection.dropdown('service')?.value() || 'ground';
const destType = routeSection.dropdown('destType')?.value() || 'residential';
if (service === 'sameday') return 'Delivery by end of day';
if (service === 'overnight') return 'Delivery by 10:30 AM (commercial) or 3:00 PM (residential)';
if (service === 'priority') return 'Delivery by end of day (typically by 5:00 PM)';
if (destType === 'commercial') {
return 'Delivery typically by 5:00 PM';
} else {
return 'Delivery typically between 9:00 AM - 7:00 PM';
}
},
customStyles: { 'font-size': '0.9rem', 'color': '#64748b', 'text-align': 'center' }
});
});
// Timeline Section
const timelineSection = form.addSubform('timeline', { title: '📋 Shipment Timeline', isCollapsible: true });
timelineSection.addRow(row => {
row.addTextPanel('step1', {
computedValue: () => {
const processingDays = dateSection.integer('processingDays')?.value() || 1;
return `1. Order Processing: ${processingDays} business day${processingDays !== 1 ? 's' : ''}`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#1e293b' }
});
});
timelineSection.addRow(row => {
row.addTextPanel('step2', {
computedValue: () => {
const cutoff = dateSection.dropdown('cutoffTime')?.value() || 'before-3pm';
const cutoffLabels: Record<string, string> = {
'before-noon': '12:00 PM', 'before-3pm': '3:00 PM',
'before-5pm': '5:00 PM', 'after-cutoff': 'next business day'
};
return `2. Carrier Pickup: By ${cutoffLabels[cutoff]}`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#1e293b' }
});
});
timelineSection.addRow(row => {
row.addTextPanel('step3', {
computedValue: () => {
const zone = getZoneFromDistance();
const service = methodSection.dropdown('service')?.value() || 'ground';
const baseTransit: Record<string, Record<string, number>> = {
'sameday': { 'zone1': 0, 'zone2': 0, 'zone3': 0, 'zone4': 0, 'zone5': 0, 'zone6': 0, 'zone7': 0, 'zone8': 0 },
'overnight': { 'zone1': 1, 'zone2': 1, 'zone3': 1, 'zone4': 1, 'zone5': 1, 'zone6': 1, 'zone7': 1, 'zone8': 1 },
'priority': { 'zone1': 2, 'zone2': 2, 'zone3': 2, 'zone4': 2, 'zone5': 2, 'zone6': 2, 'zone7': 2, 'zone8': 2 },
'express': { 'zone1': 2, 'zone2': 2, 'zone3': 3, 'zone4': 3, 'zone5': 3, 'zone6': 3, 'zone7': 3, 'zone8': 3 },
'ground': { 'zone1': 1, 'zone2': 2, 'zone3': 3, 'zone4': 4, 'zone5': 5, 'zone6': 5, 'zone7': 6, 'zone8': 7 }
};
const days = baseTransit[service]?.[zone] || 5;
return `3. In Transit: ${days} business day${days !== 1 ? 's' : ''}`;
},
customStyles: { 'font-size': '0.9rem', 'color': '#1e293b' }
});
});
timelineSection.addRow(row => {
row.addTextPanel('step4', {
computedValue: () => '4. Out for Delivery: Day of delivery',
customStyles: { 'font-size': '0.9rem', 'color': '#1e293b' }
});
});
// Summary Section
const summarySection = form.addSubform('summary', {
title: '📋 Summary',
isCollapsible: false,
sticky: 'bottom'
});
summarySection.addRow(row => {
row.addTextPanel('summaryText', {
computedValue: () => {
const carrier = methodSection.dropdown('carrier')?.value() || 'ups';
const service = methodSection.dropdown('service')?.value() || 'ground';
const destField = routeSection.address('destAddress');
const miles = destField?.distance();
const originAddr = routeSection.address('originAddress')?.value();
const destAddr = routeSection.address('destAddress')?.value();
const originCity = originAddr?.formattedAddress?.split(',')[0] || 'Origin';
const destCity = destAddr?.formattedAddress?.split(',')[0] || 'Destination';
const carrierLabels: Record<string, string> = {
'usps': 'USPS', 'ups': 'UPS', 'fedex': 'FedEx', 'dhl': 'DHL', 'regional': 'Regional'
};
const serviceLabels: Record<string, string> = {
'ground': 'Ground', 'express': '3-Day', 'priority': '2-Day', 'overnight': 'Overnight', 'sameday': 'Same Day'
};
const distanceText = miles != null ? ` (${Math.round(miles)} mi)` : '';
return `${carrierLabels[carrier]} ${serviceLabels[service]} | ${originCity} → ${destCity}${distanceText}`;
},
customStyles: { 'font-size': '0.95rem', 'font-weight': '500', 'text-align': 'center', 'color': '#1e293b' }
});
});
summarySection.addRow(row => {
row.addTextPanel('disclaimer', {
computedValue: () => 'Estimates based on standard carrier service. Actual delivery may vary due to carrier delays, weather, or customs.',
customStyles: { 'font-size': '0.8rem', 'color': '#64748b', 'text-align': 'center' }
});
});
form.configureSubmitButton({
label: 'Track Shipment'
});
}