<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <title>Receipt Generator Pro</title>

  <!-- Tailwind CSS -->

  <script src="https://cdn.tailwindcss.com"></script>

  <!-- html2pdf.js for Receipt-Sized PDF Output -->

  <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>

  <!-- Authentic Receipt Monospace & UI Fonts -->

  <link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />


  <style>

    body {

      font-family: 'Inter', sans-serif;

    }


    .receipt-font {

      font-family: 'Space Mono', 'Courier New', Courier, monospace;

    }


    /* 80mm standard POS paper styling */

    .receipt-container-80mm {

      width: 80mm;

      min-height: 120mm;

      padding: 6mm 5mm;

      background: #ffffff;

      color: #000000;

      box-sizing: border-box;

    }


    /* 58mm compact POS paper styling */

    .receipt-container-58mm {

      width: 58mm;

      min-height: 100mm;

      padding: 4mm 3mm;

      background: #ffffff;

      color: #000000;

      box-sizing: border-box;

      font-size: 10px !important;

    }


    .dashed-line {

      border-top: 1px dashed #000000;

      margin: 8px 0;

    }


    .double-line {

      border-top: 3px double #000000;

      margin: 8px 0;

    }


    .receipt-paper-wrapper {

      position: relative;

      box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.15), 0 8px 10px -6px rgba(0, 0, 0, 0.1);

    }


    /* Print media optimization for direct thermal printers */

    @media print {

      @page {

        size: 80mm auto;

        margin: 0mm;

      }


      body {

        background: #ffffff !important;

        margin: 0 !important;

        padding: 0 !important;

      }


      .no-print {

        display: none !important;

      }


      .print-area {

        display: block !important;

        margin: 0 !important;

        padding: 0 !important;

        box-shadow: none !important;

      }


      #receipt-element {

        box-shadow: none !important;

        margin: 0 !important;

      }

    }

  </style>

</head>

<body class="bg-slate-100 min-h-screen text-slate-800">


  <!-- Header Bar -->

  <header class="bg-slate-900 text-white py-4 px-6 shadow-md no-print">

    <div class="max-w-7xl mx-auto flex flex-col sm:flex-row items-center justify-between gap-4">

      <div class="flex items-center gap-3">

        <div class="bg-emerald-500 text-slate-900 font-bold p-2 rounded-lg">

          <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">

            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />

          </svg>

        </div>

        <div>

          <h1 class="text-xl font-bold tracking-tight">ReceiptGen Pro</h1>

          <p class="text-xs text-slate-400">Custom Thermal Receipt Builder & Receipt-Size PDF Exporter</p>

        </div>

      </div>


      <div class="flex flex-wrap items-center gap-3">

        <button onclick="resetForm()" class="px-3.5 py-2 text-xs font-medium bg-slate-800 hover:bg-slate-700 text-slate-200 rounded-lg border border-slate-700 transition">

          Reset Defaults

        </button>

        <button onclick="window.print()" class="px-4 py-2 text-sm font-medium bg-slate-700 hover:bg-slate-600 text-white rounded-lg flex items-center gap-2 transition">

          <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">

            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />

          </svg>

          Print Thermal

        </button>

        <button onclick="downloadReceiptPDF()" class="px-4 py-2 text-sm font-semibold bg-emerald-500 hover:bg-emerald-400 text-slate-950 rounded-lg flex items-center gap-2 shadow-sm transition">

          <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">

            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />

          </svg>

          Download Receipt PDF

        </button>

      </div>

    </div>

  </header>


  <!-- Main Interface -->

  <main class="max-w-7xl mx-auto p-4 sm:p-6 grid grid-cols-1 lg:grid-cols-12 gap-8">


    <!-- Form Section -->

    <section class="lg:col-span-7 space-y-6 no-print">


      <!-- Paper & Currency -->

      <div class="bg-white p-5 rounded-xl shadow-sm border border-slate-200">

        <h2 class="text-sm font-bold uppercase tracking-wider text-slate-500 mb-4">1. Format & Paper Size</h2>

        <div class="grid grid-cols-1 sm:grid-cols-3 gap-4">

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Paper Width</label>

            <select id="paperWidth" onchange="updateReceiptSize()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none">

              <option value="80">80mm (Standard POS)</option>

              <option value="58">58mm (Compact Thermal)</option>

            </select>

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Currency Symbol</label>

            <input type="text" id="currencySymbol" value="RM" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" placeholder="RM, $, €, £" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Show Barcode</label>

            <select id="showBarcode" onchange="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none">

              <option value="yes">Yes (Bottom Barcode)</option>

              <option value="no">No</option>

            </select>

          </div>

        </div>

      </div>


      <!-- Merchant Details -->

      <div class="bg-white p-5 rounded-xl shadow-sm border border-slate-200">

        <h2 class="text-sm font-bold uppercase tracking-wider text-slate-500 mb-4">2. Store / Business Information</h2>

        <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">

          <div class="sm:col-span-2">

            <label class="block text-xs font-semibold text-slate-600 mb-1">Business / Store Name</label>

            <input type="text" id="storeName" value="KOPI & CO. ROASTERS" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Registration / Tax ID</label>

            <input type="text" id="storeReg" value="SSM: 202401009876 (1456789-X)" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Phone Number</label>

            <input type="text" id="storePhone" value="+60 3-2145 8899" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div class="sm:col-span-2">

            <label class="block text-xs font-semibold text-slate-600 mb-1">Store Address</label>

            <textarea id="storeAddress" rows="2" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none">Lot G-12, Jalan Bukit Bintang,

55100 Kuala Lumpur, Malaysia</textarea>

          </div>

        </div>

      </div>


      <!-- Invoice Details -->

      <div class="bg-white p-5 rounded-xl shadow-sm border border-slate-200">

        <h2 class="text-sm font-bold uppercase tracking-wider text-slate-500 mb-4">3. Receipt & Transaction Details</h2>

        <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Receipt / Invoice No.</label>

            <input type="text" id="receiptNo" value="INV-2025-0842" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Date & Time</label>

            <input type="text" id="receiptDate" value="" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Cashier / Staff</label>

            <input type="text" id="cashierName" value="Farhan" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Customer / Table (Optional)</label>

            <input type="text" id="customerName" value="Walk-in (Table 04)" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

        </div>

      </div>


      <!-- Line Items -->

      <div class="bg-white p-5 rounded-xl shadow-sm border border-slate-200">

        <div class="flex items-center justify-between mb-4">

          <h2 class="text-sm font-bold uppercase tracking-wider text-slate-500">4. Purchased Items</h2>

          <button onclick="addItem()" class="px-3 py-1.5 bg-emerald-50 hover:bg-emerald-100 text-emerald-700 font-semibold text-xs rounded-lg border border-emerald-200 transition flex items-center gap-1">

            + Add Item

          </button>

        </div>


        <div id="itemsList" class="space-y-3"></div>

      </div>


      <!-- Taxes, Discounts, Payment -->

      <div class="bg-white p-5 rounded-xl shadow-sm border border-slate-200">

        <h2 class="text-sm font-bold uppercase tracking-wider text-slate-500 mb-4">5. Tax, Discounts & Payment</h2>

        <div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-4">

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Discount Amount</label>

            <input type="number" step="0.01" id="discountAmt" value="0.00" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Tax / SST Rate (%)</label>

            <input type="number" step="0.1" id="taxRate" value="6" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Service Charge (%)</label>

            <input type="number" step="0.1" id="serviceRate" value="0" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

        </div>


        <div class="grid grid-cols-1 sm:grid-cols-2 gap-4">

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Payment Method</label>

            <select id="paymentMethod" onchange="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none">

              <option value="CASH">CASH</option>

              <option value="DUITNOW QR">DUITNOW QR</option>

              <option value="VISA / MASTERCARD">VISA / MASTERCARD</option>

              <option value="E-WALLET">E-WALLET</option>

              <option value="ONLINE TRANSFER">ONLINE TRANSFER</option>

            </select>

          </div>

          <div>

            <label class="block text-xs font-semibold text-slate-600 mb-1">Amount Paid / Tendered</label>

            <input type="number" step="0.01" id="amountPaid" value="50.00" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none" />

          </div>

          <div class="sm:col-span-2">

            <label class="block text-xs font-semibold text-slate-600 mb-1">Footer Message</label>

            <textarea id="footerNote" rows="2" oninput="renderReceipt()" class="w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:ring-2 focus:ring-emerald-500 outline-none">Thank you for visiting!

Goods sold are not returnable or refundable.</textarea>

          </div>

        </div>

      </div>


    </section>


    <!-- Live Receipt Preview Section -->

    <section class="lg:col-span-5 flex flex-col items-center">

      <div class="sticky top-6 flex flex-col items-center w-full">

        <div class="mb-3 flex items-center justify-between w-full max-w-[80mm] no-print">

          <span class="text-xs font-semibold uppercase tracking-wider text-slate-500">Live Preview</span>

          <span id="sizeBadge" class="text-xs bg-slate-200 text-slate-700 font-medium px-2 py-0.5 rounded">80mm Thermal</span>

        </div>


        <div class="print-area receipt-paper-wrapper bg-white">

          <div id="receipt-element" class="receipt-container-80mm receipt-font text-xs leading-relaxed">


            <!-- Store Header -->

            <div class="text-center">

              <div id="r-storeName" class="font-bold text-base tracking-tight uppercase"></div>

              <div id="r-storeReg" class="text-[10px] mt-0.5"></div>

              <div id="r-storeAddress" class="text-[11px] whitespace-pre-line mt-1"></div>

              <div id="r-storePhone" class="text-[11px] mt-0.5"></div>

            </div>


            <div class="dashed-line"></div>


            <!-- Transaction Info -->

            <div class="text-[11px] space-y-0.5">

              <div class="flex justify-between">

                <span>Receipt #:</span>

                <span id="r-receiptNo" class="font-bold"></span>

              </div>

              <div class="flex justify-between">

                <span>Date:</span>

                <span id="r-receiptDate"></span>

              </div>

              <div class="flex justify-between">

                <span>Cashier:</span>

                <span id="r-cashierName"></span>

              </div>

              <div id="r-customerRow" class="flex justify-between">

                <span>Customer:</span>

                <span id="r-customerName"></span>

              </div>

            </div>


            <div class="dashed-line"></div>


            <!-- Items Table Header -->

            <div class="flex justify-between font-bold text-[11px]">

              <span>ITEM</span>

              <span>AMT (<span class="r-curr"></span>)</span>

            </div>


            <div class="dashed-line"></div>


            <!-- Items Output -->

            <div id="r-itemsList" class="space-y-1.5 text-[11px]"></div>


            <div class="dashed-line"></div>


            <!-- Totals Breakdown -->

            <div class="space-y-1 text-[11px]">

              <div class="flex justify-between">

                <span>Subtotal</span>

                <span id="r-subtotal">0.00</span>

              </div>

              <div id="r-discountRow" class="flex justify-between">

                <span>Discount</span>

                <span id="r-discount">-0.00</span>

              </div>

              <div id="r-serviceRow" class="flex justify-between">

                <span>Service Charge (<span id="r-serviceRate">0</span>%)</span>

                <span id="r-serviceAmt">0.00</span>

              </div>

              <div id="r-taxRow" class="flex justify-between">

                <span>Tax / SST (<span id="r-taxRate">6</span>%)</span>

                <span id="r-taxAmt">0.00</span>

              </div>

            </div>


            <div class="double-line"></div>


            <div class="flex justify-between font-bold text-sm my-1">

              <span>TOTAL</span>

              <span><span class="r-curr"></span> <span id="r-total">0.00</span></span>

            </div>


            <div class="dashed-line"></div>


            <!-- Payment & Change -->

            <div class="space-y-0.5 text-[11px]">

              <div class="flex justify-between">

                <span id="r-paymentMethod">CASH</span>

                <span id="r-amountPaid">0.00</span>

              </div>

              <div class="flex justify-between font-bold">

                <span>CHANGE</span>

                <span id="r-change">0.00</span>

              </div>

            </div>


            <div class="dashed-line"></div>


            <!-- Footer Message -->

            <div id="r-footerNote" class="text-center text-[10px] whitespace-pre-line mt-3"></div>


            <!-- Barcode -->

            <div id="r-barcodeContainer" class="mt-4 flex flex-col items-center">

              <div class="h-9 w-44 bg-[repeating-linear-gradient(90deg,#000,#000_2px,#fff_2px,#fff_4px,#000_4px,#000_5px,#fff_5px,#fff_8px,#000_8px,#000_11px,#fff_11px,#fff_13px)]"></div>

              <span id="r-barcodeText" class="text-[9px] tracking-widest mt-1"></span>

            </div>


          </div>

        </div>

      </div>

    </section>


  </main>


  <script>

    let items = [

      { name: "Iced Spanish Latte", qty: 2, price: 13.50 },

      { name: "Butter Croissant", qty: 1, price: 9.00 },

      { name: "Espresso Macchiato", qty: 1, price: 10.00 }

    ];


    function setInitialDateTime() {

      const now = new Date();

      const formatted = now.getFullYear() + "-" +

        String(now.getMonth() + 1).padStart(2, '0') + "-" +

        String(now.getDate()).padStart(2, '0') + " " +

        String(now.getHours()).padStart(2, '0') + ":" +

        String(now.getMinutes()).padStart(2, '0');

      document.getElementById('receiptDate').value = formatted;

    }


    function renderItemInputs() {

      const container = document.getElementById('itemsList');

      container.innerHTML = '';


      items.forEach((item, index) => {

        const row = document.createElement('div');

        row.className = 'grid grid-cols-12 gap-2 items-center bg-slate-50 p-2 rounded-lg border border-slate-200';

        row.innerHTML = `

          <div class="col-span-6">

            <label class="block text-[10px] text-slate-400 uppercase">Item Description</label>

            <input type="text" value="${item.name}" oninput="updateItem(${index}, 'name', this.value)"

              class="w-full bg-white rounded border border-slate-300 px-2 py-1 text-xs focus:ring-1 focus:ring-emerald-500 outline-none" />

          </div>

          <div class="col-span-2">

            <label class="block text-[10px] text-slate-400 uppercase">Qty</label>

            <input type="number" min="1" step="1" value="${item.qty}" oninput="updateItem(${index}, 'qty', this.value)"

              class="w-full bg-white rounded border border-slate-300 px-2 py-1 text-xs focus:ring-1 focus:ring-emerald-500 outline-none" />

          </div>

          <div class="col-span-3">

            <label class="block text-[10px] text-slate-400 uppercase">Unit Price</label>

            <input type="number" step="0.01" value="${item.price}" oninput="updateItem(${index}, 'price', this.value)"

              class="w-full bg-white rounded border border-slate-300 px-2 py-1 text-xs focus:ring-1 focus:ring-emerald-500 outline-none" />

          </div>

          <div class="col-span-1 flex justify-end pt-4">

            <button onclick="removeItem(${index})" class="text-rose-500 hover:text-rose-700 p-1 font-bold" title="Remove Item">✕</button>

          </div>

        `;

        container.appendChild(row);

      });

    }


    function updateItem(index, field, value) {

      if (field === 'qty' || field === 'price') {

        items[index][field] = parseFloat(value) || 0;

      } else {

        items[index][field] = value;

      }

      renderReceipt();

    }


    function addItem() {

      items.push({ name: "New Item", qty: 1, price: 5.00 });

      renderItemInputs();

      renderReceipt();

    }


    function removeItem(index) {

      if (items.length <= 1) return;

      items.splice(index, 1);

      renderItemInputs();

      renderReceipt();

    }


    function updateReceiptSize() {

      const width = document.getElementById('paperWidth').value;

      const receiptEl = document.getElementById('receipt-element');

      const badge = document.getElementById('sizeBadge');


      if (width === '58') {

        receiptEl.classList.remove('receipt-container-80mm');

        receiptEl.classList.add('receipt-container-58mm');

        badge.textContent = '58mm Thermal';

      } else {

        receiptEl.classList.remove('receipt-container-58mm');

        receiptEl.classList.add('receipt-container-80mm');

        badge.textContent = '80mm Thermal';

      }

    }


    function renderReceipt() {

      const curr = document.getElementById('currencySymbol').value || '';

      document.querySelectorAll('.r-curr').forEach(el => el.textContent = curr);


      document.getElementById('r-storeName').textContent = document.getElementById('storeName').value;

      document.getElementById('r-storeReg').textContent = document.getElementById('storeReg').value;

      document.getElementById('r-storeAddress').textContent = document.getElementById('storeAddress').value;


      const phone = document.getElementById('storePhone').value;

      document.getElementById('r-storePhone').textContent = phone ? `Tel: ${phone}` : '';


      const receiptNo = document.getElementById('receiptNo').value;

      document.getElementById('r-receiptNo').textContent = receiptNo;

      document.getElementById('r-barcodeText').textContent = `*${receiptNo}*`;

      document.getElementById('r-receiptDate').textContent = document.getElementById('receiptDate').value;

      document.getElementById('cashierName').textContent = document.getElementById('cashierName').value;


      const customer = document.getElementById('customerName').value;

      const customerRow = document.getElementById('r-customerRow');

      if (customer.trim() !== '') {

        customerRow.style.display = 'flex';

        document.getElementById('r-customerName').textContent = customer;

      } else {

        customerRow.style.display = 'none';

      }


      const rItemsContainer = document.getElementById('r-itemsList');

      rItemsContainer.innerHTML = '';

      let subtotal = 0;


      items.forEach(item => {

        const lineTotal = item.qty * item.price;

        subtotal += lineTotal;


        const itemDiv = document.createElement('div');

        itemDiv.innerHTML = `

          <div class="font-medium">${item.name || 'Unnamed Item'}</div>

          <div class="flex justify-between text-[10px] pl-2">

            <span>${item.qty} x ${item.price.toFixed(2)}</span>

            <span>${lineTotal.toFixed(2)}</span>

          </div>

        `;

        rItemsContainer.appendChild(itemDiv);

      });


      const discount = parseFloat(document.getElementById('discountAmt').value) || 0;

      const taxRate = parseFloat(document.getElementById('taxRate').value) || 0;

      const serviceRate = parseFloat(document.getElementById('serviceRate').value) || 0;


      const taxableAmount = Math.max(0, subtotal - discount);

      const serviceAmt = taxableAmount * (serviceRate / 100);

      const taxAmt = taxableAmount * (taxRate / 100);

      const grandTotal = taxableAmount + serviceAmt + taxAmt;


      document.getElementById('r-subtotal').textContent = subtotal.toFixed(2);


      const discountRow = document.getElementById('r-discountRow');

      if (discount > 0) {

        discountRow.style.display = 'flex';

        document.getElementById('r-discount').textContent = `-${discount.toFixed(2)}`;

      } else {

        discountRow.style.display = 'none';

      }


      const serviceRow = document.getElementById('r-serviceRow');

      if (serviceRate > 0) {

        serviceRow.style.display = 'flex';

        document.getElementById('r-serviceRate').textContent = serviceRate;

        document.getElementById('r-serviceAmt').textContent = serviceAmt.toFixed(2);

      } else {

        serviceRow.style.display = 'none';

      }


      const taxRow = document.getElementById('r-taxRow');

      if (taxRate > 0) {

        taxRow.style.display = 'flex';

        document.getElementById('r-taxRate').textContent = taxRate;

        document.getElementById('r-taxAmt').textContent = taxAmt.toFixed(2);

      } else {

        taxRow.style.display = 'none';

      }


      document.getElementById('r-total').textContent = grandTotal.toFixed(2);


      const paymentMethod = document.getElementById('paymentMethod').value;

      const amountPaid = parseFloat(document.getElementById('amountPaid').value) || 0;

      const change = Math.max(0, amountPaid - grandTotal);


      document.getElementById('r-paymentMethod').textContent = paymentMethod;

      document.getElementById('r-amountPaid').textContent = `${curr} ${amountPaid.toFixed(2)}`;

      document.getElementById('r-change').textContent = `${curr} ${change.toFixed(2)}`;


      document.getElementById('r-footerNote').textContent = document.getElementById('footerNote').value;

      const showBarcode = document.getElementById('showBarcode').value;

      document.getElementById('r-barcodeContainer').style.display = showBarcode === 'yes' ? 'flex' : 'none';

    }


    function downloadReceiptPDF() {

      const receiptEl = document.getElementById('receipt-element');

      const paperWidthMM = parseInt(document.getElementById('paperWidth').value, 10) || 80;

      const receiptNo = document.getElementById('receiptNo').value || 'receipt';


      const pixelWidth = receiptEl.offsetWidth;

      const pixelHeight = receiptEl.offsetHeight;

      const calculatedHeightMM = Math.ceil((pixelHeight / pixelWidth) * paperWidthMM) + 4;


      const opt = {

        margin: 0,

        filename: `${receiptNo}.pdf`,

        image: { type: 'jpeg', quality: 1 },

        html2canvas: {

          scale: 3,

          useCORS: true,

          backgroundColor: '#ffffff'

        },

        jsPDF: {

          unit: 'mm',

          format: [paperWidthMM, calculatedHeightMM],

          orientation: 'portrait'

        }

      };


      html2pdf().set(opt).from(receiptEl).save();

    }


    function resetForm() {

      document.getElementById('storeName').value = "KOPI & CO. ROASTERS";

      document.getElementById('storeReg').value = "SSM: 202401009876 (1456789-X)";

      document.getElementById('storePhone').value = "+60 3-2145 8899";

      document.getElementById('storeAddress').value = "Lot G-12, Jalan Bukit Bintang,\n55100 Kuala Lumpur, Malaysia";

      document.getElementById('receiptNo').value = "INV-2025-0842";

      document.getElementById('cashierName').value = "Farhan";

      document.getElementById('customerName').value = "Walk-in (Table 04)";

      document.getElementById('discountAmt').value = "0.00";

      document.getElementById('taxRate').value = "6";

      document.getElementById('serviceRate').value = "0";

      document.getElementById('amountPaid').value = "50.00";

      setInitialDateTime();


      items = [

        { name: "Iced Spanish Latte", qty: 2, price: 13.50 },

        { name: "Butter Croissant", qty: 1, price: 9.00 },

        { name: "Espresso Macchiato", qty: 1, price: 10.00 }

      ];

      renderItemInputs();

      renderReceipt();

    }


    window.onload = () => {

      setInitialDateTime();

      renderItemInputs();

      renderReceipt();

    };

  </script>

</body>

</html>