mirror of
https://github.com/marcogll/ap_pos.git
synced 2026-01-13 21:25: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 });
|
||||
|
||||
// Volver a cargar los clientes desde el servidor para asegurar consistencia
|
||||
clients = await load(KEY_CLIENTS, []);
|
||||
// Optimización: en lugar de recargar, actualizamos el estado local.
|
||||
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();
|
||||
updateClientDatalist();
|
||||
@@ -785,7 +790,7 @@ async function initializeApp() {
|
||||
|
||||
tipoServicioSelect?.addEventListener('change', (e) => {
|
||||
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));
|
||||
});
|
||||
|
||||
@@ -825,4 +830,3 @@ async function initializeApp() {
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initializeApp);
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
<option value="Microblading">Microblading</option>
|
||||
<option value="Lashes">Lashes</option>
|
||||
<option value="Nail Art">Nail Art</option>
|
||||
<option value="Lash Lifting">Lash Lifting</option>
|
||||
<option value="Pago">Pago</option>
|
||||
</select>
|
||||
<div id="m-subtipo-container" class="hidden">
|
||||
|
||||
@@ -82,7 +82,7 @@ function templateTicket(mov, settings) {
|
||||
* @param {object} mov El objeto del movimiento.
|
||||
* @param {object} settings El objeto de configuración.
|
||||
*/
|
||||
export function renderTicketAndPrint(mov, settings) {
|
||||
export async function renderTicketAndPrint(mov, settings) {
|
||||
const printArea = document.getElementById('printArea');
|
||||
if (!printArea) {
|
||||
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');
|
||||
if (!canvas) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 3. Generar el código QR
|
||||
const qrUrl = 'http://vanityexperience.mx/qr';
|
||||
QRCode.toCanvas(canvas, qrUrl, { width: 140, margin: 1 }, function (error) {
|
||||
if (error) {
|
||||
console.error('Error al generar el código QR:', error);
|
||||
// Ocultar el canvas si hay error y proceder a imprimir
|
||||
canvas.style.display = 'none';
|
||||
}
|
||||
|
||||
// 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);
|
||||
});
|
||||
await QRCode.toCanvas(canvas, qrUrl, { width: 140, margin: 1 });
|
||||
|
||||
// 4. Llamar a la impresión.
|
||||
// El `await` anterior asegura que el QR ya está renderizado.
|
||||
// Un pequeño timeout puede seguir siendo útil para asegurar que el navegador "pinte" el canvas en la pantalla.
|
||||
requestAnimationFrame(() => window.print());
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error al intentar imprimir:", error);
|
||||
|
||||
@@ -14,12 +14,16 @@ app.use(cors());
|
||||
app.use(express.json());
|
||||
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
|
||||
app.use(session({
|
||||
secret: 'your-very-secret-key-change-it', // Cambia esto por una clave secreta real
|
||||
secret: SESSION_SECRET,
|
||||
resave: 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 ---
|
||||
|
||||
Reference in New Issue
Block a user