mirror of
https://github.com/marcogll/ap_pos.git
synced 2026-01-13 13:15:16 +00:00
Updated ReadMe
This commit is contained in:
7
ap-pos/README.md
Normal file
7
ap-pos/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# AP-POS WebApp
|
||||
|
||||
Este es un sistema de punto de venta simple basado en la web.
|
||||
|
||||
## Futuras Implementaciones
|
||||
|
||||
Se tiene la intención de que esta aplicación se pueda ejecutar en un contenedor de Docker. Además, se buscará que la aplicación tenga la capacidad de interactuar con una impresora de tickets conectada vía USB en un entorno de macOS.
|
||||
@@ -29,6 +29,7 @@ const btnTestTicket = document.getElementById('btnTestTicket');
|
||||
const formClient = document.getElementById('formClient');
|
||||
const tblClientsBody = document.getElementById('tblClients')?.querySelector('tbody');
|
||||
const clientDatalist = document.getElementById('client-list');
|
||||
const formCredentials = document.getElementById('formCredentials');
|
||||
|
||||
// --- LÓGICA DE NEGOCIO ---
|
||||
|
||||
@@ -61,9 +62,9 @@ async function loadDashboardData() {
|
||||
};
|
||||
|
||||
if (incomeChart) {
|
||||
incomeChart.data = chartData;
|
||||
incomeChart.update();
|
||||
} else {
|
||||
incomeChart.destroy();
|
||||
}
|
||||
|
||||
incomeChart = new Chart(ctx, {
|
||||
type: 'pie',
|
||||
data: chartData,
|
||||
@@ -72,7 +73,6 @@ async function loadDashboardData() {
|
||||
maintainAspectRatio: false,
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading dashboard:', error);
|
||||
}
|
||||
@@ -254,6 +254,35 @@ async function handleSaveSettings(e) {
|
||||
alert('Configuración guardada.');
|
||||
}
|
||||
|
||||
async function handleSaveCredentials(e) {
|
||||
e.preventDefault();
|
||||
const username = document.getElementById('s-username').value;
|
||||
const password = document.getElementById('s-password').value;
|
||||
|
||||
const body = { username };
|
||||
if (password) {
|
||||
body.password = password;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/user', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert('Credenciales actualizadas.');
|
||||
document.getElementById('s-password').value = '';
|
||||
} else {
|
||||
const error = await response.json();
|
||||
alert(`Error: ${error.error}`);
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Error de conexión al guardar credenciales.');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleNewMovement(e) {
|
||||
e.preventDefault();
|
||||
const form = e.target;
|
||||
@@ -393,6 +422,7 @@ async function initializeApp() {
|
||||
const btnLogout = document.getElementById('btnLogout');
|
||||
|
||||
formSettings?.addEventListener('submit', handleSaveSettings);
|
||||
formCredentials?.addEventListener('submit', handleSaveCredentials);
|
||||
formMove?.addEventListener('submit', handleNewMovement);
|
||||
tblMovesBody?.addEventListener('click', handleTableClick);
|
||||
tblClientsBody?.addEventListener('click', handleTableClick);
|
||||
@@ -414,13 +444,17 @@ async function initializeApp() {
|
||||
Promise.all([
|
||||
load(KEY_SETTINGS, DEFAULT_SETTINGS),
|
||||
load(KEY_DATA, []),
|
||||
load(KEY_CLIENTS, [])
|
||||
load(KEY_CLIENTS, []),
|
||||
fetch('/api/user').then(res => res.json())
|
||||
]).then(values => {
|
||||
[settings, movements, clients] = values;
|
||||
[settings, movements, clients, user] = values;
|
||||
renderSettings();
|
||||
renderTable();
|
||||
renderClientsTable();
|
||||
updateClientDatalist();
|
||||
if (user) {
|
||||
document.getElementById('s-username').value = user.username;
|
||||
}
|
||||
// Cargar datos del dashboard al inicio
|
||||
loadDashboardData();
|
||||
}).catch(error => {
|
||||
|
||||
@@ -178,6 +178,20 @@
|
||||
Toda la información de tu negocio (clientes, recibos y configuración) se guarda de forma segura en el archivo <strong>ap-pos.db</strong>, ubicado en la misma carpeta que la aplicación. Para hacer un respaldo, simplemente copia este archivo.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2>Credenciales de Acceso</h2>
|
||||
<form id="formCredentials">
|
||||
<div class="form-grid">
|
||||
<label>Usuario:</label>
|
||||
<input type="text" id="s-username" required />
|
||||
<label>Nueva Contraseña:</label>
|
||||
<input type="password" id="s-password" placeholder="Dejar en blanco para no cambiar" />
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit">Guardar Credenciales</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -233,6 +233,47 @@ apiRouter.delete('/movements/:id', (req, res) => {
|
||||
// Registrar el router de la API protegida
|
||||
app.use('/api', apiRouter);
|
||||
|
||||
// --- User Management ---
|
||||
apiRouter.get('/user', (req, res) => {
|
||||
db.get("SELECT id, username FROM users WHERE id = ?", [req.session.userId], (err, row) => {
|
||||
if (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
return;
|
||||
}
|
||||
res.json(row);
|
||||
});
|
||||
});
|
||||
|
||||
apiRouter.post('/user', (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
if (!username) {
|
||||
return res.status(400).json({ error: 'Username is required' });
|
||||
}
|
||||
|
||||
if (password) {
|
||||
// Si se proporciona una nueva contraseña, hashearla y actualizar todo
|
||||
bcrypt.hash(password, SALT_ROUNDS, (err, hash) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: 'Error hashing password' });
|
||||
}
|
||||
db.run('UPDATE users SET username = ?, password = ? WHERE id = ?', [username, hash, req.session.userId], function(err) {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
res.json({ message: 'User credentials updated successfully' });
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Si no se proporciona contraseña, solo actualizar el nombre de usuario
|
||||
db.run('UPDATE users SET username = ? WHERE id = ?', [username, req.session.userId], function(err) {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: err.message });
|
||||
}
|
||||
res.json({ message: 'Username updated successfully' });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// --- Dashboard Route ---
|
||||
apiRouter.get('/dashboard', (req, res) => {
|
||||
const queries = {
|
||||
|
||||
Reference in New Issue
Block a user