mirror of
https://github.com/marcogll/ap_pos.git
synced 2026-01-13 13:15:16 +00:00
Actualiza app POS: index, server, print y lockfile
This commit is contained in:
@@ -162,8 +162,13 @@ async function saveClient(clientData) {
|
|||||||
|
|
||||||
await save('clients', { client: clientToSave });
|
await save('clients', { client: clientToSave });
|
||||||
|
|
||||||
// Volver a cargar los clientes desde el servidor para asegurar consistencia
|
// Optimización: en lugar de recargar, actualizamos el estado local.
|
||||||
clients = await load(KEY_CLIENTS, []);
|
if (isUpdate) {
|
||||||
|
const index = clients.findIndex(c => c.id === clientToSave.id);
|
||||||
|
if (index > -1) clients[index] = clientToSave;
|
||||||
|
} else {
|
||||||
|
clients.unshift(clientToSave); // Añadir al principio para que aparezca primero
|
||||||
|
}
|
||||||
|
|
||||||
renderClientsTable();
|
renderClientsTable();
|
||||||
updateClientDatalist();
|
updateClientDatalist();
|
||||||
@@ -785,7 +790,7 @@ async function initializeApp() {
|
|||||||
|
|
||||||
tipoServicioSelect?.addEventListener('change', (e) => {
|
tipoServicioSelect?.addEventListener('change', (e) => {
|
||||||
const subtipoContainer = document.getElementById('m-subtipo-container');
|
const subtipoContainer = document.getElementById('m-subtipo-container');
|
||||||
const servicesWithSubtype = ['Microblading', 'Lashes', 'Nail Art'];
|
const servicesWithSubtype = ['Microblading', 'Lashes', 'Nail Art', 'Lash Lifting'];
|
||||||
subtipoContainer.classList.toggle('hidden', !servicesWithSubtype.includes(e.target.value));
|
subtipoContainer.classList.toggle('hidden', !servicesWithSubtype.includes(e.target.value));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -825,4 +830,3 @@ async function initializeApp() {
|
|||||||
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', initializeApp);
|
document.addEventListener('DOMContentLoaded', initializeApp);
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,7 @@
|
|||||||
<option value="Microblading">Microblading</option>
|
<option value="Microblading">Microblading</option>
|
||||||
<option value="Lashes">Lashes</option>
|
<option value="Lashes">Lashes</option>
|
||||||
<option value="Nail Art">Nail Art</option>
|
<option value="Nail Art">Nail Art</option>
|
||||||
|
<option value="Lash Lifting">Lash Lifting</option>
|
||||||
<option value="Pago">Pago</option>
|
<option value="Pago">Pago</option>
|
||||||
</select>
|
</select>
|
||||||
<div id="m-subtipo-container" class="hidden">
|
<div id="m-subtipo-container" class="hidden">
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ function templateTicket(mov, settings) {
|
|||||||
* @param {object} mov El objeto del movimiento.
|
* @param {object} mov El objeto del movimiento.
|
||||||
* @param {object} settings El objeto de configuración.
|
* @param {object} settings El objeto de configuración.
|
||||||
*/
|
*/
|
||||||
export function renderTicketAndPrint(mov, settings) {
|
export async function renderTicketAndPrint(mov, settings) {
|
||||||
const printArea = document.getElementById('printArea');
|
const printArea = document.getElementById('printArea');
|
||||||
if (!printArea) {
|
if (!printArea) {
|
||||||
console.error("El área de impresión #printArea no se encontró.");
|
console.error("El área de impresión #printArea no se encontró.");
|
||||||
@@ -98,25 +98,18 @@ export function renderTicketAndPrint(mov, settings) {
|
|||||||
const canvas = document.getElementById('qr-canvas');
|
const canvas = document.getElementById('qr-canvas');
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
console.error("El canvas del QR #qr-canvas no se encontró. Se imprimirá sin QR.");
|
console.error("El canvas del QR #qr-canvas no se encontró. Se imprimirá sin QR.");
|
||||||
setTimeout(() => window.print(), 100); // Imprimir sin QR
|
window.print(); // Imprimir sin QR de inmediato
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Generar el código QR
|
// 3. Generar el código QR
|
||||||
const qrUrl = 'http://vanityexperience.mx/qr';
|
const qrUrl = 'http://vanityexperience.mx/qr';
|
||||||
QRCode.toCanvas(canvas, qrUrl, { width: 140, margin: 1 }, function (error) {
|
await QRCode.toCanvas(canvas, qrUrl, { width: 140, margin: 1 });
|
||||||
if (error) {
|
|
||||||
console.error('Error al generar el código QR:', error);
|
// 4. Llamar a la impresión.
|
||||||
// Ocultar el canvas si hay error y proceder a imprimir
|
// El `await` anterior asegura que el QR ya está renderizado.
|
||||||
canvas.style.display = 'none';
|
// Un pequeño timeout puede seguir siendo útil para asegurar que el navegador "pinte" el canvas en la pantalla.
|
||||||
}
|
requestAnimationFrame(() => window.print());
|
||||||
|
|
||||||
// 4. Llamar a la impresión después de un breve timeout
|
|
||||||
// Esto asegura que el navegador haya tenido tiempo de renderizar el QR
|
|
||||||
setTimeout(() => {
|
|
||||||
window.print();
|
|
||||||
}, 150);
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error al intentar imprimir:", error);
|
console.error("Error al intentar imprimir:", error);
|
||||||
|
|||||||
@@ -14,12 +14,16 @@ app.use(cors());
|
|||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(express.static(__dirname)); // Servir archivos estáticos como CSS, JS, etc.
|
app.use(express.static(__dirname)); // Servir archivos estáticos como CSS, JS, etc.
|
||||||
|
|
||||||
|
// Cargar una clave secreta desde variables de entorno o usar una por defecto (solo para desarrollo)
|
||||||
|
const SESSION_SECRET = process.env.SESSION_SECRET || 'your-very-secret-key-change-it';
|
||||||
|
const IN_PROD = process.env.NODE_ENV === 'production';
|
||||||
|
|
||||||
// Session Middleware
|
// Session Middleware
|
||||||
app.use(session({
|
app.use(session({
|
||||||
secret: 'your-very-secret-key-change-it', // Cambia esto por una clave secreta real
|
secret: SESSION_SECRET,
|
||||||
resave: false,
|
resave: false,
|
||||||
saveUninitialized: false,
|
saveUninitialized: false,
|
||||||
cookie: { secure: false, httpOnly: true, maxAge: 24 * 60 * 60 * 1000 } // `secure: true` en producción con HTTPS
|
cookie: { secure: IN_PROD, httpOnly: true, maxAge: 24 * 60 * 60 * 1000 } // `secure: true` en producción con HTTPS
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// --- DATABASE INITIALIZATION ---
|
// --- DATABASE INITIALIZATION ---
|
||||||
|
|||||||
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "ap_pos",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user