{'role': 'assistant', 'content': '<function_calls>\n<create-file file_path="nexusship/static/js/main.js">\n// NexusShip Main JavaScript\n\ndocument.addEventListener(\'DOMContentLoaded\', function() {\n    // Initialize tracking functionality\n    initTracking();\n    \n    // Initialize admin panel functionality\n    initAdminPanel();\n    \n    // Initialize modals\n    initModals();\n});\n\n// Tracking Functionality\nfunction initTracking() {\n    const trackingForm = document.getElementById(\'trackingForm\');\n    const trackingInput = document.getElementById(\'trackingNumber\');\n    const trackingButton = document.getElementById(\'trackButton\');\n    const trackingResults = document.getElementById(\'trackingResults\');\n    \n    if (trackingForm) {\n        trackingForm.addEventListener(\'submit\', async function(e) {\n            e.preventDefault();\n            \n            const trackingNumber = trackingInput.value.trim();\n            \n            if (!trackingNumber) {\n                showError(\'Please enter a tracking number\');\n                return;\n            }\n            \n            // Show loading state\n            trackingButton.innerHTML = \'<span class="loading"></span> Tracking...\';\n            trackingButton.disabled = true;\n            \n            try {\n                const response = await fetch(\'/api/track\', {\n                    method: \'POST\',\n                    headers: {\n                        \'Content-Type\': \'application/json\'\n                    },\n                    body: JSON.stringify({\n                        tracking_number: trackingNumber\n                    })\n                });\n                \n                if (response.ok) {\n                    const data = await response.json();\n                    displayTrackingResults(data);\n                } else {\n                    const error = await response.json();\n                    showError(error.error || \'Tracking number not found\');\n                }\n            } catch (error) {\n                showError(\'An error occurred while tracking. Please try again.\');\n            }\n            \n            // Reset button\n            trackingButton.innerHTML = \'Track Package\';\n            trackingButton.disabled = false;\n        });\n    }\n}\n\nfunction displayTrackingResults(data) {\n    const trackingResults = document.getElementById(\'trackingResults\');\n    const trackingInfo = document.querySelector(\'.tracking-info\');\n    const timeline = document.querySelector(\'.tracking-timeline\');\n    \n    // Update tracking info\n    trackingInfo.innerHTML = `\n        <div class="info-box">\n            <h4>Tracking Number</h4>\n            <p>${data.tracking_number}</p>\n        </div>\n        <div class="info-box">\n            <h4>Status</h4>\n            <p><span class="status-badge status-${data.status.replace(/\\s/g, \'\')}">${data.status}</span></p>\n        </div>\n        <div class="info-box">\n            <h4>Shipper</h4>\n            <p>${data.shipper_name}</p>\n            <p style="font-size: 14px; margin-top: 5px;">${data.shipper_address}</p>\n        </div>\n        <div class="info-box">\n            <h4>Receiver</h4>\n            <p>${data.receiver_name}</p>\n            <p style="font-size: 14px; margin-top: 5px;">${data.receiver_address}</p>\n        </div>\n        <div class="info-box">\n            <h4>Shipment Date</h4>\n            <p>${data.shipment_date}</p>\n        </div>\n        <div class="info-box">\n            <h4>Expected Delivery</h4>\n            <p>${data.delivery_date || \'Pending\'}</p>\n        </div>\n        <div class="info-box">\n            <h4>Service Type</h4>\n            <p>${data.service_type}</p>\n        </div>\n        <div class="info-box">\n            <h4>Weight</h4>\n            <p>${data.weight} kg</p>\n        </div>\n    `;\n    \n    // Update timeline\n    let timelineHTML = \'\';\n    data.history.forEach((item, index) => {\n        const icon = getTimelineIcon(item.status);\n        timelineHTML += `\n            <div class="timeline-item">\n                <div class="timeline-icon">${icon}</div>\n                <div class="timeline-content">\n                    <h4>${item.status}</h4>\n                    <p><strong>Location:</strong> ${item.location}</p>\n                    <p>${item.description}</p>\n                    <p class="timeline-date">${item.timestamp}</p>\n                    <span class="timeline-backcode">Backcode: ${item.backcode}</span>\n                </div>\n            </div>\n        `;\n    });\n    \n    timeline.innerHTML = timelineHTML;\n    \n    // Show results\n    trackingResults.classList.add(\'active\');\n    \n    // Add receipt buttons\n    addReceiptButtons(data.tracking_number);\n}\n\nfunction getTimelineIcon(status) {\n    const icons = {\n        \'Processing\': \'📦\',\n        \'In Transit\': \'🚚\',\n        \'Out for Delivery\': \'📬\',\n        \'Delivered\': \'✅\',\n        \'On Hold\': \'⏸️\',\n        \'Exception\': \'⚠️\'\n    };\n    return icons[status] || \'📋\';\n}\n\nfunction addReceiptButtons(trackingNumber) {\n    const timeline = document.querySelector(\'.tracking-timeline\');\n    \n    const buttonsHTML = `\n        <div class="receipt-actions" style="margin-top: 40px;">\n            <button class="btn-success" onclick="downloadReceiptPDF(\'${trackingNumber}\')">\n                📄 Download PDF Receipt\n            </button>\n            <button class="btn-primary" onclick="printReceipt(\'${trackingNumber}\')">\n                🖨️ Print Receipt\n            </button>\n            <button class="btn-secondary" onclick="downloadReceiptImage(\'${trackingNumber}\')">\n                📷 Download as Image\n            </button>\n        </div>\n    `;\n    \n    timeline.innerHTML += buttonsHTML;\n}\n\nasync function downloadReceiptPDF(trackingNumber) {\n    window.open(`/api/receipt/pdf/${trackingNumber}`, \'_blank\');\n}\n\nfunction printReceipt(trackingNumber) {\n    // Open print dialog\n    const url = `/api/receipt/pdf/${trackingNumber}`;\n    const printWindow = window.open(url, \'_blank\');\n    printWindow.onload = function() {\n        printWindow.print();\n    };\n}\n\nasync function downloadReceiptImage(trackingNumber) {\n    // For image download, we\'ll create a canvas from the receipt\n    alert(\'Image download feature - A screenshot of the receipt will be generated. Please use your browser\\\'s screenshot functionality for now.\');\n    \n    // Open receipt in new tab for screenshot\n    window.open(`/api/receipt/pdf/${trackingNumber}`, \'_blank\');\n}\n\nfunction showError(message) {\n    const trackingResults = document.getElementById(\'trackingResults\');\n    trackingResults.innerHTML = `\n        <div class="alert alert-error">\n            <strong>Error:</strong> ${message}\n        </div>\n    `;\n    trackingResults.classList.add(\'active\');\n}\n\n// Admin Panel Functionality\nfunction initAdminPanel() {\n    const generateButton = document.getElementById(\'generateTrackingNumbers\');\n    const shipmentsTable = document.getElementById(\'shipmentsTable\');\n    \n    if (generateButton) {\n        generateButton.addEventListener(\'click\', async function() {\n            if (confirm(\'Are you sure you want to generate 300 new tracking numbers?\')) {\n                await generateTrackingNumbers();\n            }\n        });\n    }\n    \n    if (shipmentsTable) {\n        loadShipments();\n    }\n    \n    // Initialize status update form\n    const updateStatusForm = document.getElementById(\'updateStatusForm\');\n    if (updateStatusForm) {\n        updateStatusForm.addEventListener(\'submit\', handleStatusUpdate);\n    }\n}\n\nasync function generateTrackingNumbers() {\n    const generateButton = document.getElementById(\'generateTrackingNumbers\');\n    generateButton.innerHTML = \'<span class="loading"></span> Generating...\';\n    generateButton.disabled = true;\n    \n    try {\n        const response = await fetch(\'/api/admin/generate-tracking\', {\n            method: \'POST\',\n            headers: {\n                \'Content-Type\': \'application/json\'\n            },\n            body: JSON.stringify({\n                count: 300\n            })\n        });\n        \n        const data = await response.json();\n        \n        if (data.tracking_numbers) {\n            alert(`Successfully generated ${data.tracking_numbers.length} tracking numbers!`);\n            loadShipments();\n        }\n    } catch (error) {\n        alert(\'Error generating tracking numbers: \' + error.message);\n    }\n    \n    generateButton.innerHTML = \'Generate 300 Tracking Numbers\';\n    generateButton.disabled = false;\n}\n\nasync function loadShipments() {\n    const tableBody = document.querySelector(\'#shipmentsTable tbody\');\n    \n    try {\n        const response = await fetch(\'/api/admin/shipments\');\n        const data = await response.json();\n        \n        if (data.shipments) {\n            let html = \'\';\n            data.shipments.forEach(shipment => {\n                html += `\n                    <tr>\n                        <td>${shipment.tracking_number}</td>\n                        <td>${shipment.shipper_name}</td>\n                        <td>${shipment.receiver_name}</td>\n                        <td><span class="status-badge status-${shipment.status.replace(/\\s/g, \'\')}">${shipment.status}</span></td>\n                        <td>${shipment.shipment_date}</td>\n                        <td>${shipment.delivery_date || \'Pending\'}</td>\n                        <td>\n                            <button class="btn-success" onclick="editShipment(${shipment.id})">Edit</button>\n                            <button class="btn-danger" onclick="deleteShipment(${shipment.id})">Delete</button>\n                            <button class="btn-secondary" onclick="updateStatus(${shipment.id}, \'${shipment.tracking_number}\')">Update Status</button>\n                            <button class="btn-primary" onclick="downloadReceiptPDF(\'${shipment.tracking_number}\')">Receipt</button>\n                        </td>\n                    </tr>\n                `;\n            });\n            \n            tableBody.innerHTML = html;\n        }\n    } catch (error) {\n        tableBody.innerHTML = \'<tr><td colspan="7" style="text-align: center;">Error loading shipments</td></tr>\';\n    }\n}\n\nfunction editShipment(id) {\n    // This would open an edit modal\n    alert(`Edit shipment with ID: ${id}. Full edit modal would be implemented here.`);\n}\n\nasync function deleteShipment(id) {\n    if (confirm(\'Are you sure you want to delete this shipment?\')) {\n        try {\n            const response = await fetch(`/api/admin/shipment/${id}`, {\n                method: \'DELETE\'\n            });\n            \n            if (response.ok) {\n                alert(\'Shipment deleted successfully!\');\n                loadShipments();\n            } else {\n                alert(\'Error deleting shipment\');\n            }\n        } catch (error) {\n            alert(\'Error deleting shipment: \' + error.message);\n        }\n    }\n}\n\nfunction updateStatus(id, trackingNumber) {\n    const modal = document.getElementById(\'statusModal\');\n    const trackingNumberInput = document.getElementById(\'statusTrackingNumber\');\n    const shipmentIdInput = document.getElementById(\'shipmentId\');\n    \n    if (modal && trackingNumberInput && shipmentIdInput) {\n        trackingNumberInput.value = trackingNumber;\n        shipmentIdInput.value = id;\n        modal.classList.add(\'active\');\n    }\n}\n\nasync function handleStatusUpdate(e) {\n    e.preventDefault();\n    \n    const trackingNumber = document.getElementById(\'statusTrackingNumber\').value;\n    const shipmentId = document.getElementById(\'shipmentId\').value;\n    const status = document.getElementById(\'newStatus\').value;\n    const location = document.getElementById(\'newLocation\').value;\n    const description = document.getElementById(\'newDescription\').value;\n    \n    if (!location) {\n        alert(\'Please enter a location for the status update\');\n        return;\n    }\n    \n    try {\n        const response = await fetch(`/api/admin/shipment/${shipmentId}`, {\n            method: \'PUT\',\n            headers: {\n                \'Content-Type\': \'application/json\'\n            },\n            body: JSON.stringify({\n                status: status,\n                location: location,\n                description: description\n            })\n        });\n        \n        if (response.ok) {\n            alert(\'Status updated successfully!\');\n            closeModal(\'statusModal\');\n            loadShipments();\n        } else {\n            alert(\'Error updating status\');\n        }\n    } catch (error) {\n        alert(\'Error updating status: \' + error.message);\n    }\n}\n\n// Modal Functions\nfunction initModals() {\n    // Close modal when clicking outside\n    window.addEventListener(\'click\', function(e) {\n        if (e.target.classList.contains(\'modal\')) {\n            e.target.classList.remove(\'active\');\n        }\n    });\n    \n    // Close modal buttons\n    const closeButtons = document.querySelectorAll(\'.modal-close\');\n    closeButtons.forEach(button => {\n        button.addEventListener(\'click\', function() {\n            const modal = button.closest(\'.modal\');\n            modal.classList.remove(\'active\');\n        });\n    });\n}\n\nfunction closeModal(modalId) {\n    const modal = document.getElementById(modalId);\n    if (modal) {\n        modal.classList.remove(\'active\');\n    }\n}\n\n// Bulk Status Update\nasync function bulkUpdateStatus() {\n    const selectedCheckboxes = document.querySelectorAll(\'.shipment-checkbox:checked\');\n    \n    if (selectedCheckboxes.length === 0) {\n        alert(\'Please select at least one shipment to update\');\n        return;\n    }\n    \n    const trackingNumbers = Array.from(selectedCheckboxes).map(cb => cb.dataset.tracking);\n    const status = document.getElementById(\'bulkStatus\').value;\n    const location = document.getElementById(\'bulkLocation\').value;\n    const description = document.getElementById(\'bulkDescription\').value;\n    \n    if (!location) {\n        alert(\'Please enter a location for the status update\');\n        return;\n    }\n    \n    try {\n        const response = await fetch(\'/api/admin/bulk-update-status\', {\n            method: \'POST\',\n            headers: {\n                \'Content-Type\': \'application/json\'\n            },\n            body: JSON.stringify({\n                tracking_numbers: trackingNumbers,\n                status: status,\n                location: location,\n                description: description\n            })\n        });\n        \n        const data = await response.json();\n        \n        if (data.success) {\n            alert(`Successfully updated ${data.updated} shipments!`);\n            loadShipments();\n        }\n    } catch (error) {\n        alert(\'Error updating shipments: \' + error.message);\n    }\n}\n\n// Helper Functions\nfunction formatDate(dateString) {\n    const date = new Date(dateString);\n    return date.toLocaleDateString(\'en-US\', {\n        year: \'numeric\',\n        month: \'short\',\n        day: \'numeric\'\n    });\n}\n\nfunction formatDateTime(dateString) {\n    const date = new Date(dateString);\n    return date.toLocaleString(\'en-US\', {\n        year: \'numeric\',\n        month: \'short\',\n        day: \'numeric\',\n        hour: \'2-digit\',\n        minute: \'2-digit\'\n    });\n}\n\n// Smooth scroll for navigation\ndocument.querySelectorAll(\'a[href^="#"]\').forEach(anchor => {\n    anchor.addEventListener(\'click\', function(e) {\n        e.preventDefault();\n        const target = document.querySelector(this.getAttribute(\'href\'));\n        if (target) {\n            target.scrollIntoView({\n                behavior: \'smooth\'\n            });\n        }\n    });\n});\n\n// Form validation\nfunction validateEmail(email) {\n    const re = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n    return re.test(email);\n}\n\nfunction validatePhone(phone) {\n    const re = /^[\\d\\s\\-\\+\\(\\)]+$/;\n    return re.test(phone);\n}\n</create-file>\n</function_calls>'}