Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Single Line Receipt</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap'); | |
| @media print { | |
| .no-print { | |
| display: none ; | |
| } | |
| } | |
| .receipt-font { | |
| font-family: 'Inconsolata', monospace; | |
| } | |
| .receipt-paper { | |
| background: repeating-linear-gradient( | |
| to bottom, | |
| white, | |
| white 20px, | |
| #f0f0f0 20px, | |
| #f0f0f0 21px | |
| ); | |
| } | |
| .receipt-shadow { | |
| box-shadow: 0 0 10px rgba(0,0,0,0.2); | |
| } | |
| .receipt-cut { | |
| position: relative; | |
| } | |
| .receipt-cut::after { | |
| content: ""; | |
| position: absolute; | |
| bottom: -10px; | |
| left: 0; | |
| right: 0; | |
| height: 10px; | |
| background: linear-gradient(45deg, transparent 33.333%, #fff 33.333%, #fff 66.667%, transparent 66.667%), linear-gradient(-45deg, transparent 33.333%, #fff 33.333%, #fff 66.667%, transparent 66.667%); | |
| background-size: 10px 20px; | |
| background-repeat: repeat-x; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen flex items-center justify-center p-4"> | |
| <div class="w-full max-w-md mx-auto"> | |
| <div class="receipt-paper receipt-shadow receipt-cut p-6 rounded-lg bg-white"> | |
| <div class="receipt-font"> | |
| <!-- Header --> | |
| <div class="text-center mb-4"> | |
| <h1 class="text-xl font-bold">RETAIL STORE</h1> | |
| <p class="text-xs">123 Main Street, Cityville</p> | |
| <p class="text-xs">Tel: (555) 123-4567</p> | |
| <p class="text-xs">VAT No: 123456789</p> | |
| </div> | |
| <!-- Date & Cashier --> | |
| <div class="flex justify-between text-xs mb-2"> | |
| <span id="receipt-date">DATE: 01/01/2023</span> | |
| <span id="receipt-time">TIME: 12:00 PM</span> | |
| </div> | |
| <div class="text-xs mb-4"> | |
| <span>CASHIER: JOHN DOE</span> | |
| <span class="float-right">RECEIPT #: <span id="receipt-number">000001</span></span> | |
| </div> | |
| <!-- Items --> | |
| <div class="border-t border-dashed border-gray-400 pt-2 mb-2"> | |
| <div class="flex justify-between text-sm font-bold mb-1"> | |
| <span>ITEM</span> | |
| <span>TOTAL</span> | |
| </div> | |
| <div id="receipt-items"> | |
| <!-- Single line item will be added here --> | |
| </div> | |
| </div> | |
| <!-- Totals --> | |
| <div class="border-t border-dashed border-gray-400 pt-2"> | |
| <div class="flex justify-between text-sm"> | |
| <span>SUBTOTAL:</span> | |
| <span id="subtotal">$0.00</span> | |
| </div> | |
| <div class="flex justify-between text-sm"> | |
| <span>TAX (10%):</span> | |
| <span id="tax">$0.00</span> | |
| </div> | |
| <div class="flex justify-between font-bold mt-1"> | |
| <span>TOTAL:</span> | |
| <span id="total">$0.00</span> | |
| </div> | |
| </div> | |
| <!-- Payment --> | |
| <div class="border-t border-dashed border-gray-400 pt-2 mt-2 text-sm"> | |
| <div class="flex justify-between"> | |
| <span>PAYMENT:</span> | |
| <span id="payment-method">CASH</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>CHANGE:</span> | |
| <span id="change">$0.00</span> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <div class="text-center text-xs mt-4"> | |
| <p>THANK YOU FOR SHOPPING WITH US!</p> | |
| <p class="mt-1">Returns accepted within 14 days with receipt</p> | |
| <div class="mt-2 flex justify-center"> | |
| <div class="w-32 h-8 bg-black"></div> | |
| </div> | |
| <p class="mt-1">www.retailstore.com</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Controls --> | |
| <div class="mt-8 bg-white p-6 rounded-lg shadow no-print"> | |
| <h2 class="text-lg font-bold mb-4">Create Receipt</h2> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium mb-1">Item Name</label> | |
| <input type="text" id="item-name" class="w-full p-2 border rounded" placeholder="Enter item name"> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium mb-1">Price</label> | |
| <input type="number" id="item-price" class="w-full p-2 border rounded" placeholder="0.00" step="0.01" min="0"> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium mb-1">Payment Method</label> | |
| <select id="payment-select" class="w-full p-2 border rounded"> | |
| <option value="CASH">Cash</option> | |
| <option value="CARD">Card</option> | |
| <option value="MOBILE">Mobile Payment</option> | |
| </select> | |
| </div> | |
| <div class="flex space-x-2"> | |
| <button id="add-item" class="flex-1 bg-blue-600 text-white py-2 px-4 rounded hover:bg-blue-700 transition"> | |
| <i class="fas fa-plus mr-2"></i> Add Item | |
| </button> | |
| <button id="print-receipt" class="flex-1 bg-green-600 text-white py-2 px-4 rounded hover:bg-green-700 transition"> | |
| <i class="fas fa-print mr-2"></i> Print | |
| </button> | |
| <button id="new-receipt" class="flex-1 bg-gray-600 text-white py-2 px-4 rounded hover:bg-gray-700 transition"> | |
| <i class="fas fa-receipt mr-2"></i> New Receipt | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Set current date and time | |
| const now = new Date(); | |
| document.getElementById('receipt-date').textContent = 'DATE: ' + formatDate(now); | |
| document.getElementById('receipt-time').textContent = 'TIME: ' + formatTime(now); | |
| // Generate random receipt number | |
| document.getElementById('receipt-number').textContent = Math.floor(Math.random() * 900000 + 100000); | |
| // Initialize receipt data | |
| let receiptData = { | |
| items: [], | |
| subtotal: 0, | |
| tax: 0, | |
| total: 0, | |
| paymentMethod: 'CASH', | |
| change: 0 | |
| }; | |
| // Add item button | |
| document.getElementById('add-item').addEventListener('click', function() { | |
| const itemName = document.getElementById('item-name').value.trim(); | |
| const itemPrice = parseFloat(document.getElementById('item-price').value); | |
| if (!itemName || isNaN(itemPrice) || itemPrice <= 0) { | |
| alert('Please enter valid item name and price'); | |
| return; | |
| } | |
| // Add item to receipt data | |
| receiptData.items.push({ | |
| name: itemName, | |
| price: itemPrice | |
| }); | |
| // Update receipt display | |
| updateReceipt(); | |
| // Clear input fields | |
| document.getElementById('item-name').value = ''; | |
| document.getElementById('item-price').value = ''; | |
| document.getElementById('item-name').focus(); | |
| }); | |
| // Payment method change | |
| document.getElementById('payment-select').addEventListener('change', function() { | |
| receiptData.paymentMethod = this.value; | |
| updateReceipt(); | |
| }); | |
| // New receipt button | |
| document.getElementById('new-receipt').addEventListener('click', function() { | |
| // Reset receipt data | |
| receiptData = { | |
| items: [], | |
| subtotal: 0, | |
| tax: 0, | |
| total: 0, | |
| paymentMethod: 'CASH', | |
| change: 0 | |
| }; | |
| // Update UI | |
| document.getElementById('payment-select').value = 'CASH'; | |
| updateReceipt(); | |
| // Generate new receipt number | |
| document.getElementById('receipt-number').textContent = Math.floor(Math.random() * 900000 + 100000); | |
| // Set new date/time | |
| const now = new Date(); | |
| document.getElementById('receipt-date').textContent = 'DATE: ' + formatDate(now); | |
| document.getElementById('receipt-time').textContent = 'TIME: ' + formatTime(now); | |
| }); | |
| // Print receipt button | |
| document.getElementById('print-receipt').addEventListener('click', function() { | |
| if (receiptData.items.length === 0) { | |
| alert('Please add at least one item to print receipt'); | |
| return; | |
| } | |
| // Open print dialog | |
| window.print(); | |
| }); | |
| // Update receipt display | |
| function updateReceipt() { | |
| const itemsContainer = document.getElementById('receipt-items'); | |
| itemsContainer.innerHTML = ''; | |
| // Calculate totals | |
| receiptData.subtotal = receiptData.items.reduce((sum, item) => sum + item.price, 0); | |
| receiptData.tax = receiptData.subtotal * 0.1; // 10% tax | |
| receiptData.total = receiptData.subtotal + receiptData.tax; | |
| // For cash payments, calculate change (assuming customer paid with amount >= total) | |
| if (receiptData.paymentMethod === 'CASH') { | |
| receiptData.change = Math.max(0, Math.ceil(receiptData.total / 20) * 20 - receiptData.total); | |
| } else { | |
| receiptData.change = 0; | |
| } | |
| // Add items to receipt | |
| receiptData.items.forEach(item => { | |
| const itemElement = document.createElement('div'); | |
| itemElement.className = 'flex justify-between text-sm mb-1'; | |
| itemElement.innerHTML = ` | |
| <span class="truncate max-w-[180px]">${item.name}</span> | |
| <span>$${item.price.toFixed(2)}</span> | |
| `; | |
| itemsContainer.appendChild(itemElement); | |
| }); | |
| // Update totals | |
| document.getElementById('subtotal').textContent = '$' + receiptData.subtotal.toFixed(2); | |
| document.getElementById('tax').textContent = '$' + receiptData.tax.toFixed(2); | |
| document.getElementById('total').textContent = '$' + receiptData.total.toFixed(2); | |
| document.getElementById('payment-method').textContent = receiptData.paymentMethod; | |
| document.getElementById('change').textContent = '$' + receiptData.change.toFixed(2); | |
| } | |
| // Helper functions for date formatting | |
| function formatDate(date) { | |
| const day = String(date.getDate()).padStart(2, '0'); | |
| const month = String(date.getMonth() + 1).padStart(2, '0'); | |
| const year = date.getFullYear(); | |
| return `${month}/${day}/${year}`; | |
| } | |
| function formatTime(date) { | |
| let hours = date.getHours(); | |
| const minutes = String(date.getMinutes()).padStart(2, '0'); | |
| const ampm = hours >= 12 ? 'PM' : 'AM'; | |
| hours = hours % 12; | |
| hours = hours ? hours : 12; // the hour '0' should be '12' | |
| return `${hours}:${minutes} ${ampm}`; | |
| } | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=sombochea/receipt-entry" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |