From 44d1adecdc11225126865f26cc5b10325212fe63 Mon Sep 17 00:00:00 2001 From: msaldain Date: Fri, 29 Aug 2025 02:27:28 +0000 Subject: [PATCH] Desarrollo de views + frontend --- services/manso/package-lock.json | 80 +++- services/manso/package.json | 1 + services/manso/src/index.js | 138 ++++++- services/manso/src/pages/categorias.html | 70 ---- services/manso/src/pages/comandas.html | 355 ++++++++++++++++++ .../manso/src/pages/estadoComandas.html.bak | 280 ++++++++++++++ services/manso/src/pages/productos.html | 106 ------ services/manso/src/pages/roles.html | 62 --- services/manso/src/pages/usuarios.html | 104 ----- services/manso/src/views/estadoComanas.ejs | 18 + services/manso/src/views/layouts/main.ejs | 16 + services/manso/src/views/partials/_footer.ejs | 42 +++ services/manso/src/views/partials/_head.ejs | 22 ++ services/manso/src/views/partials/_navbar.ejs | 29 ++ .../manso/src/views/partials/_sidebar.ejs | 62 +++ 15 files changed, 1027 insertions(+), 358 deletions(-) delete mode 100644 services/manso/src/pages/categorias.html create mode 100644 services/manso/src/pages/comandas.html create mode 100644 services/manso/src/pages/estadoComandas.html.bak delete mode 100644 services/manso/src/pages/productos.html delete mode 100644 services/manso/src/pages/roles.html delete mode 100644 services/manso/src/pages/usuarios.html create mode 100644 services/manso/src/views/estadoComanas.ejs create mode 100644 services/manso/src/views/layouts/main.ejs create mode 100644 services/manso/src/views/partials/_footer.ejs create mode 100644 services/manso/src/views/partials/_head.ejs create mode 100644 services/manso/src/views/partials/_navbar.ejs create mode 100644 services/manso/src/views/partials/_sidebar.ejs diff --git a/services/manso/package-lock.json b/services/manso/package-lock.json index 0a0679e..c775380 100644 --- a/services/manso/package-lock.json +++ b/services/manso/package-lock.json @@ -1,17 +1,18 @@ { - "name": "aplication", + "name": "workarround", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "aplication", + "name": "workarround", "version": "1.0.0", "license": "ISC", "dependencies": { "chalk": "^5.6.0", "cors": "^2.8.5", "dotenv": "^17.2.1", + "ejs": "^3.1.10", "express": "^5.1.0", "express-ejs-layouts": "^2.5.1", "pg": "^8.16.3", @@ -56,11 +57,16 @@ "node": ">= 8" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/binary-extensions": { @@ -345,6 +351,21 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -446,6 +467,36 @@ "resolved": "https://registry.npmjs.org/express-ejs-layouts/-/express-ejs-layouts-2.5.1.tgz", "integrity": "sha512-IXROv9n3xKga7FowT06n1Qn927JR8ZWDn5Dc9CJQoiiaaDqbhW5PDmWShzbpAa2wjWT1vJqaIM1S6vJwwX11gA==" }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -732,6 +783,23 @@ "dev": true, "license": "ISC" }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -1018,6 +1086,12 @@ "split2": "^4.1.0" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", diff --git a/services/manso/package.json b/services/manso/package.json index de9666f..8b22432 100644 --- a/services/manso/package.json +++ b/services/manso/package.json @@ -18,6 +18,7 @@ "chalk": "^5.6.0", "cors": "^2.8.5", "dotenv": "^17.2.1", + "ejs": "^3.1.10", "express": "^5.1.0", "express-ejs-layouts": "^2.5.1", "pg": "^8.16.3", diff --git a/services/manso/src/index.js b/services/manso/src/index.js index d428d8c..b4fd77c 100644 --- a/services/manso/src/index.js +++ b/services/manso/src/index.js @@ -35,6 +35,18 @@ app.use(express.json()); app.use(express.json({ limit: '1mb' })); app.use(express.static(path.join(__dirname, 'pages'))); + +// ---------------------------------------------------------- +// Motor de vistas EJS +// ---------------------------------------------------------- +app.set("views", path.join(__dirname, "views")); +app.set("view engine", "ejs"); +app.use(expressLayouts); +app.set("layout", "layouts/main"); + +// Archivos estáticos +app.use(express.static(path.join(__dirname, "public"))); + // ---------------------------------------------------------- // Configuración de conexión PostgreSQL // ---------------------------------------------------------- @@ -50,16 +62,6 @@ const dbConfig = { const pool = new Pool(dbConfig); -// Helper de consulta con acquire/release explícito (del código original, referencial) -// async function q(text, params) { -// const client = await pool.connect(); -// try { -// return await client.query(text, params); -// } finally { -// client.release(); -// } -// } - // ---------------------------------------------------------- // Seguridad: Tablas permitidas // ---------------------------------------------------------- @@ -167,13 +169,45 @@ async function pickLabelColumn(client, refTable) { return rows[0]?.column_name || 'id'; } +// ---------------------------------------------------------- +// Middleware para datos globales +// ---------------------------------------------------------- +app.use((req, res, next) => { + res.locals.currentPath = req.path; + res.locals.pageTitle = "SuiteCoffee"; + res.locals.pageId = ""; + next(); +}); + + // ---------------------------------------------------------- // Rutas de UI // ---------------------------------------------------------- -app.get('/', (req, res) => { - res.sendFile(path.join(__dirname, 'pages', 'dashboard.html')); + +app.get("/", (req, res) => { + res.locals.pageTitle = "Inicio"; + res.locals.pageId = "home"; + res.render("estadoComandas"); }); +// app.get('/', (req, res) => { +// res.sendFile(path.join(__dirname, 'pages', 'dashboard.html')); +// }); + +app.get('/comandas', (req, res) => { + res.sendFile(path.join(__dirname, 'pages', 'comandas.html')); +}); + +app.get("/estadoComandas", (req, res) => { + res.locals.pageTitle = "Estado de Comandas"; + res.locals.pageId = "estadoComandas"; + res.render("estadoComandas"); +}); + +// app.get('/estadoComandas', (req, res) => { +// res.sendFile(path.join(__dirname, 'pages', 'estadoComandas.html')); +// }); + // ---------------------------------------------------------- // API // ---------------------------------------------------------- @@ -291,6 +325,85 @@ app.post('/api/table/:table', async (req, res) => { } }); +// Listado (con join) y totales por comanda +app.get('/api/comandas', async (req, res, next) => { + try { + const estado = (req.query.estado || '').trim(); + const limit = Math.min(parseInt(req.query.limit || '200', 10), 1000); + const params = []; + let where = ''; + if (estado) { params.push(estado); where = `WHERE c.estado = $${params.length}`; } + params.push(limit); + + const sql = ` + WITH items AS ( + SELECT d.id_comanda, + COUNT(*) AS items, + SUM(d.cantidad * d.pre_unitario) AS total + FROM deta_comandas d + GROUP BY d.id_comanda + ) + SELECT + c.id_comanda, c.fec_creacion, c.estado, c.observaciones, + u.id_usuario, u.nombre AS usuario_nombre, u.apellido AS usuario_apellido, + m.id_mesa, m.numero AS mesa_numero, m.apodo AS mesa_apodo, + COALESCE(i.items, 0) AS items, + COALESCE(i.total, 0) AS total + FROM comandas c + JOIN usuarios u ON u.id_usuario = c.id_usuario + JOIN mesas m ON m.id_mesa = c.id_mesa + LEFT JOIN items i ON i.id_comanda = c.id_comanda + ${where} + ORDER BY c.id_comanda DESC + LIMIT $${params.length} + `; + const client = await pool.connect(); + try { + const { rows } = await client.query(sql, params); + res.json(rows); + } finally { client.release(); } + } catch (e) { next(e); } +}); + +// Detalle de una comanda (con nombres de productos) +app.get('/api/comandas/:id/detalle', async (req, res, next) => { + try { + const id = parseInt(req.params.id, 10); + if (!id) return res.status(400).json({ error: 'id inválido' }); + + const sql = ` + SELECT d.id_det_comanda, d.id_producto, p.nombre AS producto_nombre, + d.cantidad, d.pre_unitario, (d.cantidad * d.pre_unitario) AS subtotal, + d.observaciones + FROM deta_comandas d + JOIN productos p ON p.id_producto = d.id_producto + WHERE d.id_comanda = $1 + ORDER BY d.id_det_comanda + `; + const { rows } = await pool.query(sql, [id]); + res.json(rows); + } catch (e) { next(e); } +}); + +// Cambiar estado (abrir/cerrar) +app.post('/api/comandas/:id/estado', async (req, res, next) => { + try { + const id = parseInt(req.params.id, 10); + let { estado } = req.body || {}; + if (!id) return res.status(400).json({ error: 'id inválido' }); + + const allowed = new Set(['abierta','cerrada','pagada','anulada']); + if (!allowed.has(estado)) return res.status(400).json({ error: 'estado inválido' }); + + const { rows } = await pool.query( + `UPDATE comandas SET estado = $2 WHERE id_comanda = $1 RETURNING *`, + [id, estado] + ); + if (!rows.length) return res.status(404).json({ error: 'comanda no encontrada' }); + res.json({ updated: rows[0] }); + } catch (e) { next(e); } +}); + // ---------------------------------------------------------- // Verificación de conexión // ---------------------------------------------------------- @@ -310,7 +423,6 @@ async function verificarConexion() { // ---------------------------------------------------------- // Inicio del servidor // ---------------------------------------------------------- -app.use(expressLayouts); const PORT = process.env.PORT ? Number(process.env.PORT) : 3000; app.listen(PORT, () => { diff --git a/services/manso/src/pages/categorias.html b/services/manso/src/pages/categorias.html deleted file mode 100644 index 0a61191..0000000 --- a/services/manso/src/pages/categorias.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - Categorías - - -

Categorías

- -

Crear categoría

-
- - - -
- -

Listado

- - - - -
IDNombreVisible
- - - - diff --git a/services/manso/src/pages/comandas.html b/services/manso/src/pages/comandas.html new file mode 100644 index 0000000..93c6e5d --- /dev/null +++ b/services/manso/src/pages/comandas.html @@ -0,0 +1,355 @@ + + + + + + Comandas + + + +
+

📋 Nueva Comanda

+
+ /api/* +
+ +
+ +
+
+ Productos +
+
+ 0 ítems +
+
+
+ +
+ +
+
+
+ + +
+
Detalles
+
+
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
La fecha se completa automáticamente y los estados/activos usan sus valores por defecto.
+ +
+
Carrito
+
+
Aún no agregaste productos.
+
+ +
+ +
+
+
+
+ + + + diff --git a/services/manso/src/pages/estadoComandas.html.bak b/services/manso/src/pages/estadoComandas.html.bak new file mode 100644 index 0000000..dd69c9a --- /dev/null +++ b/services/manso/src/pages/estadoComandas.html.bak @@ -0,0 +1,280 @@ + + + + + + + Estado de Comandas + + + +
+

🧾 Estado de Comandas

+
+ ➕ Nueva comanda +
+ +
+ +
+
+ Listado +
+ +
+
+
+ + +
+
+
+
+ + +
+
+ Detalle +
+ +
+
+
Selecciona una comanda para ver el detalle.
+
+ +
+
+
+
+
+ + + + diff --git a/services/manso/src/pages/productos.html b/services/manso/src/pages/productos.html deleted file mode 100644 index 82f164f..0000000 --- a/services/manso/src/pages/productos.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - Productos - - -

Productos

- -

Crear producto

-
-
- -
-
- -
-
- -
- -
- -

Listado

- - - - - - -
IDNombrePrecioActivoID Categoría
- - - - diff --git a/services/manso/src/pages/roles.html b/services/manso/src/pages/roles.html deleted file mode 100644 index 4f26d36..0000000 --- a/services/manso/src/pages/roles.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - Roles - - -

Roles

- -

Crear rol

-
- - -
- -

Listado

- - - - -
IDNombre
- - - - diff --git a/services/manso/src/pages/usuarios.html b/services/manso/src/pages/usuarios.html deleted file mode 100644 index 9c6e7b9..0000000 --- a/services/manso/src/pages/usuarios.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - Usuarios - - -

Usuarios

- -

Crear usuario

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
- -
- -

Listado

- - - - - - - - - -
IDDocumentoNombreApellidoCorreoTeléfonoNacimientoActivo
- - - - diff --git a/services/manso/src/views/estadoComanas.ejs b/services/manso/src/views/estadoComanas.ejs new file mode 100644 index 0000000..4cbd3aa --- /dev/null +++ b/services/manso/src/views/estadoComanas.ejs @@ -0,0 +1,18 @@ +
+

Estado de Comandas

+
+ + +
+
+ + + + + + + + + + +
IDMesaEstado
15Abierta
diff --git a/services/manso/src/views/layouts/main.ejs b/services/manso/src/views/layouts/main.ejs new file mode 100644 index 0000000..6e29644 --- /dev/null +++ b/services/manso/src/views/layouts/main.ejs @@ -0,0 +1,16 @@ + + + + <% include ../partials/_head %> + + + <% include ../partials/_navbar %> + +
+ <%- body %> +
+ + <% include ../partials/_sidebar %> + <% include ../partials/_footer %> + + diff --git a/services/manso/src/views/partials/_footer.ejs b/services/manso/src/views/partials/_footer.ejs new file mode 100644 index 0000000..b6c9840 --- /dev/null +++ b/services/manso/src/views/partials/_footer.ejs @@ -0,0 +1,42 @@ + + + + diff --git a/services/manso/src/views/partials/_head.ejs b/services/manso/src/views/partials/_head.ejs new file mode 100644 index 0000000..c449c6d --- /dev/null +++ b/services/manso/src/views/partials/_head.ejs @@ -0,0 +1,22 @@ + + + +<%= typeof pageTitle !== "undefined" ? pageTitle : "SuiteCoffee" %> + + + + diff --git a/services/manso/src/views/partials/_navbar.ejs b/services/manso/src/views/partials/_navbar.ejs new file mode 100644 index 0000000..9d6cdc3 --- /dev/null +++ b/services/manso/src/views/partials/_navbar.ejs @@ -0,0 +1,29 @@ + + diff --git a/services/manso/src/views/partials/_sidebar.ejs b/services/manso/src/views/partials/_sidebar.ejs new file mode 100644 index 0000000..06069af --- /dev/null +++ b/services/manso/src/views/partials/_sidebar.ejs @@ -0,0 +1,62 @@ + +
+
+
Opciones
+ +
+
+ +
+
+
+ +