`;
elements.shippingConfigContainer.appendChild(shipmentEl);
});
}
// --- EVENT HANDLERS --- //
function handleConfigChange(e) {
if (!e.target.classList.contains('shipment-input')) return;
const target = e.target;
const id = parseInt(target.dataset.id);
const field = target.dataset.field;
const value = target.type === 'number' ? parseFloat(target.value) || 0 : target.value;
const shipment = shippingData.shipments.find(s => s.id === id);
if (shipment) {
shipment[field] = value;
updateDashboardUI();
}
}
function handleAddShipment() {
const newId = shippingData.shipments.length > 0 ? Math.max(...shippingData.shipments.map(s => s.id)) + 1 : 1;
const today = new Date().toISOString().slice(0,10);
shippingData.shipments.unshift({
id: newId, destination: 'New Destination', carrier: 'UPS', cost: 0, shipDate: today, deliveryDate: '', customsStatus: 'In Progress'
});
populateConfigForm();
updateDashboardUI();
}
function handleRemoveShipment(e) {
if (!e.target.classList.contains('remove-shipment-btn')) return;
const id = parseInt(e.target.dataset.id);
shippingData.shipments = shippingData.shipments.filter(s => s.id !== id);
populateConfigForm();
updateDashboardUI();
}
async function handlePdfDownload() {
if (typeof html2canvas === 'undefined' || typeof window.jspdf === 'undefined') return;
const { jsPDF } = window.jspdf;
const pdfExportElement = elements.pdfExportArea;
if (!pdfExportElement) return;
const originalBg = pdfExportElement.style.backgroundColor;
pdfExportElement.style.backgroundColor = 'white';
try {
const canvas = await html2canvas(pdfExportElement, { scale: 2, useCORS: true, logging: false });
pdfExportElement.style.backgroundColor = originalBg;
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({
orientation: 'landscape',
unit: 'px',
format: [canvas.width, canvas.height]
});
pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
pdf.save('Cross-Border-Shipping-Dashboard.pdf');
} catch (error) {
console.error("Error generating PDF:", error);
pdfExportElement.style.backgroundColor = originalBg;
}
}
// --- INITIALIZATION --- //
if (elements.shippingConfigContainer) {
elements.shippingConfigContainer.addEventListener('input', handleConfigChange);
elements.shippingConfigContainer.addEventListener('click', handleRemoveShipment);
}
if (elements.addShipmentBtn) {
elements.addShipmentBtn.addEventListener('click', handleAddShipment);
}
if (elements.downloadPdfBtn) {
elements.downloadPdfBtn.addEventListener('click', handlePdfDownload);
}
updateDashboardUI();
populateConfigForm();
window.updateNavButtons();
});
// --- GLOBAL FUNCTIONS FOR TAB NAVIGATION --- //
function switchTab(tabName) {
const tabDashboard = document.getElementById('tab-panel-dashboard');
const tabConfig = document.getElementById('tab-panel-config');
const btnDashboard = document.getElementById('tab-btn-dashboard');
const btnConfig = document.getElementById('tab-btn-config');
if (!tabDashboard || !tabConfig || !btnDashboard || !btnConfig) return;
const isDashboard = tabName === 'dashboard';
tabDashboard.classList.toggle('hidden', !isDashboard);
tabConfig.classList.toggle('hidden', isDashboard);
btnDashboard.classList.toggle('active', isDashboard);
btnConfig.classList.toggle('active', !isDashboard);
updateNavButtons();
}
function updateNavButtons() {
const btnDashboard = document.getElementById('tab-btn-dashboard');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
if (!btnDashboard || !prevBtn || !nextBtn) return;
const isDashboardActive = btnDashboard.classList.contains('active');
prevBtn.disabled = isDashboardActive;
nextBtn.disabled = !isDashboardActive;
prevBtn.classList.toggle('opacity-50', isDashboardActive);
prevBtn.classList.toggle('cursor-not-allowed', isDashboardActive);
nextBtn.classList.toggle('opacity-50', !isDashboardActive);
nextBtn.classList.toggle('cursor-not-allowed', !isDashboardActive);
}
function navigateTabs(direction) {
const isDashboardActive = document.getElementById('tab-btn-dashboard').classList.contains('active');
if (direction === 'next' && isDashboardActive) {
switchTab('config');
} else if (direction === 'prev' && !isDashboardActive) {
switchTab('dashboard');
}
}