`;
serviceList.insertAdjacentHTML('beforeend', item);
});
}
// --- FORMS & EVENT HANDLERS ---
calculateBtn.addEventListener('click', calculateRates);
carrierForm.addEventListener('submit', (e) => {
e.preventDefault();
const data = {
carrierName: document.getElementById('carrier-name').value,
serviceName: document.getElementById('service-name').value,
baseCost: parseFloat(document.getElementById('base-cost').value),
costPerLb: parseFloat(document.getElementById('cost-per-lb').value),
deliveryTime: document.getElementById('delivery-time').value,
minDays: parseInt(document.getElementById('min-days').value),
};
if (editingServiceId) {
const service = services.find(s => s.id === editingServiceId);
Object.assign(service, data);
} else {
data.id = Date.now();
services.push(data);
}
resetCarrierForm();
renderAll();
});
document.getElementById('cancel-edit-btn').addEventListener('click', resetCarrierForm);
document.getElementById('service-list').addEventListener('click', (e) => {
const button = e.target;
const action = button.dataset.action;
const id = parseInt(button.dataset.id);
if (action === 'edit') setupEditForm(id);
if (action === 'delete') deleteService(id);
});
function resetCarrierForm() {
carrierForm.reset();
editingServiceId = null;
document.getElementById('form-title').textContent = 'Add New Carrier Service';
document.getElementById('cancel-edit-btn').style.display = 'none';
}
function setupEditForm(id) {
const service = services.find(s => s.id === id);
if (!service) return;
document.getElementById('service-id').value = service.id;
document.getElementById('carrier-name').value = service.carrierName;
document.getElementById('service-name').value = service.serviceName;
document.getElementById('base-cost').value = service.baseCost;
document.getElementById('cost-per-lb').value = service.costPerLb;
document.getElementById('delivery-time').value = service.deliveryTime;
document.getElementById('min-days').value = service.minDays;
editingServiceId = id;
document.getElementById('form-title').textContent = 'Edit Carrier Service';
document.getElementById('cancel-edit-btn').style.display = 'inline-block';
}
function deleteService(id) {
if (confirm('Are you sure you want to delete this service?')) {
services = services.filter(s => s.id !== id);
renderAll();
}
}
downloadPdfBtn.addEventListener('click', generatePdf);
// --- TABS & NAVIGATION ---
window.switchTab = (tabName) => {
currentTab = tabName;
Object.values(tabBtns).forEach(btn => btn.classList.replace('tab-active', 'tab-inactive'));
Object.values(tabContents).forEach(content => content.style.display = 'none');
tabBtns[tabName].classList.replace('tab-inactive', 'tab-active');
tabContents[tabName].style.display = 'block';
};
window.navigateTabs = (direction) => {
if (direction === 'next' && currentTab === 'comparator') switchTab('config');
else if (direction === 'prev' && currentTab === 'config') switchTab('comparator');
};
// --- PDF GENERATION ---
async function generatePdf() {
const { jsPDF } = window.jspdf;
const pdfReportElement = document.getElementById('pdf-report');
const weight = parseFloat(document.getElementById('weight').value) || 0;
const results = services.map(service => ({...service, cost: service.baseCost + (weight * service.costPerLb)}));
document.getElementById('pdf-date').textContent = new Date().toLocaleDateString('en-US');
document.getElementById('pdf-origin').textContent = document.getElementById('origin').value;
document.getElementById('pdf-destination').textContent = document.getElementById('destination').value;
document.getElementById('pdf-weight').textContent = `${weight} lbs`;
const pdfTableBody = document.getElementById('pdf-table-body');
pdfTableBody.innerHTML = '';
const cheapest = results.reduce((prev, curr) => (prev.cost < curr.cost) ? prev : curr);
const fastest = results.reduce((prev, curr) => (prev.minDays < curr.minDays) ? prev : curr);
results.forEach(res => {
let rowClass = '';
if (res.id === cheapest.id || res.id === fastest.id) rowClass = 'pdf-best-row';
const row = `
| ${res.carrierName} | ${res.serviceName} | ${formatUSD(res.cost)} | ${res.deliveryTime} |
`;
pdfTableBody.insertAdjacentHTML('beforeend', row);
});
const canvas = await html2canvas(pdfReportElement, { scale: 2 });
const imgData = canvas.toDataURL('image/jpeg', 0.9);
const pdf = new jsPDF('p', 'mm', 'a4');
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (canvas.height * pdfWidth) / canvas.width;
pdf.addImage(imgData, 'JPEG', 0, 0, pdfWidth, pdfHeight);
pdf.save('Shipping-Comparison.pdf');
}
// --- INITIALIZATION ---
function init() {
services = [
{ id: 1, carrierName: 'UPS', serviceName: 'Ground', baseCost: 9.50, costPerLb: 0.50, deliveryTime: '3-5 business days', minDays: 3 },
{ id: 2, carrierName: 'FedEx', serviceName: 'Express Saver', baseCost: 15.00, costPerLb: 0.75, deliveryTime: '3 business days', minDays: 3 },
{ id: 3, carrierName: 'USPS', serviceName: 'Priority Mail', baseCost: 8.00, costPerLb: 0.60, deliveryTime: '2-3 business days', minDays: 2 },
{ id: 4, carrierName: 'UPS', serviceName: '2nd Day Air', baseCost: 25.00, costPerLb: 1.20, deliveryTime: '2 business days', minDays: 2 }
];
renderAll();
}
init();
});