correções em todas as telas, precisa revisar a de salvar observação e concluir o atendimento

This commit is contained in:
Eder Moraes 2025-05-30 18:19:03 -03:00
parent 187b385fac
commit 34a4d5a681
8 changed files with 175 additions and 118 deletions

View File

@ -18,12 +18,14 @@
<body> <body>
<div id="list-view"> <div id="list-view">
<h1>Fila</h1> <h1>Fila</h1>
<h3><span id="queue-number" style="color: #3498db;"></span></h3>
<ul id="item-list"> <ul id="item-list">
<!-- Itens serão carregados aqui --> <!-- Itens serão carregados aqui -->
</ul> </ul>
<button id="next-button" disabled>Iniciar atendimento</button> <button id="next-button" disabled>Iniciar atendimento</button>
<button id="sendto-button" disabled>Encaminhar</button> <button id="sendto-button" disabled>Encaminhar</button>
<button id="sair-button">Sair do app</button> <button id="logout-button">Trocar Colaborador</button>
</div> </div>
<div id="obs-view" style="display: none;"> <div id="obs-view" style="display: none;">
@ -80,8 +82,6 @@
selectedItemName = ''; selectedItemName = '';
} }
//[{"id":57,"userToken":"1feb970af7708cb","colabId":null,"colabObs":null,"serviceId":2,"attendanceType":"Normal","clientName":"Augusto teles","whatsappNumber":null,"notificationType":"audio","Favorito":false,"Status":"Fila","inicioAtendimento":null,"fimAtendimento":null,"duracaoAtendimento":null,"obsAtendimento":null,"subServiceId":0,"senhaGen":"AWTT","descricaoServico":"ENTREGA DE DOCUMENTO"}]
// Adiciona os outros itens apenas para visualização (opcional) // Adiciona os outros itens apenas para visualização (opcional)
proximos.slice(1).forEach(item => { proximos.slice(1).forEach(item => {
const li = document.createElement('li'); const li = document.createElement('li');
@ -91,44 +91,6 @@
} }
//não vai ser usado timer pois é usado no floatbuttom, ele atualiza com timer
//essa função vai ser chamada apenas quando algum registro já estiver sido atendido
function updRemoteList() {
if (!token && !colabId) {
console.warn("Token or colabId not found in localStorage. API requests will not be made.");
return; // Stop the function if token or colabId is missing
}
$.ajax(apiUrl + 'get-proximos/'+colabId, {
method: 'GET',
headers: { 'Authorization': 'Bearer '+token },
processData: false,
contentType: false,
dataType: 'JSON',
success: function(response) {
console.log('Resposta:', response);
// Ensure the response is valid JSON before parsing
try {
localStorage.setItem('proximos', JSON.stringify(response));
} catch (e) {
console.error("Error parsing JSON response:", e);
console.error("Response text:", response); // Log the raw response for debugging
}
},
error: function(xhr, status, error) {
console.error('Erro na requisição:', status, error);
console.error('Response Text:', xhr.responseText); // Log the response text for debugging
// Optionally, handle different error codes:
if (xhr.status === 401) {
console.warn("Unauthorized. Token might be invalid.");
// You could redirect the user to a login page here.
} else if (xhr.status === 404) {
console.warn("Resource not found. Check the API endpoint.");
}
}
});
}
setTimeout(()=>{ setTimeout(()=>{
obtemProximosLocalStorage(); obtemProximosLocalStorage();

91
main.js
View File

@ -317,8 +317,6 @@ ipcMain.on('chamar-fila', async () => {
if (mainWin) { if (mainWin) {
if (!mainWin.isVisible()) { if (!mainWin.isVisible()) {
const data = readData();
mainWin.webContents.send('load-data', data); // Envia dados ao mostrar
mainWin.show(); mainWin.show();
mainWin.focus(); mainWin.focus();
} else { } else {
@ -327,38 +325,62 @@ ipcMain.on('chamar-fila', async () => {
} else { } else {
createMainWindow(); // Cria se não existir createMainWindow(); // Cria se não existir
mainWin.webContents.on('did-finish-load', () => { mainWin.webContents.on('did-finish-load', () => {
const data = readData();
mainWin.webContents.send('load-data', data);
mainWin.show(); mainWin.show();
mainWin.focus(); mainWin.focus();
}); });
} }
try{ const colabId = await getSelectedOperatorId();
//chama-fila-app-colab/{colabId} const token = await getAuthToken('token');
const colabId = await getSelectedOperatorId(); const url = apiUrl + 'chama-fila-app-colab/'+colabId; // URL de exemplo para enviar a solicitação
const token = await getAuthToken('token');
const url = apiUrl + 'chama-fila-app-colab/'+colabId; // URL de exemplo para enviar a solicitação const request = net.request({
const request = net.request({ method: 'GET',
method: 'GET', url: url,
url: url, headers: {
headers: { 'Content-Type': 'application/json',
'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token
'Authorization': 'Bearer ' + token }
} });
request.on('response', (response) => {
let rawData = '';
response.on('data', (chunk) => {
rawData += chunk;
}); });
request.on('response', (response) => { response.on('end', () => {
if (response.statusCode === 200) { try {
mainWin.webContents.send('select-atend-id', response.data.id); const parsedData = JSON.parse(rawData);
// window.electronAPI.selectAtendID(response.data.id);
console.log(response.data); if (response.statusCode === 200) {
mainWin.webContents.send('select-atend-id', parsedData.data);
console.log(parsedData);
} else {
console.error(`Erro na requisição: Status code ${response.statusCode}`, parsedData);
// Lidar com o erro adequadamente, talvez enviando uma mensagem para a janela principal
mainWin.webContents.send('api-error', {
message: `Erro ao iniciar atendimento: ${parsedData.message || 'Erro desconhecido'}`
});
}
} catch (error) {
console.error("Erro ao analisar a resposta JSON:", error);
mainWin.webContents.send('api-error', {
message: `Erro ao processar resposta do servidor.`
});
} }
}); });
});
} catch(error){ request.on('error', (error) => {
console.log(error); console.error("Erro na requisição:", error);
} mainWin.webContents.send('api-error', {
message: `Erro ao iniciar atendimento: ${error.message}`
});
});
request.end();
}); });
@ -441,8 +463,20 @@ ipcMain.on('drag-float-window', (event, { offsetX, offsetY }) => {
}); });
*/ */
ipcMain.on('sair', ()=>{
app.exit(); ipcMain.on('logout', ()=>{
mainWin.webContents.executeJavaScript(`
localStorage.removeItem("idOperator");
localStorage.removeItem("selectedOperator");
localStorage.removeItem("salaOperator");
localStorage.removeItem("servicosOperator");
`).then(() => {
// Fecha a janela main e abre a janela de operador e inicia o aplicativo
mainWin.hide();
floatingWin.hide();
createOperatorWindow();
app.isReady();
});
}); });
// Handler para login // Handler para login
@ -651,4 +685,9 @@ ipcMain.on('token-exists', async () => {
createFloatingWindow(); createFloatingWindow();
createMainWindow(); createMainWindow();
} }
});
ipcMain.on('sair', ()=>{
app.exit();
}); });

View File

@ -21,6 +21,7 @@
</div> </div>
<button id="select-button" disabled>Continuar</button> <button id="select-button" disabled>Continuar</button>
<button id="sair-button">Sair do app</button>
</div> </div>
<script src="operator.js"></script> <script src="operator.js"></script>

View File

@ -1,6 +1,7 @@
const operatorSelect = document.getElementById('operator-select'); const operatorSelect = document.getElementById('operator-select');
const selectButton = document.getElementById('select-button'); const selectButton = document.getElementById('select-button');
const errorMessage = document.getElementById('error-message'); const errorMessage = document.getElementById('error-message');
const quitButton = document.getElementById('sair-button');
// Carrega a lista de operadores ao iniciar // Carrega a lista de operadores ao iniciar
window.addEventListener('DOMContentLoaded', async () => { window.addEventListener('DOMContentLoaded', async () => {
@ -78,4 +79,10 @@ window.electronAPI.onOperatorResponse((response) => {
selectButton.textContent = 'Continuar'; selectButton.textContent = 'Continuar';
} }
// Se for bem-sucedido, o processo principal fechará esta janela // Se for bem-sucedido, o processo principal fechará esta janela
});
quitButton.addEventListener('click',()=>{
window.electronAPI.quitApp();
}); });

View File

@ -3,5 +3,6 @@ const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
getOperators: () => ipcRenderer.invoke('get-operators'), getOperators: () => ipcRenderer.invoke('get-operators'),
selectOperator: (operatorName) => ipcRenderer.send('select-operator', operatorName), selectOperator: (operatorName) => ipcRenderer.send('select-operator', operatorName),
onOperatorResponse: (callback) => ipcRenderer.on('operator-response', (_event, response) => callback(response)) onOperatorResponse: (callback) => ipcRenderer.on('operator-response', (_event, response) => callback(response)),
quitApp : () => ipcRenderer.send('sair'),
}); });

View File

@ -2,7 +2,7 @@
"name": "autoatendcolab", "name": "autoatendcolab",
"version": "1.0.0", "version": "1.0.0",
"main": "main.js", "main": "main.js",
"isBuildNow": false, "isBuildNow": true,
"scripts": { "scripts": {
"start": "electron .", "start": "electron .",
"nodemon": "nodemon --exec electron .", "nodemon": "nodemon --exec electron .",

View File

@ -2,9 +2,10 @@ const { app, contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
onLoadData: (callback) => ipcRenderer.on('load-data', (_event, value) => callback(value)), onLoadData: (callback) => ipcRenderer.on('load-data', (_event, value) => callback(value)),
selectAtendID: (callback) => ipcRenderer.on('select-atend-id', (_event, value) => callback(value)), selectAtendID: (callback) => ipcRenderer.on('select-atend-id', (_event, data) => callback(data)),
iniciaAtendimento: (itemId) => ipcRenderer.send('iniciar-atendimento', itemId), iniciaAtendimento: (itemId) => ipcRenderer.send('iniciar-atendimento', itemId),
quitApp : () => ipcRenderer.send('sair'),
logoutApp: () => ipcRenderer.send('logout'),
saveObservation: (data) => ipcRenderer.send('save-observation', data), // data = { itemId, observation } saveObservation: (data) => ipcRenderer.send('save-observation', data), // data = { itemId, observation }
updAvailable: () => ipcRenderer.on('update-available',(event,arg)=>{ updAvailable: () => ipcRenderer.on('update-available',(event,arg)=>{

View File

@ -3,74 +3,79 @@ const observationView = document.getElementById('obs-view');
const encaminharView = document.getElementById('encaminhar-view'); const encaminharView = document.getElementById('encaminhar-view');
const itemList = document.getElementById('item-list'); const itemList = document.getElementById('item-list');
const nextButton = document.getElementById('next-button'); const nextButton = document.getElementById('next-button');
const quitButton = document.getElementById('sair-button'); const logoutButton = document.getElementById('logout-button');
const observationText = document.getElementById('observation-text'); const observationText = document.getElementById('observation-text');
const saveButton = document.getElementById('save-button'); const saveButton = document.getElementById('save-button');
const selectedItemNameSpan = document.getElementById('selected-item-name'); const selectedItemNameSpan = document.getElementById('selected-item-name');
const queueNumber = document.getElementById('queue-number');
let currentData = []; let currentData = [];
let selectedItemId = null; let selectedItemId = null;
let selectedItemName = ''; let selectedItemName = '';
window.electronAPI.onLoadData(() => { // window.electronAPI.onLoadData(() => {
populateList(); // populateList();
// Reseta a view para a lista sempre que os dados são carregados // // Reseta a view para a lista sempre que os dados são carregados
showListView(); // showListView();
// });
//chama o proximo da fila ao abrir a janela de atendimentos
window.electronAPI.selectAtendID((data)=>{
selectedItemId = data.id;
queueNumber.innerHTML = data ? 'Chamando: '+data.senhaGen + ' - '+ data.clientName.toUpperCase() + ' - ' + data.descricaoServico.toUpperCase() : 'Ninguem aguardando atendimento';
}); });
// Função para popular a lista de itens // Função para popular a lista de itens
function populateList() { function populateList() {
// let datastorage = localStorage.getItem('proximos'); let datastorage = localStorage.getItem('proximos');
//
// // Adiciona os outros itens apenas para visualização (opcional) // Adiciona os outros itens apenas para visualização (opcional)
// const proximos = JSON.parse(datastorage); const proximos = JSON.parse(datastorage);
//
// itemList.innerHTML = ''; // Limpa a lista anterior itemList.innerHTML = ''; // Limpa a lista anterior
// if (!proximos || proximos.length === 0) { if (!proximos || proximos.length === 0) {
// itemList.innerHTML = '<li>Nenhum item encontrado.</li>'; itemList.innerHTML = '<li>Nenhum item encontrado.</li>';
// nextButton.disabled = true; nextButton.disabled = true;
// return; return;
// } }
//
// // Seleciona o primeiro item por padrão (ou o próximo disponível) // Seleciona o primeiro item por padrão (ou o próximo disponível)
// // Aqui, vamos apenas pegar o primeiro da lista atual // Aqui, vamos apenas pegar o primeiro da lista atual
// const itemToProcess = proximos[0]; // Pega o primeiro item const itemToProcess = proximos[0]; // Pega o primeiro item
// if (itemToProcess) { if (itemToProcess) {
// selectedItemId = itemToProcess.id; selectedItemId = itemToProcess.id;
// selectedItemName = itemToProcess.clientName; selectedItemName = itemToProcess.clientName;
// const li = document.createElement('li'); const li = document.createElement('li');
// li.textContent = `${itemToProcess.senhaGen}: ${itemToProcess.clientName.toUpperCase()} - ${itemToProcess.attendanceType.toUpperCase()} - ${itemToProcess.descricaoServico.toUpperCase()}`; li.textContent = `${itemToProcess.senhaGen}: ${itemToProcess.clientName.toUpperCase()} - ${itemToProcess.attendanceType.toUpperCase()} - ${itemToProcess.descricaoServico.toUpperCase()}`;
// li.dataset.id = itemToProcess.id; // Armazena o ID no elemento li.dataset.id = itemToProcess.id; // Armazena o ID no elemento
// li.classList.add('selected'); // Marca como selecionado visualmente (precisa de CSS) li.classList.add('selected'); // Marca como selecionado visualmente (precisa de CSS)
// itemList.appendChild(li); itemList.appendChild(li);
// nextButton.disabled = false; nextButton.disabled = false;
// } else { } else {
// itemList.innerHTML = '<li>Nenhum item para processar.</li>'; itemList.innerHTML = '<li>Nenhum item para processar.</li>';
// nextButton.disabled = true; nextButton.disabled = true;
// selectedItemId = null; selectedItemId = null;
// selectedItemName = ''; selectedItemName = '';
// } }
//
// // Adiciona os outros itens apenas para visualização (opcional) // Adiciona os outros itens apenas para visualização (opcional)
// proximos.slice(1).forEach(item => { proximos.slice(1).forEach(item => {
// const li = document.createElement('li'); const li = document.createElement('li');
// li.textContent = `${item.senhaGen}: ${item.clientName.toUpperCase()} - ${item.attendanceType.toUpperCase()} - ${item.descricaoServico.toUpperCase()}`; li.textContent = `${item.senhaGen}: ${item.clientName.toUpperCase()} - ${item.attendanceType.toUpperCase()} - ${item.descricaoServico.toUpperCase()}`;
// itemList.appendChild(li); itemList.appendChild(li);
// }); });
} }
//mostra a tela de listagem e permite iniciar o atendimento //mostra a tela de listagem e permite iniciar o atendimento
function showListView() { function showListView() {
populateList(); // populateList();
listView.style.display = 'block'; listView.style.display = 'block';
encaminharView.style.display = 'none'; encaminharView.style.display = 'none';
observationView.style.display = 'none'; observationView.style.display = 'none';
observationText.value = ''; // Limpa a textarea observationText.value = ''; // Limpa a textarea
window.electronAPI.currVersion(()=>{});
// nextButton.disabled = !selectedItemId; // Habilita/desabilita baseado na seleção // nextButton.disabled = !selectedItemId; // Habilita/desabilita baseado na seleção
} }
@ -99,8 +104,8 @@ nextButton.addEventListener('click', () => {
quitButton.addEventListener('click',()=>{ logoutButton.addEventListener('click',()=>{
window.electronAPI.quitApp(); window.electronAPI.logoutApp();
}); });
// //
@ -116,3 +121,44 @@ quitButton.addEventListener('click',()=>{
// }); // });
// Inicialmente, mostra a view da lista (estará vazia até receber dados) // Inicialmente, mostra a view da lista (estará vazia até receber dados)
//não vai ser usado timer pois é usado no floatbuttom, ele atualiza com timer
//essa função vai ser chamada apenas quando algum registro já estiver sido atendido
function updRemoteList() {
if (!token && !colabId) {
console.warn("Token or colabId not found in localStorage. API requests will not be made.");
return; // Stop the function if token or colabId is missing
}
$.ajax(apiUrl + 'get-proximos/'+colabId, {
method: 'GET',
headers: { 'Authorization': 'Bearer '+token },
processData: false,
contentType: false,
dataType: 'JSON',
success: function(response) {
console.log('Resposta:', response);
// Ensure the response is valid JSON before parsing
try {
localStorage.setItem('proximos', JSON.stringify(response));
} catch (e) {
console.error("Error parsing JSON response:", e);
console.error("Response text:", response); // Log the raw response for debugging
}
},
error: function(xhr, status, error) {
console.error('Erro na requisição:', status, error);
console.error('Response Text:', xhr.responseText); // Log the response text for debugging
// Optionally, handle different error codes:
if (xhr.status === 401) {
console.warn("Unauthorized. Token might be invalid.");
// You could redirect the user to a login page here.
} else if (xhr.status === 404) {
console.warn("Resource not found. Check the API endpoint.");
}
}
});
}