International Shipping Rate Estimator

International Shipping Rate Estimator

Compare international shipping rates and estimate duties.

Est. ${r.deliveryTime}

Shipping: ${formatCurrency(r.shippingCost)} + Duties: ${formatCurrency(r.estimatedDuties)}

${formatCurrency(r.totalCost)}

${tags}
`; }).join(''); resultsContainer.innerHTML = `

Available Estimates

${resultsHtml}

Duty & tax estimates are for informational purposes only and may vary.

`; lucide.createIcons(); document.getElementById('download-pdf-btn').addEventListener('click', generatePdf); }; const renderConfiguration = () => { const configContent = document.getElementById('content-config'); if (!configContent) return; const dutyRatesHtml = Object.entries(appData.countries).map(([code, data]) => `
`).join(''); configContent.innerHTML = `

Duty & Tax Rates (%)

${dutyRatesHtml}

Carrier Rate Configuration

`; renderCarrierConfig(); document.getElementById('save-config-btn').addEventListener('click', handleConfigSave); }; const renderCarrierConfig = () => { const container = document.getElementById('carrier-config-form'); if (!container) return; container.innerHTML = appData.carriers.map((carrier, cIndex) => `

${carrier.name}

${carrier.services.map((service, sIndex) => `
${service.name}
$
$/lb
`).join('')}
`).join(''); }; const handleConfigSave = (e) => { e.preventDefault(); document.querySelectorAll('#duty-config-form input').forEach(input => { appData.countries[input.dataset.country].dutyRate = parseFloat(input.value); }); document.querySelectorAll('#carrier-config-form input').forEach(input => { const { carrier, service, field } = input.dataset; appData.carriers[carrier].services[service][field] = parseFloat(input.value); }); alert('Configuration saved!'); }; const generatePdf = () => { if (!calculationResult) return; loadingOverlay.style.display = 'flex'; const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); let y = 40; pdf.setFontSize(18).setFont('helvetica', 'bold').text('International Shipping Report', pdf.internal.pageSize.getWidth() / 2, y, { align: 'center' }); y += 30; pdf.setFontSize(12).setFont('helvetica', 'bold').text('Shipment Details', 40, y); y += 15; pdf.autoTable({ startY: y, theme: 'plain', body: [ ['Origin:', appData.countries[calculationInputs.origin].name, 'Weight:', `${calculationInputs.weight} lbs`], ['Destination:', appData.countries[calculationInputs.dest].name, 'Declared Value:', formatCurrency(calculationInputs.value)], ] }); y = pdf.autoTable.previous.finalY + 30; pdf.autoTable({ startY: y, head: [['Carrier', 'Service', 'Shipping', 'Duties', 'Total']], body: calculationResult.results.map(r => [r.carrier, r.service, formatCurrency(r.shippingCost), formatCurrency(r.estimatedDuties), formatCurrency(r.totalCost)]), theme: 'grid', headStyles: { fillColor: [59, 130, 246] } // Blue header }); pdf.save(`International-Shipping-Report.pdf`); loadingOverlay.style.display = 'none'; }; const switchTab = (tabIndex) => { activeTabIndex = tabIndex; document.querySelectorAll('.tab-btn').forEach((btn, i) => btn.classList.toggle('active', i === tabIndex)); document.querySelectorAll('.tab-content').forEach((content, i) => content.classList.toggle('hidden', i !== tabIndex)); updateNavButtons(); }; const updateNavButtons = () => { prevTabBtn.disabled = activeTabIndex === 0; nextTabBtn.disabled = activeTabIndex === tabIdentifiers.length - 1; }; const initializeUI = () => { const tabs = [ { name: 'Rate Estimator', id: 'calculator' }, { name: 'Rate & Duty Configuration', id: 'config' } ]; tabIdentifiers = tabs.map(t => t.id); tabsContainer.innerHTML = tabs.map(tab => ``).join(''); mainContent.innerHTML = tabs.map(tab => `
`).join(''); tabs.forEach((tab, index) => { document.getElementById(`tab-${tab.id}`).addEventListener('click', () => switchTab(index)); }); renderCalculator(); renderConfiguration(); switchTab(0); lucide.createIcons(); }; initializeUI(); prevTabBtn.addEventListener('click', () => { if (activeTabIndex > 0) switchTab(activeTabIndex - 1); }); nextTabBtn.addEventListener('click', () => { if (activeTabIndex < tabIdentifiers.length - 1) switchTab(activeTabIndex + 1); }); });
Scroll to Top