diff --git a/ap-pos/app.js b/ap-pos/app.js
index f2c997d..5b6eba2 100644
--- a/ap-pos/app.js
+++ b/ap-pos/app.js
@@ -234,9 +234,11 @@ function renderUsersTable() {
users.forEach(u => {
const tr = document.createElement('tr');
tr.innerHTML = `
+
${u.name} |
${u.username} |
${u.role === 'admin' ? 'Administrador' : 'Usuario'} |
+
${u.id !== currentUser.id ? `` : ''}
|
`;
@@ -276,10 +278,11 @@ async function handleSaveSettings(e) {
async function handleSaveCredentials(e) {
e.preventDefault();
+ const name = document.getElementById('s-name').value;
const username = document.getElementById('s-username').value;
const password = document.getElementById('s-password').value;
- const body = { username };
+ const body = { username, name };
if (password) {
body.password = password;
}
@@ -293,6 +296,8 @@ async function handleSaveCredentials(e) {
if (response.ok) {
alert('Credenciales actualizadas.');
+ currentUser.name = name; // Actualizar el nombre en el estado local
+ currentUser.username = username;
document.getElementById('s-password').value = '';
} else {
const error = await response.json();
@@ -303,31 +308,54 @@ async function handleSaveCredentials(e) {
}
}
-async function handleAddUser(e) {
+async function handleAddOrUpdateUser(e) {
e.preventDefault();
+ const id = document.getElementById('u-id').value;
+ const name = document.getElementById('u-name').value;
const username = document.getElementById('u-username').value;
const password = document.getElementById('u-password').value;
const role = document.getElementById('u-role').value;
+ const isUpdate = !!id;
+ const url = isUpdate ? `/api/users/${id}` : '/api/users';
+ const method = isUpdate ? 'PUT' : 'POST';
+
+ const body = { name, username, role };
+ if (password || !isUpdate) {
+ if (!password && !isUpdate) {
+ alert('La contraseña es obligatoria para nuevos usuarios.');
+ return;
+ }
+ body.password = password;
+ }
+
try {
- const response = await fetch('/api/users', {
- method: 'POST',
+ const response = await fetch(url, {
+ method: method,
headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ username, password, role })
+ body: JSON.stringify(body)
});
- const newUser = await response.json();
+ const result = await response.json();
if (response.ok) {
- alert('Usuario creado exitosamente.');
- users.push(newUser);
+ alert(`Usuario ${isUpdate ? 'actualizado' : 'creado'} exitosamente.`);
+ if (isUpdate) {
+ const index = users.findIndex(u => u.id === parseInt(id));
+ if (index > -1) {
+ users[index] = { ...users[index], name, username, role };
+ }
+ } else {
+ users.push(result);
+ }
renderUsersTable();
formAddUser.reset();
+ document.getElementById('u-id').value = '';
} else {
- alert(`Error: ${newUser.error}`);
+ alert(`Error: ${result.error}`);
}
} catch (error) {
- alert('Error de conexión al crear usuario.');
+ alert('Error de conexión al guardar el usuario.');
}
}
@@ -381,7 +409,7 @@ async function handleNewMovement(e) {
monto: Number(monto.toFixed(2)),
metodo: document.getElementById('m-metodo').value,
concepto: document.getElementById('m-concepto').value,
- staff: document.getElementById('m-staff').value,
+ staff: currentUser.name, // Usar el nombre del usuario actual
notas: document.getElementById('m-notas').value,
fechaCita: document.getElementById('m-fecha-cita').value,
horaCita: document.getElementById('m-hora-cita').value,
@@ -424,6 +452,16 @@ function handleTableClick(e) {
deleteClient(id);
}
}
+ } else if (action === 'edit-user') {
+ const user = users.find(u => u.id === parseInt(id));
+ if (user) {
+ document.getElementById('u-id').value = user.id;
+ document.getElementById('u-name').value = user.name;
+ document.getElementById('u-username').value = user.username;
+ document.getElementById('u-role').value = user.role;
+ document.getElementById('u-password').value = ''; // Limpiar campo de contraseña
+ document.getElementById('u-password').placeholder = 'Dejar en blanco para no cambiar';
+ }
} else if (action === 'delete-user') {
deleteUser(parseInt(id, 10));
}
@@ -508,6 +546,7 @@ function setupUIForRole(role) {
const dashboardTab = document.querySelector('[data-tab="tab-dashboard"]');
const settingsTab = document.querySelector('[data-tab="tab-settings"]');
const userManagementSection = document.getElementById('user-management-section');
+ const staffInput = document.getElementById('m-staff');
if (role === 'admin') {
// El admin puede ver todo
@@ -526,6 +565,11 @@ function setupUIForRole(role) {
settingsTab.style.display = 'none';
userManagementSection.style.display = 'none';
}
+
+ // Deshabilitar el campo "Atendió" para todos, ya que se autocompleta
+ if (staffInput) {
+ staffInput.disabled = true;
+ }
}
@@ -563,6 +607,7 @@ async function initializeApp() {
// 3. Añadir manejadores de eventos.
const tabs = document.querySelector('.tabs');
const btnLogout = document.getElementById('btnLogout');
+ const btnCancelEditUser = document.getElementById('btnCancelEditUser');
formSettings?.addEventListener('submit', handleSaveSettings);
formCredentials?.addEventListener('submit', handleSaveCredentials);
@@ -575,7 +620,7 @@ async function initializeApp() {
tabs?.addEventListener('click', handleTabChange);
if (currentUser.role === 'admin') {
- formAddUser?.addEventListener('submit', handleAddUser);
+ formAddUser?.addEventListener('submit', handleAddOrUpdateUser);
tblUsersBody?.addEventListener('click', handleTableClick);
}
@@ -589,6 +634,13 @@ async function initializeApp() {
document.getElementById('c-id').value = '';
});
+ btnCancelEditUser?.addEventListener('click', (e) => {
+ e.preventDefault();
+ formAddUser.reset();
+ document.getElementById('u-id').value = '';
+ document.getElementById('u-password').placeholder = 'Contraseña';
+ });
+
// 4. Cargar el resto de los datos de la aplicación.
Promise.all([
load(KEY_SETTINGS, DEFAULT_SETTINGS),
@@ -603,7 +655,9 @@ async function initializeApp() {
updateClientDatalist();
if (currentUser) {
+ document.getElementById('s-name').value = currentUser.name || '';
document.getElementById('s-username').value = currentUser.username;
+ document.getElementById('m-staff').value = currentUser.name || '';
}
// 5. Configurar la UI y activar la pestaña inicial correcta.
diff --git a/ap-pos/index.html b/ap-pos/index.html
index 60b31c1..7bdab94 100644
--- a/ap-pos/index.html
+++ b/ap-pos/index.html
@@ -183,6 +183,8 @@
Mis Credenciales