https://t.me/RX1948
Server : Apache/2.4.18 (Ubuntu)
System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64
User : oppastar ( 1041)
PHP Version : 7.0.33-0ubuntu0.16.04.15
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
Directory :  /var/www/laciasmara.com/public_html/shop/application/views/admin_new/orders/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /var/www/laciasmara.com/public_html/shop/application/views/admin_new/orders/print_label.php
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shipping Label Printer</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            background-color: #f5f5f5;
        }

        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }

        .controls {
            margin-bottom: 20px;
            padding: 20px;
            background: #f8f9fa;
            border-radius: 6px;
        }

        .form-group {
            margin-bottom: 15px;
        }

        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #333;
        }

        input[type="text"] {
            width: 200px;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }

        button {
            background: #7A4397;
            color: white;
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            margin-right: 10px;
        }

        button:hover {
            background: #66357a;
        }

        button:disabled {
            background: #6c757d;
            cursor: not-allowed;
        }

        .preview {
            margin-top: 20px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: white;
        }

        .preview-header {
            background: #e9ecef;
            padding: 10px;
            border-bottom: 1px solid #ddd;
            font-weight: bold;
        }

        .labels-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            padding: 10px;
        }

        .label {
            border: 1px dashed #7A4397;
            padding: 8px;
            font-size: 10px;
            height: 350px;
            position: relative;
            background: #fafafa;
        }

        .label-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            padding: 5px;
            border-bottom: 1px solid #ddd;
            background-color: #7A4397;
        }

        .logo {
            display: flex;
            align-items: center;
            height: 30px;
        }

        .logo img {
            max-height: 30px;
            max-width: 120px;
            object-fit: contain;
        }

        .logo span {
            font-weight: bold;
            font-size: 12px;
            color: #007bff;
        }

        .order-info {
            font-size: 9px;
            color: white;
        }

        .address-section {
            margin-bottom: 8px;
        }

        .shipping-info {
            display: flex;
            justify-content: space-between;
            flex-wrap: wrap;
            margin-bottom: 10px;
            padding-bottom: 8px;
            border-bottom: 1px solid #ddd;
        }

        .shipping-pair {
            display: flex;
            flex-direction: column;
            min-width: 80px;
            text-align: left;
        }

        .shipping-pair .shipping-label {
            font-weight: bold;
            color: #333;
            font-size: 9px;
            margin-bottom: 2px;
        }

        .shipping-pair .shipping-value {
            color: #444;
            font-size: 8px;
        }


        .address-title {
            font-weight: bold;
            font-size: 9px;
            color: #333;
            margin-bottom: 2px;
        }

        .address-content {
            font-size: 8px;
            line-height: 1.2;
            color: #555;
        }

        .cut-line {
            border-top: 1px dashed #999;
            margin: 8px 0;
            position: relative;
        }

        .cut-line::before {
            content: "✂ Cut here";
            position: absolute;
            right: 0;
            top: -8px;
            font-size: 7px;
            color: #666;
            background: #fafafa;
            padding: 0 5px;
        }

        .items-list {
            font-size: 7px;
            line-height: 1.2;
        }

        .item {
            margin-bottom: 2px;
            display: flex;
            justify-content: space-between;
        }

        .loading {
            text-align: center;
            padding: 20px;
            color: #666;
        }

        .error {
            color: #dc3545;
            background: #f8d7da;
            padding: 10px;
            border-radius: 4px;
            margin-bottom: 15px;
        }

        .success {
            color: #155724;
            background: #d4edda;
            padding: 10px;
            border-radius: 4px;
            margin-bottom: 15px;
        }

        .remove-label-btn {
            background: #ff4444;
            color: white;
            border: none;
            border-radius: 50%;
            width: 24px;
            height: 24px;
            font-size: 12px;
            font-weight: bold;
            cursor: pointer;
            position: absolute;
            top: 5px;
            right: 5px;
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
            transition: all 0.2s ease;
            z-index: 10;
            padding: 0;
            line-height: 1;
            min-width: 20px;
        }


        .remove-label-btn:hover {
            background: #cc0000;
            transform: scale(1.1);
            box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
        }

        .remove-label-btn:active {
            transform: scale(0.95);
        }

        /* Print styles */
        @media print {
            body * {
                visibility: hidden;
            }

            .print-area,
            .print-area * {
                visibility: visible;
            }

            .print-area {
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <h1>Shipping Label</h1>

        <div class="controls">
            <div class="form-group">
                <label for="orderId">Order ID:</label>
                <input type="text" id="orderId" placeholder="Enter order ID" value="12345">
                <span>Total Pesanan: <span id="orderCount">0</span></span>
            </div>

            <div class="form-group" style="display: none;">
                <label for="apiEndpoint">API Endpoint:</label>
                <input type="text" id="apiEndpoint" placeholder="/api/orders/" value="<?= base_url('admin/orders/get_print_label_data/') ?>" disabled>
            </div>

            <button id="loadOrder">Load Order</button>
            <button id="printLabel" disabled>Print Labels (4 per page)</button>
            <!-- <button id="generatePDF" disabled>Generate PDF</button> -->
            <button id="clearAll">Clear All Orders</button>
        </div>

        <div id="message"></div>

        <div class="preview">
            <div class="preview-header">Label Preview (4 labels per A4 page)</div>
            <div id="previewContent">
                <div class="loading">Load an order to see preview</div>
            </div>
        </div>
    </div>

    <script>
        class ShippingLabelPrinter {
            constructor() {
                this.ordersData = []; // Array to store multiple orders
                this.initializeElements();
                this.attachEventListeners();
            }

            initializeElements() {
                this.orderIdInput = document.getElementById('orderId');
                this.apiEndpointInput = document.getElementById('apiEndpoint');
                this.loadOrderBtn = document.getElementById('loadOrder');
                this.printLabelBtn = document.getElementById('printLabel');
                // this.generatePDFBtn = document.getElementById('generatePDF');
                this.clearAllBtn = document.getElementById('clearAll'); // Add clear all button
                this.messageDiv = document.getElementById('message');
                this.previewContent = document.getElementById('previewContent');
                this.orderCountSpan = document.getElementById('orderCount'); // Add order count display
            }

            attachEventListeners() {
                this.loadOrderBtn.addEventListener('click', () => this.loadOrder());
                this.printLabelBtn.addEventListener('click', () => this.printLabels());
                // this.generatePDFBtn.addEventListener('click', () => this.generatePDF());
                if (this.clearAllBtn) {
                    this.clearAllBtn.addEventListener('click', () => this.clearAllOrders());
                }
            }

            showMessage(message, type = 'info') {
                this.messageDiv.innerHTML = `<div class="${type}">${message}</div>`;
                setTimeout(() => {
                    this.messageDiv.innerHTML = '';
                }, 5000);
            }

            updateOrderCount() {
                if (this.orderCountSpan) {
                    this.orderCountSpan.textContent = this.ordersData.length;
                }
            }

            async loadOrder() {
                const orderId = this.orderIdInput.value.trim();
                const apiEndpoint = this.apiEndpointInput.value.trim();

                if (!orderId) {
                    this.showMessage('Please enter an order ID', 'error');
                    return;
                }

                // Check if order already exists
                const existingOrder = this.ordersData.find(order => order.order.id_orders === orderId);
                if (existingOrder) {
                    this.showMessage(`Order ${orderId} already loaded`, 'warning');
                    return;
                }

                this.loadOrderBtn.disabled = true;
                this.showMessage('Loading order data...', 'info');

                try {
                    // For demo purposes, we'll simulate the API response
                    const response = await fetch(`${apiEndpoint}${orderId}`, {
                        method: 'GET',
                        headers: {
                            'Content-Type': 'application/json',
                        }
                    });

                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }

                    const result = await response.json();

                    let orderData;
                    if (result.success && result.data) {
                        orderData = result.data;
                    } else if (result.website_data) {
                        orderData = result;
                    } else {
                        throw new Error('Invalid response format');
                    }

                    // Add the new order to the array
                    this.ordersData.push(orderData);
                    this.renderPreview();
                    this.enablePrintButtons();
                    this.updateOrderCount();
                    this.showMessage(`Pesanan ${orderId} berhasil ditambahin! Total pesanan: ${this.ordersData.length}`, 'success');

                    // Clear the input field for next order
                    this.orderIdInput.value = '';

                } catch (error) {
                    // If API fails, use mock data for demo
                    this.showMessage(`API failed, using mock data for order ${orderId}`, 'warning');
                    const mockData = this.getMockOrderData(orderId);
                    this.ordersData.push(mockData);
                    this.renderPreview();
                    this.enablePrintButtons();
                    this.updateOrderCount();
                    this.orderIdInput.value = '';
                } finally {
                    this.loadOrderBtn.disabled = false;
                }
            }

            maskName(name) {
                if (!name || name.length < 2) return name;
                return name[0] + '*'.repeat(name.length - 1);
            }

            maskPhone(phone) {
                if (!phone || phone.length < 4) return phone;
                return phone.slice(0, 2) + '*'.repeat(phone.length - 4) + phone.slice(-2);
            }

            getMockOrderData(orderId) {
                // Mock data with different customer info for each order
                const mockCustomers = [{
                        name: 'John Doe',
                        email: 'john.doe@example.com',
                        phone: '(555) 987-6543',
                        address: '456 Customer Ave',
                        city: 'Customer City',
                        state: 'CS',
                        zip: '54321'
                    },
                    {
                        name: 'Jane Smith',
                        email: 'jane.smith@example.com',
                        phone: '(555) 123-7890',
                        address: '789 Buyer Street',
                        city: 'Shopping Town',
                        state: 'ST',
                        zip: '67890'
                    },
                    {
                        name: 'Bob Johnson',
                        email: 'bob.johnson@example.com',
                        phone: '(555) 456-1234',
                        address: '321 Purchase Blvd',
                        city: 'Order City',
                        state: 'OC',
                        zip: '13579'
                    }
                ];

                const mockProducts = [
                    [{
                            product_name: 'Wireless Headphones',
                            quantity: 1,
                            price: 199.99,
                            sku: 'WH-001'
                        },
                        {
                            product_name: 'Phone Case',
                            quantity: 2,
                            price: 49.99,
                            sku: 'PC-002'
                        }
                    ],
                    [{
                            product_name: 'Bluetooth Speaker',
                            quantity: 1,
                            price: 89.99,
                            sku: 'BS-003'
                        },
                        {
                            product_name: 'USB Cable',
                            quantity: 3,
                            price: 15.99,
                            sku: 'UC-004'
                        }
                    ],
                    [{
                            product_name: 'Laptop Stand',
                            quantity: 1,
                            price: 59.99,
                            sku: 'LS-005'
                        },
                        {
                            product_name: 'Wireless Mouse',
                            quantity: 1,
                            price: 29.99,
                            sku: 'WM-006'
                        }
                    ]
                ];

                const customerIndex = (parseInt(orderId) % mockCustomers.length);
                const productIndex = (parseInt(orderId) % mockProducts.length);

                return {
                    website_data: {
                        logo: 'Your Store Logo',
                        website_name: 'Your eCommerce Store',
                        address: '123 Business St, City, State 12345',
                        phone: '(555) 123-4567'
                    },
                    order: {
                        id_orders: orderId,
                        order_date: '2024-07-14',
                        total_amount: mockProducts[productIndex].reduce((sum, item) => sum + (item.price * item.quantity), 0),
                        shipping_method: 'Standard Shipping'
                    },
                    customer: mockCustomers[customerIndex],
                    orders_detail: mockProducts[productIndex]
                };
            }

            renderPreview() {
                const labelsHtml = this.ordersData.map(orderData => this.generateLabelHtml(orderData)).join('');
                this.previewContent.innerHTML = `
                    <div class="labels-grid">
                        ${labelsHtml}
                    </div>
                `;
            }

            generateLabelHtml(data) {
                const baseUrl = "<?= base_url() ?>";
                const itemsHtml = data.orders_detail.map(item => `
                    <div class="item">
                        <span>${item.product_name} (${item.sku})</span>
                        <span>x ${item.quantity}</span>
                    </div>
                `).join('');

                return `
                    <div class="label" data-order-id="${data.order.id_orders}">
                        <div class="label-header">
                            <div class="logo">
                                <img src="${baseUrl}uploads/${data.website_data.logo}" alt="Logo" onerror="this.style.display='none'; this.nextElementSibling.style.display='block';">
                                <span style="display: none;">${data.website_data.logo}</span>
                            </div>
                            <div class="order-info">Order: ${data.order.id_orders}</div>
                            <button class="remove-label-btn" onclick="shippingPrinter.removeOrder('${data.order.id_orders}')" title="Remove this order">✕</button>
                        </div>
                        <div class="shipping-info">
                            <div class="shipping-pair">
                                <span class="shipping-label">Layanan:</span>
                                <span class="shipping-value">${data.order.shipment_type}</span>
                            </div>
                            <div class="shipping-pair">
                                <span class="shipping-label">Kurir:</span>
                                <span class="shipping-value">${data.order.shipment_name}</span>
                            </div>
                            <div class="shipping-pair">
                                <span class="shipping-label">Ongkir:</span>
                                <span class="shipping-value">IDR ${data.order.shipping_fee}</span>
                            </div>
                        </div>
                    
                        <div class="address-section">
                            <div class="address-title">Pengirim:</div>
                            <div class="address-content">
                                ${this.maskName(data.website_data.website_name)}<br>
                                Tebet, Jakarta Selatan, Indonesia<br>
                            </div>
                        </div>
                        
                        <div class="address-section">
                            <div class="address-title">Penerima:</div>
                            <div class="address-content">
                                ${data.customer.name} (${this.maskPhone(data.customer.phone)})<br>
                                ${data.customer.address}<br>
                                ${data.customer.subdistrict}, ${data.customer.district}, ${data.customer.province}<br>
                            </div>
                        </div>
                        
                        <div class="cut-line"></div>
                        
                        <div class="items-list">
                            <div style="font-weight: bold; margin-bottom: 3px;">Items:</div>
                            ${itemsHtml}
                        </div>
                    </div>
                `;
            }

            removeOrder(orderId) {
                this.ordersData = this.ordersData.filter(order => order.order.id_orders !== orderId);
                this.renderPreview();
                this.updateOrderCount();
                this.showMessage(`Order ${orderId} removed`, 'info');

                if (this.ordersData.length === 0) {
                    this.printLabelBtn.disabled = true;
                    // this.generatePDFBtn.disabled = true;
                }
            }

            clearAllOrders() {
                this.ordersData = [];
                this.renderPreview();
                this.updateOrderCount();
                this.printLabelBtn.disabled = true;
                // this.generatePDFBtn.disabled = true;
                this.showMessage('All orders cleared', 'info');
            }

            enablePrintButtons() {
                this.printLabelBtn.disabled = false;
                // this.generatePDFBtn.disabled = false;
            }

            printLabels() {
                if (this.ordersData.length === 0) {
                    this.showMessage('Please load at least one order first', 'error');
                    return;
                }

                const baseUrl = "<?= base_url() ?>";
                // Create a new window for printing
                const printWindow = window.open('', '_blank');
                const labelsHtml = this.ordersData.map(orderData => {
                    const itemsHtml = orderData.orders_detail.map(item => `
                        <div class="item">
                            <span>${item.product_name} (${item.sku})</span>
                            <span>x ${item.quantity}</span>
                        </div>
                    `).join('');

                    return `
                        <div class="label" data-order-id="${orderData.order.id_orders}">
                            <div class="label-header">
                                <div class="logo">
                                    <img src="${baseUrl}uploads/${orderData.website_data.logo}" alt="Logo" onerror="this.style.display='none'; this.nextElementSibling.style.display='block';">
                                    <span style="display: none;">${orderData.website_data.logo}</span>
                                </div>
                                <div class="order-info">Order: ${orderData.order.id_orders}</div>
                            </div>
                            
                            <div class="shipping-info">
                                <div class="shipping-pair">
                                    <span class="shipping-label">Layanan:</span>
                                    <span class="shipping-value">${orderData.order.shipment_type}</span>
                                </div>
                                <div class="shipping-pair">
                                    <span class="shipping-label">Kurir:</span>
                                    <span class="shipping-value">${orderData.order.shipment_name}</span>
                                </div>
                                <div class="shipping-pair">
                                    <span class="shipping-label">Ongkir:</span>
                                    <span class="shipping-value">IDR ${orderData.order.shipping_fee}</span>
                                </div>
                            </div>
                    
                            <div class="address-section">
                                <div class="address-title">Pengirim:</div>
                                <div class="address-content">
                                    ${this.maskName(orderData.website_data.website_name)}<br>
                                    Tebet, Jakarta Selatan, Indonesia<br>
                                </div>
                            </div>
                            
                            <div class="address-section">
                                <div class="address-title">Penerima:</div>
                                <div class="address-content">
                                    ${orderData.customer.name} (${this.maskPhone(orderData.customer.phone)})<br>
                                    ${orderData.customer.address}<br>
                                    ${orderData.customer.subdistrict}, ${orderData.customer.district}, ${orderData.customer.province}<br>
                                </div>
                            </div>
                            
                            <div class="cut-line"></div>
                            
                            <div class="items-list">
                                <div style="font-weight: bold; margin-bottom: 3px;">Items:</div>
                                ${itemsHtml}
                            </div>
                        </div>
                    `;
                }).join('');

                printWindow.document.write(`
                    <!DOCTYPE html>
                    <html>
                    <head>
                        <title>Shipping Labels - ${this.ordersData.length} Orders</title>
                        <style>
                            @page {
                                size: A4;
                                margin: 0.5in;
                            }
                            
                            body {
                                font-family: Arial, sans-serif;
                                margin: 0;
                                padding: 0;
                            }
                            
                            .labels-grid {
                                display: grid;
                                grid-template-columns: 1fr 1fr;
                                gap: 10px;
                                margin: 10px;
                            }
                            
                            .label {
                                border: 2px solid #000;
                                padding: 8px;
                                font-size: 12px;
                                position: relative;
                                background: white;
                                break-inside: avoid;
                                page-break-inside: avoid;
                                height: 350px;

                            }
                            
                            .label-header {
                                display: flex;
                                justify-content: space-between;
                                align-items: center;
                                margin-bottom: 15px;
                                padding-bottom: 10px;
                                border-bottom: 1px solid #333;
                            }
                            
                            .logo {
                                display: flex;
                                align-items: center;
                                height: 30px;
                            }
                            
                            .logo img {
                                max-height: 30px;
                                max-width: 120px;
                                object-fit: contain;
                            }
                            
                            .logo span {
                                font-weight: bold;
                                font-size: 12px;
                                color: #007bff;
                            }
                            
                            .order-info {
                                font-size: 9px;
                                color: white;
                            }

                            .address-section {
                                margin-bottom: 8px;
                            }

                            .shipping-info {
                                display: flex;
                                justify-content: space-between;
                                flex-wrap: wrap;
                                margin-bottom: 10px;
                                padding-bottom: 8px;
                                border-bottom: 1px solid #ddd;
                            }

                            .shipping-pair {
                                display: flex;
                                flex-direction: column;
                                min-width: 80px;
                                text-align: left;
                            }

                            .shipping-pair .shipping-label {
                                font-weight: bold;
                                color: #333;
                                font-size: 9px;
                                margin-bottom: 2px;
                            }

                            .shipping-pair .shipping-value {
                                color: #444;
                                font-size: 8px;
                            }


                            .address-title {
                                font-weight: bold;
                                font-size: 9px;
                                color: #333;
                                margin-bottom: 2px;
                            }

                            .address-content {
                                font-size: 8px;
                                line-height: 1.2;
                                color: #555;
                            }
                            .remove-label-btn {
                                display: none; /* Hide remove button in print */
                            }
                            
                            .cut-line {
                                border-top: 2px dashed #333;
                                margin: 15px 0;
                                position: relative;
                            }
                            
                            .cut-line::before {
                                content: "✂ Cut here";
                                position: absolute;
                                right: 0;
                                top: -10px;
                                font-size: 10px;
                                background: white;
                                padding: 0 5px;
                            }
                            
                            .items-list {
                                font-size: 7px;
                                line-height: 1.2;
                            }
                            
                            .item {
                                margin-bottom: 3px;
                                display: flex;
                                justify-content: space-between;
                            }
                        </style>
                    </head>
                    <body>
                        <div class="labels-grid">
                            ${labelsHtml}
                        </div>
                    </body>
                    </html>
                `);

                printWindow.document.close();
                printWindow.focus();

                // Print after a short delay to ensure content is loaded
                setTimeout(() => {
                    printWindow.print();
                    printWindow.close();
                }, 500);
            }

            generatePDF() {
                if (this.ordersData.length === 0) {
                    this.showMessage('Please load at least one order first', 'error');
                    return;
                }

                const {
                    jsPDF
                } = window.jspdf;
                const doc = new jsPDF();

                const pageWidth = doc.internal.pageSize.width;
                const pageHeight = doc.internal.pageSize.height;

                // Calculate label dimensions (1/4 of A4)
                const labelWidth = (pageWidth - 30) / 2; // 2 columns with margins
                const labelHeight = (pageHeight - 30) / 2; // 2 rows with margins

                const positions = [{
                        x: 15,
                        y: 15
                    }, // Top-left
                    {
                        x: 15 + labelWidth + 10,
                        y: 15
                    }, // Top-right
                    {
                        x: 15,
                        y: 15 + labelHeight + 10
                    }, // Bottom-left
                    {
                        x: 15 + labelWidth + 10,
                        y: 15 + labelHeight + 10
                    } // Bottom-right
                ];

                // Generate labels for each order
                this.ordersData.forEach((orderData, orderIndex) => {
                    const pageNumber = Math.floor(orderIndex / 4);
                    const positionIndex = orderIndex % 4;

                    // Add new page if needed
                    if (pageNumber > 0 && positionIndex === 0) {
                        doc.addPage();
                    }

                    const pos = positions[positionIndex];
                    this.drawLabel(doc, pos.x, pos.y, labelWidth, labelHeight, orderData);
                });

                // Save the PDF
                const orderIds = this.ordersData.map(order => order.order.id_orders).join('-');
                doc.save(`shipping-labels-orders-${orderIds}.pdf`);
                this.showMessage('PDF generated successfully!', 'success');
            }

            drawLabel(doc, x, y, width, height, data) {
                // Draw border
                doc.rect(x, y, width, height);

                let currentY = y + 10;

                // Header
                doc.setFontSize(12);
                doc.setFont(undefined, 'bold');

                // Try to add logo image, fallback to text if fails
                try {
                    const baseUrl = "<?= base_url() ?>";
                    const logoUrl = `${baseUrl}uploads/${data.website_data.logo}`;
                    // For PDF, we'll just use text for now since adding images requires more complex handling
                    doc.text(data.website_data.website_name, x + 5, currentY);
                } catch (error) {
                    doc.text(data.website_data.website_name, x + 5, currentY);
                }

                doc.text(`Order: ${data.order.id_orders}`, x + width - 40, currentY);

                currentY += 15;

                // FROM section
                doc.setFontSize(10);
                doc.setFont(undefined, 'bold');
                doc.text('FROM:', x + 5, currentY);

                currentY += 5;
                doc.setFont(undefined, 'normal');
                doc.setFontSize(9);
                doc.text(data.website_data.website_name, x + 5, currentY);
                currentY += 4;
                doc.text(data.website_data.address, x + 5, currentY);
                currentY += 4;
                doc.text(data.website_data.phone, x + 5, currentY);

                currentY += 10;

                // TO section
                doc.setFontSize(10);
                doc.setFont(undefined, 'bold');
                doc.text('TO:', x + 5, currentY);

                currentY += 5;
                doc.setFont(undefined, 'normal');
                doc.setFontSize(9);
                doc.text(data.customer.name, x + 5, currentY);
                currentY += 4;
                doc.text(data.customer.address, x + 5, currentY);
                currentY += 4;
                doc.text(`${data.customer.city}, ${data.customer.state} ${data.customer.zip}`, x + 5, currentY);
                currentY += 4;
                doc.text(data.customer.phone, x + 5, currentY);

                currentY += 10;

                // Dashed line
                doc.setLineDashPattern([2, 2], 0);
                doc.line(x + 5, currentY, x + width - 5, currentY);
                doc.setLineDashPattern([], 0);

                // Cut here text
                doc.setFontSize(8);
                doc.text('✂ Cut here', x + width - 25, currentY - 2);

                currentY += 8;

                // Items section
                doc.setFontSize(9);
                doc.setFont(undefined, 'bold');
                doc.text('Items:', x + 5, currentY);

                currentY += 5;
                doc.setFont(undefined, 'normal');
                doc.setFontSize(8);

                data.orders_detail.forEach(item => {
                    const itemText = `${item.product_name} (${item.sku})`;
                    const qtyText = `Qty: ${item.quantity}`;

                    doc.text(itemText, x + 5, currentY);
                    doc.text(qtyText, x + width - 25, currentY);
                    currentY += 4;
                });
            }
        }

        // Initialize the application
        let shippingPrinter;
        document.addEventListener('DOMContentLoaded', () => {
            shippingPrinter = new ShippingLabelPrinter();
        });
    </script>
</body>

</html>

https://t.me/RX1948 - 2025