adicionadas novas funcionalidades, agora o app mostra se tem um atendimento em progresso, antes de iniciar o chamado de outro cliente
This commit is contained in:
parent
8280bb2ff6
commit
1598ccd22f
39
floating.js
39
floating.js
|
|
@ -3,6 +3,11 @@ const countSpan = document.getElementById('count');
|
||||||
|
|
||||||
// Atualiza a contagem e a cor do botão quando recebe do main process
|
// Atualiza a contagem e a cor do botão quando recebe do main process
|
||||||
window.electronAPI.onUpdateCount((value) => {
|
window.electronAPI.onUpdateCount((value) => {
|
||||||
|
// Se estiver em atendimento, ignora qualquer atualização de contagem
|
||||||
|
if (floatButton.classList.contains('em-atendimento')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
countSpan.innerHTML = value ?? 0;
|
countSpan.innerHTML = value ?? 0;
|
||||||
// Verifica a contagem para mudar a cor
|
// Verifica a contagem para mudar a cor
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
|
|
@ -12,6 +17,40 @@ window.electronAPI.onUpdateCount((value) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Altera a cor do botão com base no status do atendimento
|
||||||
|
window.electronAPI.onAtendimentoStatusChanged((status) => {
|
||||||
|
if (status === 'iniciado') {
|
||||||
|
const nomeAtendimento = localStorage.getItem('atendimentoAtualNome');
|
||||||
|
floatButton.classList.remove('has-items');
|
||||||
|
floatButton.classList.add('em-atendimento');
|
||||||
|
countSpan.innerHTML = '-'; // Mostra o hífen
|
||||||
|
if (nomeAtendimento) {
|
||||||
|
floatButton.setAttribute('title', `Atendendo: ${nomeAtendimento}`);
|
||||||
|
}
|
||||||
|
} else { // 'finalizado'
|
||||||
|
floatButton.classList.remove('em-atendimento');
|
||||||
|
floatButton.setAttribute('title', 'Chamar próximo da fila');
|
||||||
|
// Solicita uma atualização imediata da contagem para refletir o estado atual da fila
|
||||||
|
window.electronAPI.refreshCount();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ao carregar, verifica se já existe um atendimento em andamento
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const atendimentoAtual = localStorage.getItem('atendimentoAtual');
|
||||||
|
if (atendimentoAtual) {
|
||||||
|
const nomeAtendimento = localStorage.getItem('atendimentoAtualNome');
|
||||||
|
floatButton.classList.remove('has-items');
|
||||||
|
floatButton.classList.add('em-atendimento');
|
||||||
|
countSpan.innerHTML = '-'; // Mostra o hífen
|
||||||
|
if (nomeAtendimento) {
|
||||||
|
floatButton.setAttribute('title', `Atendendo: ${nomeAtendimento}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
floatButton.setAttribute('title', 'Chamar próximo da fila');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Mostra a janela principal ao clicar
|
// Mostra a janela principal ao clicar
|
||||||
floatButton.addEventListener('click', () => {
|
floatButton.addEventListener('click', () => {
|
||||||
window.electronAPI.showMainWindow();
|
window.electronAPI.showMainWindow();
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ const { contextBridge, ipcRenderer } = require('electron');
|
||||||
|
|
||||||
contextBridge.exposeInMainWorld('electronAPI', {
|
contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
onUpdateCount: (callback) => ipcRenderer.on('update-count', (_event, value) => callback(value)),
|
onUpdateCount: (callback) => ipcRenderer.on('update-count', (_event, value) => callback(value)),
|
||||||
|
onAtendimentoStatusChanged: (callback) => ipcRenderer.on('atendimento-status-changed', (_event, status) => callback(status)),
|
||||||
|
refreshCount: () => ipcRenderer.send('refresh-count'),
|
||||||
showMainWindow: () => ipcRenderer.send('chamar-fila'),
|
showMainWindow: () => ipcRenderer.send('chamar-fila'),
|
||||||
showMenu: () => ipcRenderer.send('show-context-menu')
|
showMenu: () => ipcRenderer.send('show-context-menu')
|
||||||
});
|
});
|
||||||
41
main.js
41
main.js
|
|
@ -462,10 +462,8 @@ ipcMain.handle('get-count', async () => {
|
||||||
// Ouvir pedido para mostrar a janela principal
|
// Ouvir pedido para mostrar a janela principal
|
||||||
ipcMain.on('chamar-fila', async () => {
|
ipcMain.on('chamar-fila', async () => {
|
||||||
|
|
||||||
const countFila = async () => {
|
// Primeiro, verifica se já existe um atendimento em andamento
|
||||||
const proximos = JSON.parse(await floatingWin.webContents.executeJavaScript("localStorage.getItem('proximos')")) ?? [];
|
const atendimentoAtualId = await floatingWin.webContents.executeJavaScript("localStorage.getItem('atendimentoAtual')");
|
||||||
return proximos.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
const showMainWindow = () => {
|
const showMainWindow = () => {
|
||||||
if (mainWin) {
|
if (mainWin) {
|
||||||
|
|
@ -484,6 +482,19 @@ ipcMain.on('chamar-fila', async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Se um atendimento já estiver em andamento, apenas mostra a janela principal.
|
||||||
|
// A lógica em renderer.js cuidará de exibir a tela de observação.
|
||||||
|
if (atendimentoAtualId) {
|
||||||
|
showMainWindow();
|
||||||
|
return; // Interrompe a execução aqui
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se não houver atendimento em andamento, continua com a lógica original.
|
||||||
|
const countFila = async () => {
|
||||||
|
const proximos = JSON.parse(await floatingWin.webContents.executeJavaScript("localStorage.getItem('proximos')")) ?? [];
|
||||||
|
return proximos.length;
|
||||||
|
}
|
||||||
|
|
||||||
const requestData = async () => {
|
const requestData = async () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -583,6 +594,14 @@ ipcMain.on('chamar-fila', async () => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ouve um pedido da janela flutuante para forçar a atualização da contagem
|
||||||
|
ipcMain.on('refresh-count', async () => {
|
||||||
|
if (floatingWin) {
|
||||||
|
const proximos = JSON.parse(await floatingWin.webContents.executeJavaScript("localStorage.getItem('proximos')")) ?? [];
|
||||||
|
floatingWin.webContents.send('update-count', proximos.length);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.on('select-atend-id', (itemId) => {
|
ipcMain.on('select-atend-id', (itemId) => {
|
||||||
selectedItemId = itemId;
|
selectedItemId = itemId;
|
||||||
console.log(selectedItemId);
|
console.log(selectedItemId);
|
||||||
|
|
@ -632,6 +651,20 @@ ipcMain.on('iniciar-atendimento', async (event, itemId) => {
|
||||||
// A janela principal já mudou a UI ao enviar o evento 'next-step'
|
// A janela principal já mudou a UI ao enviar o evento 'next-step'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ouve quando um atendimento é iniciado e notifica a janela flutuante
|
||||||
|
ipcMain.on('atendimento-iniciado', (event, itemId) => {
|
||||||
|
if (floatingWin) {
|
||||||
|
floatingWin.webContents.send('atendimento-status-changed', 'iniciado');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ouve quando um atendimento é finalizado e notifica a janela flutuante
|
||||||
|
ipcMain.on('atendimento-finalizado', () => {
|
||||||
|
if (floatingWin) {
|
||||||
|
floatingWin.webContents.send('atendimento-status-changed', 'finalizado');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Ouvir clique no botão "Salvar"
|
// Ouvir clique no botão "Salvar"
|
||||||
ipcMain.on('save-observation', async (event, { itemId, observation }) => {
|
ipcMain.on('save-observation', async (event, { itemId, observation }) => {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
//inicia o atendimento atual
|
//inicia o atendimento atual
|
||||||
iniciaAtendimento: (itemId) => ipcRenderer.send('iniciar-atendimento', itemId),
|
iniciaAtendimento: (itemId) => ipcRenderer.send('iniciar-atendimento', itemId),
|
||||||
|
|
||||||
|
//notifica sobre o status do atendimento
|
||||||
|
atendimentoIniciado: (itemId) => ipcRenderer.send('atendimento-iniciado', itemId),
|
||||||
|
atendimentoFinalizado: () => ipcRenderer.send('atendimento-finalizado'),
|
||||||
|
|
||||||
showObservation: (callback) => ipcRenderer.on('show-observation', (_event) => callback() ),
|
showObservation: (callback) => ipcRenderer.on('show-observation', (_event) => callback() ),
|
||||||
//salva a observação do atendimento
|
//salva a observação do atendimento
|
||||||
saveObservation: (data) => ipcRenderer.send('save-observation', data),
|
saveObservation: (data) => ipcRenderer.send('save-observation', data),
|
||||||
|
|
|
||||||
38
renderer.js
38
renderer.js
|
|
@ -91,7 +91,11 @@ window.electronAPI.selectAtendID((data) => {
|
||||||
// Reseta a view para a lista sempre que os dados são carregados ao clicar no botão para abrir a janela
|
// Reseta a view para a lista sempre que os dados são carregados ao clicar no botão para abrir a janela
|
||||||
populateList(data);
|
populateList(data);
|
||||||
showListView();
|
showListView();
|
||||||
|
|
||||||
|
// Garante que o item selecionado (ID e Nome) seja o que veio da chamada, sobrescrevendo o da lista.
|
||||||
selectedItemId = data.id ?? null;
|
selectedItemId = data.id ?? null;
|
||||||
|
selectedItemName = data.clientName ?? '';
|
||||||
|
|
||||||
//data.senhaGen
|
//data.senhaGen
|
||||||
queueNumber.innerHTML = data ? `NA VEZ: <u>${data.clientName.toUpperCase()}</u> - ${data.descricaoServico.toUpperCase()}` : 'Ninguem aguardando atendimento';
|
queueNumber.innerHTML = data ? `NA VEZ: <u>${data.clientName.toUpperCase()}</u> - ${data.descricaoServico.toUpperCase()}` : 'Ninguem aguardando atendimento';
|
||||||
selectedItemNameSpan.innerHTML = data ? `<u> ${data.clientName.toUpperCase()} </u> <i style="float:right;">[ ${data.senhaGen} ]</i>` : 'Ninguem aguardando atendimento';
|
selectedItemNameSpan.innerHTML = data ? `<u> ${data.clientName.toUpperCase()} </u> <i style="float:right;">[ ${data.senhaGen} ]</i>` : 'Ninguem aguardando atendimento';
|
||||||
|
|
@ -104,6 +108,16 @@ window.electronAPI.showObservation(() => {
|
||||||
|
|
||||||
// Função para popular a lista de itens
|
// Função para popular a lista de itens
|
||||||
function populateList(currentData) {
|
function populateList(currentData) {
|
||||||
|
const atendimentoEmAndamentoId = localStorage.getItem('atendimentoAtual');
|
||||||
|
const atendimentoEmAndamentoNome = localStorage.getItem('atendimentoAtualNome');
|
||||||
|
|
||||||
|
if (atendimentoEmAndamentoId) {
|
||||||
|
itemList.innerHTML = `<li>Atendimento com <strong>${(atendimentoEmAndamentoNome || '').toUpperCase()}</strong> em andamento.</li>`;
|
||||||
|
queueNumber.innerHTML = `EM ATENDIMENTO: <u>${(atendimentoEmAndamentoNome || '').toUpperCase()}</u>`;
|
||||||
|
nextButton.disabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -142,6 +156,19 @@ function populateList(currentData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Verifica o estado ao carregar a janela
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const atendimentoEmAndamentoId = localStorage.getItem('atendimentoAtual');
|
||||||
|
if (atendimentoEmAndamentoId) {
|
||||||
|
// Se um atendimento está em andamento, a tela de observação deve ser mostrada
|
||||||
|
selectedItemId = atendimentoEmAndamentoId;
|
||||||
|
selectedItemName = localStorage.getItem('atendimentoAtualNome');
|
||||||
|
selectedItemNameSpan.innerHTML = `<u> ${(selectedItemName || '').toUpperCase()} </u>`;
|
||||||
|
showObservationView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
//mostra a tela de listagem e permite iniciar o atendimento
|
//mostra a tela de listagem e permite iniciar o atendimento
|
||||||
function showListView() {
|
function showListView() {
|
||||||
listView.style.display = 'block';
|
listView.style.display = 'block';
|
||||||
|
|
@ -163,6 +190,12 @@ function showObservationView() {
|
||||||
// // Evento do botão "Iniciar atendimento"
|
// // Evento do botão "Iniciar atendimento"
|
||||||
nextButton.addEventListener('click', () => {
|
nextButton.addEventListener('click', () => {
|
||||||
if (selectedItemId !== null) {
|
if (selectedItemId !== null) {
|
||||||
|
// Salva o estado de atendimento no localStorage
|
||||||
|
localStorage.setItem('atendimentoAtual', selectedItemId);
|
||||||
|
localStorage.setItem('atendimentoAtualNome', selectedItemName);
|
||||||
|
|
||||||
|
// Notifica o main process e muda a view
|
||||||
|
window.electronAPI.atendimentoIniciado(selectedItemId);
|
||||||
window.electronAPI.iniciaAtendimento(selectedItemId);
|
window.electronAPI.iniciaAtendimento(selectedItemId);
|
||||||
showObservationView(); // Muda para a tela de observação
|
showObservationView(); // Muda para a tela de observação
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -181,6 +214,11 @@ logoutButton.addEventListener('click', () => {
|
||||||
saveButton.addEventListener('click', () => {
|
saveButton.addEventListener('click', () => {
|
||||||
const observation = observationText.value;
|
const observation = observationText.value;
|
||||||
if (selectedItemId !== null) {
|
if (selectedItemId !== null) {
|
||||||
|
// Limpa o estado de atendimento
|
||||||
|
localStorage.removeItem('atendimentoAtual');
|
||||||
|
localStorage.removeItem('atendimentoAtualNome');
|
||||||
|
window.electronAPI.atendimentoFinalizado();
|
||||||
|
|
||||||
window.electronAPI.saveObservation({ itemId: selectedItemId, observation: observation });
|
window.electronAPI.saveObservation({ itemId: selectedItemId, observation: observation });
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,13 @@ body#floating{
|
||||||
animation: pulse-border .5s infinite;
|
animation: pulse-border .5s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Nova classe para quando estiver em atendimento */
|
||||||
|
#float-button.em-atendimento {
|
||||||
|
background-color: var(--danger-color); /* Vermelho */
|
||||||
|
border: 4px solid var(--dark-danger-color);
|
||||||
|
animation: pulse-border .2s infinite; /* Pulso mais rápido */
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes pulse-border {
|
@keyframes pulse-border {
|
||||||
0% {
|
0% {
|
||||||
border-color: var(--medium-gold);
|
border-color: var(--medium-gold);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue