Files
Autoparts-DB/pos/static/js/app-init.js
consultoria-as 77541e4c52 fix: re-render sidebar when module config loads
- Convert sidebar.js IIFE to window.renderSidebar() so it can be re-rendered
- Call window.renderSidebar(data) from app-init.js after fetching modules
- Ensures sidebar reflects actual tenant module config, not stale localStorage
2026-05-28 00:36:07 +00:00

201 lines
7.1 KiB
JavaScript

/**
* app-init.js — Shared initialization for all POS pages
*
* Handles:
* 1. Auth check (redirect to login if no valid token)
* 2. Set real employee name/role in sidebar and header
* 3. Set navigation links as active based on current page
* 4. Sidebar toggle for mobile
*/
(function() {
'use strict';
// ─── Auth Check ───
var token = localStorage.getItem('pos_token');
if (!token) {
window.location.href = '/pos/login';
return;
}
// Validate token not expired
try {
var payload = JSON.parse(atob(token.split('.')[1]));
if (payload.exp * 1000 < Date.now()) {
localStorage.removeItem('pos_token');
localStorage.removeItem('pos_employee');
window.location.href = '/pos/login';
return;
}
} catch(e) {
localStorage.removeItem('pos_token');
window.location.href = '/pos/login';
return;
}
// ─── Get employee info ───
var employee = {};
try {
employee = JSON.parse(localStorage.getItem('pos_employee') || '{}');
} catch(e) {}
var name = employee.name || payload.name || 'Usuario';
var role = employee.role || payload.role || '';
var _t = typeof window.t === 'function' ? window.t : function(k) { return k; };
var roleLabels = {
'owner': _t('role_owner'), 'admin': _t('role_admin'), 'cashier': _t('role_cashier'),
'warehouse': _t('role_warehouse'), 'accountant': _t('role_accountant')
};
var roleLabel = roleLabels[role] || role;
var initials = name.split(' ').map(function(p) { return p[0]; }).join('').toUpperCase().substring(0, 2);
// ─── Replace hardcoded names in sidebar ───
// Sidebar user name
document.querySelectorAll('.sidebar__user-name').forEach(function(el) {
el.textContent = name;
});
// Sidebar user role
document.querySelectorAll('.sidebar__user-role').forEach(function(el) {
el.textContent = roleLabel;
});
// Sidebar user initials/avatar
document.querySelectorAll('.sidebar__user-avatar, .sidebar__avatar').forEach(function(el) {
el.textContent = initials;
});
// Profile info in headers (catalog uses this pattern)
document.querySelectorAll('.profile-info__name').forEach(function(el) {
el.textContent = name;
});
document.querySelectorAll('.profile-info__role').forEach(function(el) {
el.textContent = roleLabel;
});
// Theme bar user labels
document.querySelectorAll('.theme-bar__label').forEach(function(el) {
if (el.textContent.indexOf('Usuario:') !== -1 || el.textContent.indexOf('Sucursal') !== -1) {
el.textContent = 'Sucursal Principal — ' + name;
}
});
// Status bar user names
document.querySelectorAll('.status-bar .user-name, .status-info span').forEach(function(el) {
var text = el.textContent;
// Replace common demo names
['Hugo M.', 'Hugo García', 'J. Ramírez', 'José Ramírez', 'Carlos M.', 'Admin'].forEach(function(demo) {
if (text.indexOf(demo) !== -1) {
el.textContent = text.replace(demo, name);
}
});
});
// ─── Set active nav link ───
var path = window.location.pathname;
var navMap = {
'/pos/dashboard': 'dashboard',
'/pos/sale': 'pos',
'/pos/catalog': 'catalogo',
'/pos/inventory': 'inventario',
'/pos/customers': 'clientes',
'/pos/invoicing': 'facturacion',
'/pos/accounting': 'contabilidad',
'/pos/reports': 'reportes',
'/pos/config': 'configuracion'
};
document.querySelectorAll('.nav-item, .nav-link').forEach(function(link) {
link.classList.remove('is-active', 'active');
var href = link.getAttribute('href') || '';
if (href === path) {
link.classList.add('is-active');
link.classList.add('active');
}
});
// ─── Logout ───
window.posLogout = function() {
localStorage.removeItem('pos_token');
localStorage.removeItem('pos_employee');
localStorage.removeItem('pos_tenant_id');
localStorage.removeItem('pos_cart');
window.location.href = '/pos/login';
};
// Wire any logout buttons
document.querySelectorAll('[data-action="logout"], .btn-logout, .logout-btn').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.preventDefault();
posLogout();
});
});
// ─── Theme management ───
// Determine theme: saved preference > system preference > default 'industrial'
var savedTheme = localStorage.getItem('pos_theme');
if (!savedTheme) {
// No saved preference — use system color scheme
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
savedTheme = 'industrial';
} else {
savedTheme = 'modern';
}
}
document.documentElement.setAttribute('data-theme', savedTheme);
// Hide all theme bars (they overlap content with position:fixed)
document.querySelectorAll('.theme-bar').forEach(function(bar) {
bar.style.display = 'none';
});
// Expose theme toggle function (global)
window.posSetTheme = function(theme) {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('pos_theme', theme);
};
// Override any page-level setTheme functions so they use our persistent version
window.setTheme = window.posSetTheme;
// Listen for system color scheme changes and auto-switch (only if user hasn't manually set a preference)
if (window.matchMedia) {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
// Only auto-switch if user hasn't explicitly set a preference
var userExplicit = localStorage.getItem('pos_theme');
if (!userExplicit) {
var autoTheme = e.matches ? 'industrial' : 'modern';
document.documentElement.setAttribute('data-theme', autoTheme);
}
});
}
// ─── Expose globally ───
window.POS_USER = {
name: name,
role: role,
roleLabel: roleLabel,
initials: initials,
token: token,
tenantId: payload.tenant_id,
employeeId: payload.employee_id,
branchId: payload.branch_id,
permissions: payload.permissions || []
};
// ─── Preload enabled modules for sidebar filtering ───
try {
fetch('/pos/api/config/modules', {
headers: { 'Authorization': 'Bearer ' + token }
}).then(function(r) {
if (r.ok) return r.json();
}).then(function(data) {
if (data) {
localStorage.setItem('pos_modules', JSON.stringify(data));
window.POS_USER.modules = data;
if (typeof window.renderSidebar === 'function') {
window.renderSidebar(data);
}
}
}).catch(function() {});
} catch(e) {}
})();