From 063e336b80ce2798420ae7f0f828ba8e3b4cd3e1 Mon Sep 17 00:00:00 2001 From: Eder Moraes <54563944+edermcastro@users.noreply.github.com> Date: Sun, 1 Jun 2025 02:02:47 -0300 Subject: [PATCH] =?UTF-8?q?adicionado=20funcionalidade=20pra=20salvar=20as?= =?UTF-8?q?=20observa=C3=A7=C3=B5es,=20algumas=20altera=C3=A7=C3=B5es=20no?= =?UTF-8?q?=20estilo=20de=20alguns=20elementos=20foram=20acrescentados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 4 ++-- main.js | 62 +++++++++++++++++++++++++++++++++++++++++++---------- renderer.js | 38 ++++++++++++++++---------------- 3 files changed, 73 insertions(+), 31 deletions(-) diff --git a/index.html b/index.html index 7cf0533..9421d1e 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - Aguardando atendimento + Tela de Atendimento @@ -31,7 +31,7 @@ diff --git a/main.js b/main.js index bfcdbf6..9b35ce0 100644 --- a/main.js +++ b/main.js @@ -49,7 +49,11 @@ async function readData() { // Função para buscar dados da API async function fetchDataFromAPI() { //executa uma vez e a cada 30 segundos - getAndUpdateDataStorage(); setInterval(()=>{ + + //TODO propicio para fazer um webhook nessas funções que repetem a chamada de requisições em busca de alterações + getAndUpdateDataStorage(); + + const timer = setInterval(()=>{ getAndUpdateDataStorage(); },30000); } @@ -235,7 +239,7 @@ function createFloatingWindow() { height: winHeight, icon: "icon.ico", x: screenWidth - winWidth + 0, - y: screenHeight - winHeight - 60, + y: screenHeight - winHeight - 180, frame: false, transparent: true, alwaysOnTop: true, @@ -517,8 +521,10 @@ ipcMain.on('select-atend-id',(itemId)=>{ }); // Ouvir clique no botão "Iniciar atendimento" -ipcMain.on('iniciar-atendimento', (event, itemId) => { +ipcMain.on('iniciar-atendimento', async (event, itemId) => { + const token = await getAuthToken(); + const colabId = await floatingWin.webContents.executeJavaScript("localStorage.getItem('idOperator')") //TODO inicia o atendimento o id do atendimento deve ser requisitado do backend const url = apiUrl + 'iniciar-atendimento/'+itemId; // URL de exemplo para enviar a solicitação @@ -529,7 +535,7 @@ ipcMain.on('iniciar-atendimento', (event, itemId) => { url: url, headers: { 'Content-Type': 'application/json', - 'Authorization': 'Bearer ' + localStorage.getItem('token') + 'Authorization': 'Bearer ' + token } }); @@ -559,19 +565,53 @@ ipcMain.on('iniciar-atendimento', (event, itemId) => { }); // Ouvir clique no botão "Salvar" -ipcMain.on('save-observation', (event, { itemId, observation }) => { +ipcMain.on('save-observation', async (event, { itemId, observation }) => { //TODO salva a observação e finaliza o atendimento console.log(`Salvando observação para item ${itemId}: ${observation}`); - console.log("Observação 'salva' (apenas log por enquanto)."); + const token = await getAuthToken(); + const colabId = await floatingWin.webContents.executeJavaScript("localStorage.getItem('idOperator')") + //TODO inicia o atendimento o id do atendimento deve ser requisitado do backend + + const url = apiUrl + 'finalizar-atendimento/'+itemId; // URL de exemplo para enviar a solicitação + + const fmData = JSON.stringify({ + "colabId": colabId, + "obsAtendimento": observation + }); + + + // Simula o envio de uma solicitação POST com o ID do item + const request = net.request({ + method: 'POST', + url: url, + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + token + } + }); + + request.on('response', (response) => { + response.on('data', (chunk) => { + console.log(`BODY: ${chunk}`); + }); + response.on('end', () => { + console.log('Solicitação concluída.'); + // Avisa a janela principal que a solicitação foi feita (opcional) + // mainWin.webContents.send('request-done', itemId); + }); + }); + request.on('error', (error) => { + console.error(`Erro na solicitação: ${error}`); + // Poderia notificar a UI sobre o erro + }); + + // Envia o ID como corpo da requisição (exemplo) + request.write(fmData); + request.end(); - // Opcional: Ler dados novamente e atualizar contagem na janela flutuante - // const data = readData(); - // if (floatingWin) { - // floatingWin.webContents.send('update-count', data.length); - // } // Opcional: Fechar ou resetar a janela principal após salvar if (mainWin) { diff --git a/renderer.js b/renderer.js index e470e0b..b2bb1d9 100644 --- a/renderer.js +++ b/renderer.js @@ -5,6 +5,7 @@ const itemList = document.getElementById('item-list'); const nextButton = document.getElementById('next-button'); const logoutButton = document.getElementById('logout-button'); const observationText = document.getElementById('observation-text'); +const encObservationText = document.getElementById('enc-observation-text'); const saveButton = document.getElementById('save-button'); const selectedItemNameSpan = document.getElementById('selected-item-name'); const queueNumber = document.getElementById('queue-number'); @@ -26,15 +27,19 @@ window.electronAPI.onLoadData((data) => { //chama o proximo da fila ao abrir a janela de atendimentos window.electronAPI.selectAtendID((data)=>{ if(!data){ - queueNumber.innerHTML = 'Ninguem aguardando atendimento'; - window.close(); + queueNumber.innerHTML = 'Ninguem aguardando atendimento, fechando a janela em alguns segundos...'; + setTimeout(() => { + window.close(); + },5000); return; } // Reseta a view para a lista sempre que os dados são carregados ao clicar no botão para abrir a janela populateList(data); showListView(); selectedItemId = data.id ?? null; - queueNumber.innerHTML = data ? 'NA VEZ: '+ /*data.senhaGen + ' - '+*/ data.clientName.toUpperCase() + ' - ' + data.descricaoServico.toUpperCase() : 'Ninguem aguardando atendimento'; + //data.senhaGen + queueNumber.innerHTML = data ? `NA VEZ: ${data.clientName.toUpperCase()} - ${data.descricaoServico.toUpperCase()}` : 'Ninguem aguardando atendimento'; + selectedItemNameSpan.innerHTML = data ? ` ${data.clientName.toUpperCase()} [ ${data.senhaGen} ]` : 'Ninguem aguardando atendimento'; }); @@ -47,7 +52,7 @@ function populateList(currentData) { itemList.innerHTML = ''; // Limpa a lista anterior if (!proximos || proximos.length === 0 || !currentData) { - itemList.innerHTML = '
  • Nenhum item encontrado.
  • '; + itemList.innerHTML = '
  • Fila vazia!
  • '; nextButton.disabled = !currentData; return; } @@ -59,13 +64,13 @@ function populateList(currentData) { selectedItemId = itemToProcess.id; selectedItemName = itemToProcess.clientName; const li = document.createElement('li'); - li.textContent = /*${itemToProcess.senhaGen}: */ `${itemToProcess.clientName.toUpperCase()} - ${itemToProcess.attendanceType.toUpperCase()} - ${itemToProcess.descricaoServico.toUpperCase()}`; + li.innerHTML = /*${itemToProcess.senhaGen}: */ `${itemToProcess.clientName.toUpperCase()} - ${itemToProcess.attendanceType.toUpperCase()} - ${itemToProcess.descricaoServico.toUpperCase()}`; li.dataset.id = itemToProcess.id; // Armazena o ID no elemento li.classList.add('selected'); // Marca como selecionado visualmente (precisa de CSS) itemList.appendChild(li); nextButton.disabled = false; } else { - itemList.innerHTML = '
  • Nenhum item para processar.
  • '; + itemList.innerHTML = '
  • Fila vazia!
  • '; nextButton.disabled = !currentData; selectedItemId = null; selectedItemName = ''; @@ -96,9 +101,6 @@ showListView(); //inicia o atendimento function showObservationView() { if (!selectedItemId) return; // Não muda se nada estiver selecionado - - //obter o id do atendimento de modo asyncrono - selectedItemNameSpan.textContent = selectedItemName || `ID ${selectedItemId}`; // Mostra nome ou ID listView.style.display = 'none'; observationView.style.display = 'block'; } @@ -121,14 +123,14 @@ logoutButton.addEventListener('click',()=>{ // // // Evento do botão "Salvar" -// saveButton.addEventListener('click', () => { -// const observation = observationText.value.trim(); -// if (selectedItemId !== null) { -// window.electronAPI.saveObservation({ itemId: selectedItemId, observation: observation }); -// window.location.reload(); -// // A janela será escondida pelo main process após salvar (conforme main.js) -// // Se quiser resetar a view sem esconder, chame showListView() aqui. -// } -// }); +saveButton.addEventListener('click', () => { + const observation = observationText.value; + if (selectedItemId !== null) { + window.electronAPI.saveObservation({ itemId: selectedItemId, observation: observation }); + window.location.reload(); + // A janela será escondida pelo main process após salvar (conforme main.js) + // Se quiser resetar a view sem esconder, chame showListView() aqui. + } +}); // Inicialmente, mostra a view da lista (estará vazia até receber dados)