fix: persist messaging schedule state in frontend to avoid data loss on tab switch

This commit is contained in:
Sidney 2026-04-30 11:43:00 -03:00
parent a8adcd6cf0
commit 94fe187998
2 changed files with 25 additions and 0 deletions

View File

@ -9,6 +9,7 @@
- [x] **Segurança Anti-Spam:** Desativado envio imediato de `PAYMENT_OVERDUE` via Webhook para garantir que cobranças ocorram apenas no horário agendado. - [x] **Segurança Anti-Spam:** Desativado envio imediato de `PAYMENT_OVERDUE` via Webhook para garantir que cobranças ocorram apenas no horário agendado.
- [x] **Auto-Initialization DB:** Script de boot que garante a existência das colunas `overdue_warnings_count` e `last_overdue_warning_at` na tabela `alunos_cobrancas`. - [x] **Auto-Initialization DB:** Script de boot que garante a existência das colunas `overdue_warnings_count` e `last_overdue_warning_at` na tabela `alunos_cobrancas`.
- [x] **Correção de Crash no Portal:** Resolvido erro de `.toFixed()` que quebrava as abas de "Avaliações" e "Notas" devido ao retorno de tipos `NUMERIC` do PostgreSQL como strings. - [x] **Correção de Crash no Portal:** Resolvido erro de `.toFixed()` que quebrava as abas de "Avaliações" e "Notas" devido ao retorno de tipos `NUMERIC` do PostgreSQL como strings.
- [x] **Persistência de UI (Mensagens):** Integrada chamada ao `updateData` ao salvar agendamentos, garantindo que o estado do toggle não seja perdido ao trocar de aba no Manager.
- [ ] Próximo Passo: Monitorar o log de disparos automáticos (`[Cron]`) e validar a taxa de entrega via Evolution API. - [ ] Próximo Passo: Monitorar o log de disparos automáticos (`[Cron]`) e validar a taxa de entrega via Evolution API.
## 📅 Histórico Anterior (22/04/2026) ## 📅 Histórico Anterior (22/04/2026)

View File

@ -411,6 +411,12 @@ const Messages: React.FC<MessagesProps> = ({ data, updateData }) => {
}); });
const d = await resp.json(); const d = await resp.json();
setCronActive(d.preventive); setCronActive(d.preventive);
// Persistir no estado global para não perder ao trocar de aba
const newRules = { ...templates.automationRules, autoScheduleEnabled: newEnabled, autoScheduleTime: scheduleTime };
setTemplates(prev => ({ ...prev, automationRules: newRules }));
updateData({ messageTemplates: { ...templates, automationRules: newRules } });
showAlert('Sucesso', newEnabled ? `Rotina ativada para ${scheduleTime}!` : 'Rotina automática desativada.', 'success'); showAlert('Sucesso', newEnabled ? `Rotina ativada para ${scheduleTime}!` : 'Rotina automática desativada.', 'success');
} catch { } catch {
showAlert('Erro', 'Erro ao salvar agendamento.', 'error'); showAlert('Erro', 'Erro ao salvar agendamento.', 'error');
@ -452,6 +458,12 @@ const Messages: React.FC<MessagesProps> = ({ data, updateData }) => {
}); });
const d = await resp.json(); const d = await resp.json();
setCronActive(d.preventive); setCronActive(d.preventive);
// Persistir no estado global
const newRules = { ...templates.automationRules, autoScheduleEnabled: true, autoScheduleTime: scheduleTime };
setTemplates(prev => ({ ...prev, automationRules: newRules }));
updateData({ messageTemplates: { ...templates, automationRules: newRules } });
showAlert('Sucesso', `Horário atualizado para ${scheduleTime}!`, 'success'); showAlert('Sucesso', `Horário atualizado para ${scheduleTime}!`, 'success');
} catch { } catch {
showAlert('Erro', 'Erro ao atualizar horário.', 'error'); showAlert('Erro', 'Erro ao atualizar horário.', 'error');
@ -515,6 +527,12 @@ const Messages: React.FC<MessagesProps> = ({ data, updateData }) => {
}); });
const d = await resp.json(); const d = await resp.json();
setCronOverdueActive(d.overdue); setCronOverdueActive(d.overdue);
// Persistir no estado global
const newRules = { ...templates.automationRules, autoScheduleOverdueEnabled: newEnabled, autoScheduleOverdueTime: scheduleOverdueTime };
setTemplates(prev => ({ ...prev, automationRules: newRules }));
updateData({ messageTemplates: { ...templates, automationRules: newRules } });
showAlert('Sucesso', newEnabled ? `Rotina de inadimplência ativada para ${scheduleOverdueTime}!` : 'Rotina de inadimplência desativada.', 'success'); showAlert('Sucesso', newEnabled ? `Rotina de inadimplência ativada para ${scheduleOverdueTime}!` : 'Rotina de inadimplência desativada.', 'success');
} catch { } catch {
showAlert('Erro', 'Erro ao salvar agendamento.', 'error'); showAlert('Erro', 'Erro ao salvar agendamento.', 'error');
@ -556,6 +574,12 @@ const Messages: React.FC<MessagesProps> = ({ data, updateData }) => {
}); });
const d = await resp.json(); const d = await resp.json();
setCronOverdueActive(d.overdue); setCronOverdueActive(d.overdue);
// Persistir no estado global
const newRules = { ...templates.automationRules, autoScheduleOverdueEnabled: true, autoScheduleOverdueTime: scheduleOverdueTime };
setTemplates(prev => ({ ...prev, automationRules: newRules }));
updateData({ messageTemplates: { ...templates, automationRules: newRules } });
showAlert('Sucesso', `Horário atualizado para ${scheduleOverdueTime}!`, 'success'); showAlert('Sucesso', `Horário atualizado para ${scheduleOverdueTime}!`, 'success');
} catch { } catch {
showAlert('Erro', 'Erro ao atualizar horário.', 'error'); showAlert('Erro', 'Erro ao atualizar horário.', 'error');