SuiteCoffee/backup/comandas.html
msaldain f483058c2c Se pudo conectar satisfactoriamente a la base de datos tenantdb_1 y suitecoffee-db.
En ./services/app/

Se sirvierons los HTML de la carpeta /pages.

Se crearon los endpoints REST para crear y listar roles, usuarios, categorias, productos.
2025-08-14 23:37:38 +00:00

196 lines
5.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Crear comanda</title>
</head>
<body>
<h1>Crear comanda</h1>
<section>
<label>
Mesa (ID o número):
<input type="number" id="mesaId" required />
</label>
<br />
<label>
Mozo (ID de usuario):
<input type="text" id="mozoId" required />
</label>
<br />
<label>
Notas:
<input type="text" id="notas" placeholder="Sin observaciones" />
</label>
</section>
<hr />
<section>
<h2>Agregar productos</h2>
<label>
Producto:
<select id="productoSelect"></select>
</label>
<label>
Cantidad:
<input type="number" id="cantidadInput" value="1" min="1" />
</label>
<button id="agregarBtn">Agregar</button>
<h3>Items de la comanda</h3>
<ul id="itemsList"></ul>
</section>
<hr />
<button id="enviarBtn">Enviar comanda</button>
<pre id="salida"></pre>
<script>
// === CONFIGURA AQUÍ SI ES NECESARIO ===
const API_BASE = "http://localhost:3000"; // Cambia al puerto/host de tu servidor Node
const PRODUCTOS_PATH = "/productos"; // GET
const COMANDAS_PATH = "/comandas"; // POST
// === ESTADO EN MEMORIA ===
const productosCache = new Map(); // id -> {id, nombre, ...}
const items = []; // {producto_id, cantidad}
// === ELEMENTOS DEL DOM ===
const productoSelect = document.getElementById("productoSelect");
const cantidadInput = document.getElementById("cantidadInput");
const agregarBtn = document.getElementById("agregarBtn");
const itemsList = document.getElementById("itemsList");
const enviarBtn = document.getElementById("enviarBtn");
const mesaIdInput = document.getElementById("mesaId");
const mozoIdInput = document.getElementById("mozoId");
const notasInput = document.getElementById("notas");
const salida = document.getElementById("salida");
// === UTILIDADES ===
function renderItems() {
itemsList.innerHTML = "";
items.forEach((it, idx) => {
const li = document.createElement("li");
const prod = productosCache.get(it.producto_id);
const nombre = prod ? (prod.nombre || prod.name || `Producto ${it.producto_id}`) : `ID ${it.producto_id}`;
li.textContent = `${nombre} × ${it.cantidad}`;
const btn = document.createElement("button");
btn.textContent = "Quitar";
btn.onclick = () => {
items.splice(idx, 1);
renderItems();
};
li.appendChild(document.createTextNode(" "));
li.appendChild(btn);
itemsList.appendChild(li);
});
}
function mostrarMensaje(obj) {
try {
salida.textContent = typeof obj === "string" ? obj : JSON.stringify(obj, null, 2);
} catch {
salida.textContent = String(obj);
}
}
function validarEnteroPositivo(valor) {
const n = Number(valor);
return Number.isInteger(n) && n > 0;
}
// === LOGICA ===
async function cargarProductos() {
try {
const res = await fetch(API_BASE + PRODUCTOS_PATH);
if (!res.ok) throw new Error("No se pudieron obtener los productos");
const data = await res.json();
// Espera un array de productos con al menos {id, nombre}
productoSelect.innerHTML = "";
data.forEach(p => {
productosCache.set(p.id, p);
const opt = document.createElement("option");
opt.value = p.id;
opt.textContent = p.nombre || p.name || `Producto ${p.id}`;
productoSelect.appendChild(opt);
});
if (data.length === 0) {
mostrarMensaje("No hay productos disponibles.");
}
} catch (e) {
mostrarMensaje("Error cargando productos: " + e.message);
}
}
agregarBtn.addEventListener("click", () => {
const prodId = Number(productoSelect.value);
const cant = Number(cantidadInput.value);
if (!validarEnteroPositivo(prodId)) {
return mostrarMensaje("Selecciona un producto válido.");
}
if (!validarEnteroPositivo(cant)) {
return mostrarMensaje("La cantidad debe ser un entero positivo.");
}
// Si ya existe el producto en la lista, acumula cantidad
const existente = items.find(i => i.producto_id === prodId);
if (existente) {
existente.cantidad += cant;
} else {
items.push({ producto_id: prodId, cantidad: cant });
}
renderItems();
cantidadInput.value = 1;
mostrarMensaje("Producto agregado.");
});
enviarBtn.addEventListener("click", async () => {
const mesa_id = Number(mesaIdInput.value);
const mozo_id = mozoIdInput.value.trim();
const notas = notasInput.value.trim();
if (!validarEnteroPositivo(mesa_id)) {
return mostrarMensaje("Debes indicar un número de mesa válido.");
}
if (!mozo_id) {
return mostrarMensaje("Debes indicar el ID del mozo.");
}
if (items.length === 0) {
return mostrarMensaje("Agrega al menos un producto a la comanda.");
}
const payload = { mesa_id, mozo_id, notas, items };
enviarBtn.disabled = true;
mostrarMensaje("Enviando comanda...");
try {
const res = await fetch(API_BASE + COMANDAS_PATH, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
const data = await res.json();
if (!res.ok) {
mostrarMensaje({ error: "No se pudo crear la comanda", detalle: data });
} else {
mostrarMensaje({ ok: true, comanda: data });
// Limpia el estado
items.length = 0;
renderItems();
notasInput.value = "";
}
} catch (e) {
mostrarMensaje("Error al enviar comanda: " + e.message);
} finally {
enviarBtn.disabled = false;
}
});
// Cargar productos al iniciar
cargarProductos();
</script>
</body>
</html>