Spaces:
Running
Running
Create a mobile credit application for my grocery store, including functions such as buying, selling, total debt, total credit, adding a buyer, deleting a buyer, and editing. - Initial Deployment
d5a7171 verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Grocery Store Credit System</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"> | |
| <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| </head> | |
| <body class="bg-gray-100"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <h1 class="text-3xl font-bold text-center mb-8">Grocery Store Credit System</h1> | |
| <!-- Summary Cards --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8"> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h3 class="text-lg font-semibold mb-2">Total Credit</h3> | |
| <p class="text-2xl font-bold text-green-600" id="totalCredit">$0.00</p> | |
| </div> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h3 class="text-lg font-semibold mb-2">Total Debt</h3> | |
| <p class="text-2xl font-bold text-red-600" id="totalDebt">$0.00</p> | |
| </div> | |
| </div> | |
| <!-- Buyer Management --> | |
| <div class="bg-white p-4 rounded-lg shadow mb-8"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-semibold">Buyers</h2> | |
| <button onclick="openAddBuyerModal()" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"> | |
| <i data-feather="plus"></i> Add Buyer | |
| </button> | |
| </div> | |
| <div class="overflow-x-auto"> | |
| <table class="min-w-full bg-white"> | |
| <thead> | |
| <tr> | |
| <th class="py-2 px-4 border-b">Name</th> | |
| <th class="py-2 px-4 border-b">Phone</th> | |
| <th class="py-2 px-4 border-b">Balance</th> | |
| <th class="py-2 px-4 border-b">Actions</th> | |
| </tr> | |
| </thead> | |
| <tbody id="buyersTable"> | |
| <!-- Buyers will be populated here --> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| <!-- Transaction Section --> | |
| <div class="bg-white p-4 rounded-lg shadow"> | |
| <h2 class="text-xl font-semibold mb-4">Transactions</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4"> | |
| <div> | |
| <label class="block mb-2">Select Buyer</label> | |
| <select id="transactionBuyer" class="w-full p-2 border rounded"> | |
| <option value="">Select a buyer</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block mb-2">Amount</label> | |
| <input type="number" id="transactionAmount" class="w-full p-2 border rounded" placeholder="0.00"> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <button onclick="addCredit()" class="bg-green-500 text-white p-2 rounded hover:bg-green-600"> | |
| <i data-feather="plus-circle"></i> Add Credit | |
| </button> | |
| <button onclick="addDebt()" class="bg-red-500 text-white p-2 rounded hover:bg-red-600"> | |
| <i data-feather="minus-circle"></i> Add Debt | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Add Buyer Modal --> | |
| <div id="addBuyerModal" class="fixed inset-0 bg-black bg-opacity-50 hidden flex items-center justify-center"> | |
| <div class="bg-white p-6 rounded-lg w-full max-w-md"> | |
| <h2 class="text-xl font-semibold mb-4">Add New Buyer</h2> | |
| <div class="mb-4"> | |
| <label class="block mb-2">Full Name</label> | |
| <input type="text" id="buyerName" class="w-full p-2 border rounded"> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block mb-2">Phone Number</label> | |
| <input type="tel" id="buyerPhone" class="w-full p-2 border rounded"> | |
| </div> | |
| <div class="flex justify-end space-x-2"> | |
| <button onclick="closeAddBuyerModal()" class="px-4 py-2 border rounded">Cancel</button> | |
| <button onclick="saveBuyer()" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">Save</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Edit Buyer Modal --> | |
| <div id="editBuyerModal" class="fixed inset-0 bg-black bg-opacity-50 hidden flex items-center justify-center"> | |
| <div class="bg-white p-6 rounded-lg w-full max-w-md"> | |
| <h2 class="text-xl font-semibold mb-4">Edit Buyer</h2> | |
| <input type="hidden" id="editBuyerId"> | |
| <div class="mb-4"> | |
| <label class="block mb-2">Full Name</label> | |
| <input type="text" id="editBuyerName" class="w-full p-2 border rounded"> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block mb-2">Phone Number</label> | |
| <input type="tel" id="editBuyerPhone" class="w-full p-2 border rounded"> | |
| </div> | |
| <div class="flex justify-end space-x-2"> | |
| <button onclick="closeEditBuyerModal()" class="px-4 py-2 border rounded">Cancel</button> | |
| <button onclick="updateBuyer()" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">Update</button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Sample data storage (in a real app, use a database) | |
| let buyers = []; | |
| let transactions = []; | |
| // DOM elements | |
| const buyersTable = document.getElementById('buyersTable'); | |
| const transactionBuyer = document.getElementById('transactionBuyer'); | |
| const totalCreditEl = document.getElementById('totalCredit'); | |
| const totalDebtEl = document.getElementById('totalDebt'); | |
| // Modal elements | |
| const addBuyerModal = document.getElementById('addBuyerModal'); | |
| const editBuyerModal = document.getElementById('editBuyerModal'); | |
| // Initialize | |
| function init() { | |
| feather.replace(); | |
| AOS.init(); | |
| renderBuyers(); | |
| updateTotals(); | |
| } | |
| // Render buyers table | |
| function renderBuyers() { | |
| buyersTable.innerHTML = ''; | |
| transactionBuyer.innerHTML = '<option value="">Select a buyer</option>'; | |
| buyers.forEach(buyer => { | |
| // Calculate balance | |
| const balance = calculateBalance(buyer.id); | |
| // Add to table | |
| const row = document.createElement('tr'); | |
| row.innerHTML = ` | |
| <td class="py-2 px-4 border-b">${buyer.name}</td> | |
| <td class="py-2 px-4 border-b">${buyer.phone}</td> | |
| <td class="py-2 px-4 border-b ${balance >= 0 ? 'text-green-600' : 'text-red-600'}"> | |
| $${Math.abs(balance).toFixed(2)} ${balance >= 0 ? '(CR)' : '(DR)'} | |
| </td> | |
| <td class="py-2 px-4 border-b"> | |
| <button onclick="openEditBuyerModal('${buyer.id}')" class="text-blue-500 mr-2"> | |
| <i data-feather="edit"></i> | |
| </button> | |
| <button onclick="deleteBuyer('${buyer.id}')" class="text-red-500"> | |
| <i data-feather="trash-2"></i> | |
| </button> | |
| </td> | |
| `; | |
| buyersTable.appendChild(row); | |
| // Add to transaction dropdown | |
| const option = document.createElement('option'); | |
| option.value = buyer.id; | |
| option.textContent = buyer.name; | |
| transactionBuyer.appendChild(option); | |
| }); | |
| feather.replace(); | |
| } | |
| // Calculate balance for a buyer | |
| function calculateBalance(buyerId) { | |
| const buyerTransactions = transactions.filter(t => t.buyerId === buyerId); | |
| return buyerTransactions.reduce((total, t) => { | |
| return total + (t.type === 'credit' ? t.amount : -t.amount); | |
| }, 0); | |
| } | |
| // Update summary totals | |
| function updateTotals() { | |
| const allBalances = buyers.map(b => calculateBalance(b.id)); | |
| const totalCredit = allBalances.filter(b => b > 0).reduce((a, b) => a + b, 0); | |
| const totalDebt = allBalances.filter(b => b < 0).reduce((a, b) => a + b, 0); | |
| totalCreditEl.textContent = `$${totalCredit.toFixed(2)}`; | |
| totalDebtEl.textContent = `$${Math.abs(totalDebt).toFixed(2)}`; | |
| } | |
| // Buyer management functions | |
| function openAddBuyerModal() { | |
| addBuyerModal.classList.remove('hidden'); | |
| } | |
| function closeAddBuyerModal() { | |
| addBuyerModal.classList.add('hidden'); | |
| document.getElementById('buyerName').value = ''; | |
| document.getElementById('buyerPhone').value = ''; | |
| } | |
| function saveBuyer() { | |
| const name = document.getElementById('buyerName').value.trim(); | |
| const phone = document.getElementById('buyerPhone').value.trim(); | |
| if (!name || !phone) { | |
| alert('Please fill all fields'); | |
| return; | |
| } | |
| const newBuyer = { | |
| id: Date.now().toString(), | |
| name, | |
| phone | |
| }; | |
| buyers.push(newBuyer); | |
| renderBuyers(); | |
| closeAddBuyerModal(); | |
| } | |
| function openEditBuyerModal(id) { | |
| const buyer = buyers.find(b => b.id === id); | |
| if (!buyer) return; | |
| document.getElementById('editBuyerId').value = buyer.id; | |
| document.getElementById('editBuyerName').value = buyer.name; | |
| document.getElementById('editBuyerPhone').value = buyer.phone; | |
| editBuyerModal.classList.remove('hidden'); | |
| } | |
| function closeEditBuyerModal() { | |
| editBuyerModal.classList.add('hidden'); | |
| } | |
| function updateBuyer() { | |
| const id = document.getElementById('editBuyerId').value; | |
| const name = document.getElementById('editBuyerName').value.trim(); | |
| const phone = document.getElementById('editBuyerPhone').value.trim(); | |
| if (!name || !phone) { | |
| alert('Please fill all fields'); | |
| return; | |
| } | |
| const buyerIndex = buyers.findIndex(b => b.id === id); | |
| if (buyerIndex !== -1) { | |
| buyers[buyerIndex] = { ...buyers[buyerIndex], name, phone }; | |
| renderBuyers(); | |
| closeEditBuyerModal(); | |
| } | |
| } | |
| function deleteBuyer(id) { | |
| if (confirm('Are you sure you want to delete this buyer?')) { | |
| buyers = buyers.filter(b => b.id !== id); | |
| transactions = transactions.filter(t => t.buyerId !== id); | |
| renderBuyers(); | |
| updateTotals(); | |
| } | |
| } | |
| // Transaction functions | |
| function addCredit() { | |
| const buyerId = transactionBuyer.value; | |
| const amount = parseFloat(document.getElementById('transactionAmount').value); | |
| if (!buyerId || isNaN(amount) || amount <= 0) { | |
| alert('Please select a buyer and enter a valid amount'); | |
| return; | |
| } | |
| transactions.push({ | |
| id: Date.now().toString(), | |
| buyerId, | |
| type: 'credit', | |
| amount, | |
| date: new Date().toISOString() | |
| }); | |
| document.getElementById('transactionAmount').value = ''; | |
| renderBuyers(); | |
| updateTotals(); | |
| } | |
| function addDebt() { | |
| const buyerId = transactionBuyer.value; | |
| const amount = parseFloat(document.getElementById('transactionAmount').value); | |
| if (!buyerId || isNaN(amount) || amount <= 0) { | |
| alert('Please select a buyer and enter a valid amount'); | |
| return; | |
| } | |
| transactions.push({ | |
| id: Date.now().toString(), | |
| buyerId, | |
| type: 'debt', | |
| amount, | |
| date: new Date().toISOString() | |
| }); | |
| document.getElementById('transactionAmount').value = ''; | |
| renderBuyers(); | |
| updateTotals(); | |
| } | |
| // Initialize on load | |
| window.onload = init; | |
| </script> | |
| </body> | |
| </html> |