|
<!DOCTYPE html> |
|
<html lang="es"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Kiosco - Inventario y Cuadre</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> |
|
.fade-in { |
|
animation: fadeIn 0.3s ease-in-out; |
|
} |
|
@keyframes fadeIn { |
|
from { opacity: 0; transform: translateY(10px); } |
|
to { opacity: 1; transform: translateY(0); } |
|
} |
|
.receipt-print { |
|
font-family: 'Courier New', monospace; |
|
background-color: white; |
|
padding: 15px; |
|
border-radius: 5px; |
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1); |
|
} |
|
.product-row:hover { |
|
background-color: #f0f9ff; |
|
} |
|
.sold-animation { |
|
animation: soldPulse 0.5s ease-in-out; |
|
} |
|
@keyframes soldPulse { |
|
0% { background-color: #f0fdf4; } |
|
50% { background-color: #dcfce7; } |
|
100% { background-color: #f0fdf4; } |
|
} |
|
.delete-confirmation { |
|
animation: shake 0.5s ease-in-out; |
|
} |
|
@keyframes shake { |
|
0%, 100% { transform: translateX(0); } |
|
20%, 60% { transform: translateX(-5px); } |
|
40%, 80% { transform: translateX(5px); } |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-100"> |
|
<div class="container mx-auto px-4 py-6 max-w-4xl"> |
|
|
|
<header class="bg-blue-600 text-white rounded-lg shadow-md p-4 mb-6"> |
|
<div class="flex items-center justify-between"> |
|
<div> |
|
<h1 class="text-2xl font-bold">Kiosco Ventas PRO</h1> |
|
<p class="text-blue-100 text-sm" id="current-date"></p> |
|
</div> |
|
<div class="flex items-center space-x-4"> |
|
<div class="bg-white text-blue-600 rounded-full w-12 h-12 flex items-center justify-center"> |
|
<i class="fas fa-cash-register text-2xl"></i> |
|
</div> |
|
<div class="text-right"> |
|
<p class="text-sm">Turno: <span id="current-shift">Mañana</span></p> |
|
<p class="text-sm">Usuario: <span id="current-user">Admin</span></p> |
|
</div> |
|
</div> |
|
</div> |
|
</header> |
|
|
|
|
|
<div class="bg-white rounded-lg shadow-md overflow-hidden mb-6"> |
|
|
|
<div class="flex border-b"> |
|
<button id="tab-inventory" class="flex-1 py-3 font-medium text-blue-600 border-b-2 border-blue-600"> |
|
<i class="fas fa-boxes mr-2"></i>Inventario |
|
</button> |
|
<button id="tab-register" class="flex-1 py-3 font-medium text-gray-500"> |
|
<i class="fas fa-calculator mr-2"></i>Cuadre |
|
</button> |
|
<button id="tab-history" class="flex-1 py-3 font-medium text-gray-500"> |
|
<i class="fas fa-history mr-2"></i>Historial |
|
</button> |
|
<button id="tab-settings" class="flex-1 py-3 font-medium text-gray-500"> |
|
<i class="fas fa-cog mr-2"></i>Ajustes |
|
</button> |
|
</div> |
|
|
|
|
|
<div id="inventory-content" class="p-4 fade-in"> |
|
<div class="mb-4 flex"> |
|
<input type="text" id="product-search" class="flex-1 px-3 py-2 border rounded-l-lg focus:outline-none" placeholder="Buscar producto..."> |
|
<button id="search-product" class="bg-blue-600 text-white px-4 py-2 rounded-r-lg"> |
|
<i class="fas fa-search"></i> |
|
</button> |
|
</div> |
|
|
|
<div class="mb-4 flex justify-between items-center"> |
|
<h3 class="font-bold text-lg">Productos en inventario</h3> |
|
<div class="flex space-x-2"> |
|
<button id="add-product" class="bg-green-600 hover:bg-green-700 text-white px-3 py-1 rounded-lg text-sm"> |
|
<i class="fas fa-plus mr-1"></i>Agregar |
|
</button> |
|
<button id="delete-selected" class="bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded-lg text-sm hidden"> |
|
<i class="fas fa-trash-alt mr-1"></i>Eliminar |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div class="overflow-x-auto"> |
|
<table class="w-full"> |
|
<thead class="bg-gray-100"> |
|
<tr> |
|
<th class="px-4 py-2 text-left w-8"> |
|
<input type="checkbox" id="select-all" class="form-checkbox h-4 w-4 text-blue-600"> |
|
</th> |
|
<th class="px-4 py-2 text-left">Producto</th> |
|
<th class="px-4 py-2 text-left">Precio</th> |
|
<th class="px-4 py-2 text-left">Stock</th> |
|
<th class="px-4 py-2 text-left">Vendidos</th> |
|
<th class="px-4 py-2 text-left">Total</th> |
|
<th class="px-4 py-2 text-left">Acciones</th> |
|
</tr> |
|
</thead> |
|
<tbody id="product-list"> |
|
|
|
</tbody> |
|
</table> |
|
</div> |
|
|
|
<div class="mt-4 p-3 bg-blue-50 rounded-lg"> |
|
<div class="flex justify-between"> |
|
<span class="font-medium">Total vendido hoy:</span> |
|
<span id="daily-sales-total" class="font-bold">$0.00</span> |
|
</div> |
|
<div class="flex justify-between"> |
|
<span class="font-medium">Productos vendidos:</span> |
|
<span id="products-sold-count" class="font-bold">0</span> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="register-content" class="hidden p-4"> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Efectivo Inicial</label> |
|
<input type="number" id="initial-cash" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="0.00"> |
|
</div> |
|
|
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Ventas del día (automático)</label> |
|
<input type="number" id="daily-sales" class="w-full px-3 py-2 border rounded-lg bg-gray-100" placeholder="0.00" readonly> |
|
</div> |
|
|
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Efectivo en caja</label> |
|
<input type="number" id="current-cash" class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="0.00"> |
|
</div> |
|
|
|
<div class="bg-blue-50 p-3 rounded-lg mb-4"> |
|
<div class="flex justify-between mb-1"> |
|
<span class="font-medium">Total teórico:</span> |
|
<span id="theoretical-total" class="font-bold">$0.00</span> |
|
</div> |
|
<div class="flex justify-between mb-1"> |
|
<span class="font-medium">Diferencia:</span> |
|
<span id="difference" class="font-bold">$0.00</span> |
|
</div> |
|
</div> |
|
|
|
<button id="calculate-btn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-3 px-4 rounded-lg font-medium mb-4 transition duration-200"> |
|
<i class="fas fa-calculator mr-2"></i>Calcular Cuadre |
|
</button> |
|
|
|
<div id="results" class="hidden"> |
|
<div class="receipt-print mb-4"> |
|
<h3 class="text-center font-bold text-lg mb-2">CUADRE DE CAJA</h3> |
|
<p class="text-center text-sm mb-4" id="receipt-date"></p> |
|
|
|
<div class="flex justify-between py-1 border-b"> |
|
<span>Efectivo Inicial:</span> |
|
<span id="receipt-initial"></span> |
|
</div> |
|
<div class="flex justify-between py-1 border-b"> |
|
<span>Ventas del día:</span> |
|
<span id="receipt-sales"></span> |
|
</div> |
|
<div class="flex justify-between py-1 border-b"> |
|
<span>Total Teórico:</span> |
|
<span id="receipt-theoretical"></span> |
|
</div> |
|
<div class="flex justify-between py-1 border-b"> |
|
<span>Efectivo en caja:</span> |
|
<span id="receipt-current"></span> |
|
</div> |
|
<div class="flex justify-between py-1 font-bold mt-2"> |
|
<span>Diferencia:</span> |
|
<span id="receipt-difference"></span> |
|
</div> |
|
</div> |
|
|
|
<div class="flex space-x-2"> |
|
<button id="save-btn" class="flex-1 bg-green-600 hover:bg-green-700 text-white py-2 px-4 rounded-lg font-medium transition duration-200"> |
|
<i class="fas fa-save mr-2"></i>Guardar |
|
</button> |
|
<button id="print-btn" class="flex-1 bg-gray-600 hover:bg-gray-700 text-white py-2 px-4 rounded-lg font-medium transition duration-200"> |
|
<i class="fas fa-print mr-2"></i>Imprimir |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="history-content" class="hidden p-4"> |
|
<div class="mb-4 flex items-center"> |
|
<input type="date" id="history-date" class="flex-1 px-3 py-2 border rounded-lg mr-2"> |
|
<button id="search-history" class="bg-blue-600 text-white px-4 py-2 rounded-lg"> |
|
<i class="fas fa-search"></i> |
|
</button> |
|
</div> |
|
|
|
<div id="history-list" class="space-y-3"> |
|
|
|
<div class="border rounded-lg p-3"> |
|
<div class="flex justify-between items-center mb-1"> |
|
<span class="font-medium">15/06/2023</span> |
|
<span class="text-sm bg-blue-100 text-blue-800 px-2 py-1 rounded">Cuadre</span> |
|
</div> |
|
<div class="flex justify-between text-sm"> |
|
<span>Ventas: $1,250.00</span> |
|
<span>Diferencia: <span class="font-bold text-green-600">$0.00</span></span> |
|
</div> |
|
</div> |
|
|
|
<div class="border rounded-lg p-3"> |
|
<div class="flex justify-between items-center mb-1"> |
|
<span class="font-medium">14/06/2023</span> |
|
<span class="text-sm bg-blue-100 text-blue-800 px-2 py-1 rounded">Cuadre</span> |
|
</div> |
|
<div class="flex justify-between text-sm"> |
|
<span>Ventas: $980.50</span> |
|
<span>Diferencia: <span class="font-bold text-red-600">-$5.50</span></span> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="settings-content" class="hidden p-4"> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Nombre del Kiosco</label> |
|
<input type="text" class="w-full px-3 py-2 border rounded-lg" value="Mi Kiosco"> |
|
</div> |
|
|
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Moneda</label> |
|
<select class="w-full px-3 py-2 border rounded-lg"> |
|
<option>Pesos ($)</option> |
|
<option>Dólares (USD)</option> |
|
<option>Euros (€)</option> |
|
</select> |
|
</div> |
|
|
|
<div class="mb-4"> |
|
<label class="flex items-center"> |
|
<input type="checkbox" class="form-checkbox h-5 w-5 text-blue-600" checked> |
|
<span class="ml-2 text-gray-700">Mostrar decimales</span> |
|
</label> |
|
</div> |
|
|
|
<div class="mb-4"> |
|
<label class="flex items-center"> |
|
<input type="checkbox" class="form-checkbox h-5 w-5 text-blue-600"> |
|
<span class="ml-2 text-gray-700">Imprimir automáticamente</span> |
|
</label> |
|
</div> |
|
|
|
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-3 px-4 rounded-lg font-medium mb-2 transition duration-200"> |
|
<i class="fas fa-save mr-2"></i>Guardar Ajustes |
|
</button> |
|
|
|
<button class="w-full bg-gray-600 hover:bg-gray-700 text-white py-3 px-4 rounded-lg font-medium transition duration-200"> |
|
<i class="fas fa-sync-alt mr-2"></i>Respaldar Datos |
|
</button> |
|
</div> |
|
</div> |
|
|
|
|
|
<footer class="text-center text-gray-500 text-sm"> |
|
<p>Kiosco App PRO v2.0 - © 2023</p> |
|
</footer> |
|
</div> |
|
|
|
|
|
<div id="add-product-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden"> |
|
<div class="bg-white rounded-lg p-6 w-full max-w-md"> |
|
<h3 class="text-xl font-bold mb-4">Agregar Producto</h3> |
|
|
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Nombre del Producto</label> |
|
<input type="text" id="product-name" class="w-full px-3 py-2 border rounded-lg"> |
|
</div> |
|
|
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Precio</label> |
|
<input type="number" id="product-price" class="w-full px-3 py-2 border rounded-lg"> |
|
</div> |
|
|
|
<div class="mb-4"> |
|
<label class="block text-gray-700 mb-2">Stock Inicial</label> |
|
<input type="number" id="product-stock" class="w-full px-3 py-2 border rounded-lg" value="1"> |
|
</div> |
|
|
|
<div class="flex justify-end space-x-2"> |
|
<button id="cancel-add" class="px-4 py-2 border rounded-lg">Cancelar</button> |
|
<button id="confirm-add" class="px-4 py-2 bg-blue-600 text-white rounded-lg">Agregar</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="delete-confirm-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden"> |
|
<div class="bg-white rounded-lg p-6 w-full max-w-md"> |
|
<h3 class="text-xl font-bold mb-4 text-red-600"> |
|
<i class="fas fa-exclamation-triangle mr-2"></i>Confirmar Eliminación |
|
</h3> |
|
|
|
<p class="mb-4">¿Estás seguro que deseas eliminar los productos seleccionados?</p> |
|
<p class="text-sm text-gray-500 mb-6">Esta acción no se puede deshacer.</p> |
|
|
|
<div class="flex justify-end space-x-2"> |
|
<button id="cancel-delete" class="px-4 py-2 border rounded-lg">Cancelar</button> |
|
<button id="confirm-delete" class="px-4 py-2 bg-red-600 text-white rounded-lg"> |
|
<i class="fas fa-trash-alt mr-2"></i>Eliminar |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
|
|
let products = [ |
|
{ id: 1, name: "Coca-Cola 600ml", price: 25.00, stock: 50, sold: 0 }, |
|
{ id: 2, name: "Sabritas 45g", price: 18.00, stock: 30, sold: 0 }, |
|
{ id: 3, name: "Galletas Emperador", price: 15.00, stock: 40, sold: 0 }, |
|
{ id: 4, name: "Agua 1L", price: 12.00, stock: 25, sold: 0 }, |
|
{ id: 5, name: "Chocolate Hershey's", price: 20.00, stock: 20, sold: 0 } |
|
]; |
|
|
|
|
|
let dailySalesTotal = 0; |
|
let productsSoldCount = 0; |
|
let initialCash = 0; |
|
let selectedProducts = []; |
|
|
|
|
|
const now = new Date(); |
|
document.getElementById('current-date').textContent = now.toLocaleDateString('es-ES', { |
|
weekday: 'long', |
|
year: 'numeric', |
|
month: 'long', |
|
day: 'numeric' |
|
}); |
|
|
|
|
|
document.getElementById('receipt-date').textContent = now.toLocaleDateString('es-ES', { |
|
year: 'numeric', |
|
month: 'long', |
|
day: 'numeric', |
|
hour: '2-digit', |
|
minute: '2-digit' |
|
}); |
|
|
|
|
|
function renderProductList() { |
|
const productList = document.getElementById('product-list'); |
|
productList.innerHTML = ''; |
|
|
|
products.forEach(product => { |
|
const isSelected = selectedProducts.includes(product.id); |
|
const row = document.createElement('tr'); |
|
row.className = `product-row border-b ${isSelected ? 'bg-blue-50' : ''}`; |
|
row.innerHTML = ` |
|
<td class="px-4 py-3 w-8"> |
|
<input type="checkbox" class="product-checkbox form-checkbox h-4 w-4 text-blue-600" |
|
data-id="${product.id}" ${isSelected ? 'checked' : ''}> |
|
</td> |
|
<td class="px-4 py-3">${product.name}</td> |
|
<td class="px-4 py-3">${formatCurrency(product.price)}</td> |
|
<td class="px-4 py-3">${product.stock}</td> |
|
<td class="px-4 py-3">${product.sold}</td> |
|
<td class="px-4 py-3">${formatCurrency(product.price * product.sold)}</td> |
|
<td class="px-4 py-3"> |
|
<button class="sell-btn bg-green-100 text-green-800 px-2 py-1 rounded text-sm" data-id="${product.id}"> |
|
<i class="fas fa-cash-register mr-1"></i>Vender |
|
</button> |
|
<button class="edit-btn bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm ml-1" data-id="${product.id}"> |
|
<i class="fas fa-edit mr-1"></i>Editar |
|
</button> |
|
<button class="delete-btn bg-red-100 text-red-800 px-2 py-1 rounded text-sm ml-1" data-id="${product.id}"> |
|
<i class="fas fa-trash-alt mr-1"></i> |
|
</button> |
|
</td> |
|
`; |
|
productList.appendChild(row); |
|
}); |
|
|
|
|
|
document.getElementById('daily-sales-total').textContent = formatCurrency(dailySalesTotal); |
|
document.getElementById('products-sold-count').textContent = productsSoldCount; |
|
document.getElementById('daily-sales').value = dailySalesTotal.toFixed(2); |
|
|
|
|
|
const deleteBtn = document.getElementById('delete-selected'); |
|
if (selectedProducts.length > 0) { |
|
deleteBtn.classList.remove('hidden'); |
|
deleteBtn.innerHTML = `<i class="fas fa-trash-alt mr-1"></i>Eliminar (${selectedProducts.length})`; |
|
} else { |
|
deleteBtn.classList.add('hidden'); |
|
} |
|
|
|
|
|
const selectAll = document.getElementById('select-all'); |
|
selectAll.checked = selectedProducts.length > 0 && selectedProducts.length === products.length; |
|
|
|
|
|
addProductEventListeners(); |
|
} |
|
|
|
|
|
function addProductEventListeners() { |
|
|
|
document.querySelectorAll('.sell-btn').forEach(button => { |
|
button.addEventListener('click', function() { |
|
const productId = parseInt(this.getAttribute('data-id')); |
|
sellProduct(productId); |
|
}); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.delete-btn').forEach(button => { |
|
button.addEventListener('click', function() { |
|
const productId = parseInt(this.getAttribute('data-id')); |
|
showDeleteModal([productId]); |
|
}); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.product-checkbox').forEach(checkbox => { |
|
checkbox.addEventListener('change', function() { |
|
const productId = parseInt(this.getAttribute('data-id')); |
|
if (this.checked) { |
|
if (!selectedProducts.includes(productId)) { |
|
selectedProducts.push(productId); |
|
} |
|
} else { |
|
selectedProducts = selectedProducts.filter(id => id !== productId); |
|
} |
|
renderProductList(); |
|
}); |
|
}); |
|
} |
|
|
|
|
|
function sellProduct(productId) { |
|
const product = products.find(p => p.id === productId); |
|
|
|
if (product && product.stock > 0) { |
|
product.stock--; |
|
product.sold++; |
|
dailySalesTotal += product.price; |
|
productsSoldCount++; |
|
|
|
|
|
renderProductList(); |
|
|
|
|
|
const row = document.querySelector(`.sell-btn[data-id="${productId}"]`).closest('tr'); |
|
row.classList.add('sold-animation'); |
|
setTimeout(() => { |
|
row.classList.remove('sold-animation'); |
|
}, 500); |
|
} else { |
|
alert('No hay suficiente stock de este producto'); |
|
} |
|
} |
|
|
|
|
|
function formatCurrency(amount) { |
|
return '$' + amount.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); |
|
} |
|
|
|
|
|
const tabs = { |
|
inventory: document.getElementById('tab-inventory'), |
|
register: document.getElementById('tab-register'), |
|
history: document.getElementById('tab-history'), |
|
settings: document.getElementById('tab-settings') |
|
}; |
|
|
|
const contents = { |
|
inventory: document.getElementById('inventory-content'), |
|
register: document.getElementById('register-content'), |
|
history: document.getElementById('history-content'), |
|
settings: document.getElementById('settings-content') |
|
}; |
|
|
|
function showTab(tabName) { |
|
|
|
Object.values(contents).forEach(content => { |
|
content.classList.add('hidden'); |
|
content.classList.remove('fade-in'); |
|
}); |
|
|
|
|
|
contents[tabName].classList.remove('hidden'); |
|
setTimeout(() => { |
|
contents[tabName].classList.add('fade-in'); |
|
}, 10); |
|
|
|
|
|
Object.values(tabs).forEach(tab => { |
|
tab.classList.remove('text-blue-600', 'border-blue-600'); |
|
tab.classList.add('text-gray-500'); |
|
}); |
|
|
|
tabs[tabName].classList.remove('text-gray-500'); |
|
tabs[tabName].classList.add('text-blue-600', 'border-blue-600'); |
|
} |
|
|
|
|
|
tabs.inventory.addEventListener('click', () => showTab('inventory')); |
|
tabs.register.addEventListener('click', () => showTab('register')); |
|
tabs.history.addEventListener('click', () => showTab('history')); |
|
tabs.settings.addEventListener('click', () => showTab('settings')); |
|
|
|
|
|
document.getElementById('calculate-btn').addEventListener('click', function() { |
|
initialCash = parseFloat(document.getElementById('initial-cash').value) || 0; |
|
const currentCash = parseFloat(document.getElementById('current-cash').value) || 0; |
|
|
|
const theoreticalTotal = initialCash + dailySalesTotal; |
|
const difference = currentCash - theoreticalTotal; |
|
|
|
|
|
document.getElementById('theoretical-total').textContent = formatCurrency(theoreticalTotal); |
|
document.getElementById('difference').textContent = formatCurrency(difference); |
|
|
|
|
|
const diffElement = document.getElementById('difference'); |
|
diffElement.classList.remove('text-green-600', 'text-red-600'); |
|
if (difference > 0) { |
|
diffElement.classList.add('text-green-600'); |
|
} else if (difference < 0) { |
|
diffElement.classList.add('text-red-600'); |
|
} |
|
|
|
|
|
document.getElementById('receipt-initial').textContent = formatCurrency(initialCash); |
|
document.getElementById('receipt-sales').textContent = formatCurrency(dailySalesTotal); |
|
document.getElementById('receipt-theoretical').textContent = formatCurrency(theoreticalTotal); |
|
document.getElementById('receipt-current').textContent = formatCurrency(currentCash); |
|
document.getElementById('receipt-difference').textContent = formatCurrency(difference); |
|
|
|
|
|
document.getElementById('results').classList.remove('hidden'); |
|
}); |
|
|
|
|
|
document.getElementById('save-btn').addEventListener('click', function() { |
|
alert('Cuadre guardado correctamente'); |
|
|
|
}); |
|
|
|
|
|
document.getElementById('print-btn').addEventListener('click', function() { |
|
|
|
const printContent = document.querySelector('.receipt-print').innerHTML; |
|
const originalContent = document.body.innerHTML; |
|
|
|
document.body.innerHTML = printContent; |
|
window.print(); |
|
document.body.innerHTML = originalContent; |
|
showTab('register'); |
|
}); |
|
|
|
|
|
document.getElementById('add-product').addEventListener('click', function() { |
|
document.getElementById('add-product-modal').classList.remove('hidden'); |
|
}); |
|
|
|
document.getElementById('cancel-add').addEventListener('click', function() { |
|
document.getElementById('add-product-modal').classList.add('hidden'); |
|
}); |
|
|
|
document.getElementById('confirm-add').addEventListener('click', function() { |
|
const name = document.getElementById('product-name').value; |
|
const price = parseFloat(document.getElementById('product-price').value); |
|
const stock = parseInt(document.getElementById('product-stock').value); |
|
|
|
if (name && !isNaN(price) && !isNaN(stock)) { |
|
const newId = products.length > 0 ? Math.max(...products.map(p => p.id)) + 1 : 1; |
|
products.push({ |
|
id: newId, |
|
name: name, |
|
price: price, |
|
stock: stock, |
|
sold: 0 |
|
}); |
|
|
|
renderProductList(); |
|
document.getElementById('add-product-modal').classList.add('hidden'); |
|
|
|
|
|
document.getElementById('product-name').value = ''; |
|
document.getElementById('product-price').value = ''; |
|
document.getElementById('product-stock').value = '1'; |
|
} else { |
|
alert('Por favor complete todos los campos correctamente'); |
|
} |
|
}); |
|
|
|
|
|
document.getElementById('select-all').addEventListener('change', function() { |
|
if (this.checked) { |
|
selectedProducts = products.map(p => p.id); |
|
} else { |
|
selectedProducts = []; |
|
} |
|
renderProductList(); |
|
}); |
|
|
|
|
|
document.getElementById('delete-selected').addEventListener('click', function() { |
|
if (selectedProducts.length > 0) { |
|
showDeleteModal(selectedProducts); |
|
} |
|
}); |
|
|
|
|
|
function showDeleteModal(idsToDelete) { |
|
const modal = document.getElementById('delete-confirm-modal'); |
|
modal.classList.remove('hidden'); |
|
|
|
document.getElementById('cancel-delete').addEventListener('click', function() { |
|
modal.classList.add('hidden'); |
|
}, { once: true }); |
|
|
|
document.getElementById('confirm-delete').addEventListener('click', function() { |
|
|
|
products = products.filter(p => !idsToDelete.includes(p.id)); |
|
|
|
|
|
selectedProducts = selectedProducts.filter(id => !idsToDelete.includes(id)); |
|
|
|
|
|
renderProductList(); |
|
modal.classList.add('hidden'); |
|
|
|
|
|
const toast = document.createElement('div'); |
|
toast.className = 'fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg'; |
|
toast.innerHTML = `<i class="fas fa-check-circle mr-2"></i>Productos eliminados correctamente`; |
|
document.body.appendChild(toast); |
|
|
|
setTimeout(() => { |
|
toast.classList.add('opacity-0', 'transition-opacity', 'duration-300'); |
|
setTimeout(() => toast.remove(), 300); |
|
}, 2000); |
|
}, { once: true }); |
|
} |
|
|
|
|
|
showTab('inventory'); |
|
renderProductList(); |
|
</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=yosmani/kioscos" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |