En ./services/app/ Se sirvierons los HTML de la carpeta /pages. Se crearon los endpoints REST para crear y listar roles, usuarios, categorias, productos.
196 lines
5.9 KiB
HTML
196 lines
5.9 KiB
HTML
<!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>
|