Replace 5 POS templates with updated design system pages using tokens.css. Add routes for dashboard, config, and reports pages. Create stub JS files for dashboard, config, and reports modules. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
140 lines
4.5 KiB
JavaScript
140 lines
4.5 KiB
JavaScript
// /home/Autopartes/pos/static/js/config.js
|
|
// Config module: branches, employees, theme, system settings
|
|
|
|
const Config = (() => {
|
|
const API = '/pos/api/config';
|
|
|
|
function token() {
|
|
return localStorage.getItem('pos_token') || '';
|
|
}
|
|
|
|
function checkAuth() {
|
|
if (!token()) {
|
|
window.location.href = '/pos/login';
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function headers() {
|
|
return { 'Authorization': `Bearer ${token()}`, 'Content-Type': 'application/json' };
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Theme switcher
|
|
// -------------------------------------------------------------------------
|
|
function setTheme(theme) {
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
try { localStorage.setItem('nexus-theme', theme); } catch(e) {}
|
|
|
|
document.querySelectorAll('.theme-btn').forEach(function(btn) {
|
|
btn.classList.toggle('is-active', btn.dataset.themeTarget === theme);
|
|
});
|
|
|
|
document.querySelectorAll('.theme-option').forEach(function(opt) {
|
|
opt.classList.remove('is-selected');
|
|
});
|
|
var idx = theme === 'industrial' ? 0 : 1;
|
|
var opts = document.querySelectorAll('.theme-option');
|
|
if (opts[idx]) opts[idx].classList.add('is-selected');
|
|
}
|
|
window.setTheme = setTheme;
|
|
|
|
function selectThemeOption(theme) {
|
|
setTheme(theme);
|
|
}
|
|
window.selectThemeOption = selectThemeOption;
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Live clock
|
|
// -------------------------------------------------------------------------
|
|
function updateClock() {
|
|
var now = new Date();
|
|
var hh = String(now.getHours()).padStart(2, '0');
|
|
var mm = String(now.getMinutes()).padStart(2, '0');
|
|
var el = document.getElementById('live-clock');
|
|
if (el) el.textContent = hh + ':' + mm;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// API calls using existing config_bp endpoints
|
|
// -------------------------------------------------------------------------
|
|
async function loadBranches() {
|
|
try {
|
|
const res = await fetch(`${API}/branches`, { headers: headers() });
|
|
if (!res.ok) throw new Error('Failed to load branches');
|
|
return await res.json();
|
|
} catch (e) {
|
|
console.error('Config.loadBranches:', e);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async function loadEmployees() {
|
|
try {
|
|
const res = await fetch(`${API}/employees`, { headers: headers() });
|
|
if (!res.ok) throw new Error('Failed to load employees');
|
|
return await res.json();
|
|
} catch (e) {
|
|
console.error('Config.loadEmployees:', e);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async function saveBranch(data) {
|
|
const res = await fetch(`${API}/branches`, {
|
|
method: 'POST',
|
|
headers: headers(),
|
|
body: JSON.stringify(data)
|
|
});
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
throw new Error(err.error || 'Save failed');
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
async function saveEmployee(data) {
|
|
const res = await fetch(`${API}/employees`, {
|
|
method: 'POST',
|
|
headers: headers(),
|
|
body: JSON.stringify(data)
|
|
});
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
throw new Error(err.error || 'Save failed');
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Init
|
|
// -------------------------------------------------------------------------
|
|
function init() {
|
|
if (!checkAuth()) return;
|
|
|
|
// Restore theme
|
|
try {
|
|
var saved = localStorage.getItem('nexus-theme');
|
|
if (saved === 'industrial' || saved === 'modern') {
|
|
setTheme(saved);
|
|
}
|
|
} catch(e) {}
|
|
|
|
// Start clock
|
|
updateClock();
|
|
setInterval(updateClock, 30000);
|
|
|
|
// Load initial data
|
|
loadBranches();
|
|
loadEmployees();
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
|
|
return {
|
|
init, setTheme, selectThemeOption,
|
|
loadBranches, loadEmployees, saveBranch, saveEmployee
|
|
};
|
|
})();
|