Arrumar a tela de pagamento colocando paginação
This commit is contained in:
BIN
Imagens para implantação /Imagem colada (2).png
Normal file
BIN
Imagens para implantação /Imagem colada (2).png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 299 KiB |
48
README.md
48
README.md
@@ -1366,3 +1366,51 @@ docker compose up -d --build
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><strong>🔭 Roadmap — Integrações futuras com a API SimpliRoute (08/07/2026)</strong></summary>
|
||||
|
||||
Mapeamento completo da API do SimpliRoute (documentation.simpliroute.com) cruzado com o fluxo
|
||||
do sistema. **Nada aqui está implementado** — são os próximos passos priorizados. A base
|
||||
técnica já existe (`SimpliRoute::Client`, `SimpliRoute::PlanilhaCarga`, token via ENV):
|
||||
cada item vira uma fase própria quando for priorizado.
|
||||
|
||||
### 1. 🚀 Carga direta no SimpliRoute (substitui o baixar/importar planilha)
|
||||
`POST /v1/routes/visits/` aceita criação **em lote**: um botão "Subir para o SimpliRoute"
|
||||
criaria as visitas da operação vigente direto pela API, com as mesmas regras da planilha
|
||||
(título `NF {nf} - {nome}`, janelas 08:00–18:00, lat/long do mês anterior, etc.).
|
||||
> ⚠️ **Pré-requisito que segura esta fase: consolidar os ENDEREÇOS antes da subida.**
|
||||
- Anti-duplicação: conferir `reference` + `planned_date` antes de criar (reexecutar não duplica).
|
||||
- Desfazer: `POST /v1/bulk/delete/visits/` permite implementar um "remover carga".
|
||||
|
||||
### 2. 🧾 Relatório de comprovantes de entrega (POD)
|
||||
`GET /v1/plans/visits/{visit_id}/detail/` traz **foto, assinatura, hora e GPS** de cada
|
||||
entrega → gerar PDF por operação/mês (reuso do padrão Prawn em `app/services/pdf/`).
|
||||
Valor: faturamento com STS/prefeitura e defesa em disputas ("não recebi").
|
||||
|
||||
### 3. ⚡ Webhooks — painel em tempo real
|
||||
`POST /v1/addons/webhooks/` com eventos `visit_checkout`, `route_started/finished`,
|
||||
`on_its_way` → endpoint público autenticado no app grava o evento e o painel atualiza
|
||||
**na hora**, sem esperar a sync de 30 min. Exige atenção à segurança (assinatura,
|
||||
idempotência) e URL pública estável.
|
||||
|
||||
### 4. 📱 Aviso ao paciente via WhatsApp
|
||||
Evento `on_its_way` + ETA da API + Twilio já existente (`NotificacaoService`):
|
||||
"seu medicamento saiu para entrega". Reduz insucesso por **RESPONSÁVEL AUSENTE**
|
||||
(motivo real da lista de observations).
|
||||
|
||||
### 5. 📺 Monitor de rotas ao vivo
|
||||
`GET /v1/plans/{date}/vehicles/` + visitas por rota → tela "Operação de hoje" com cada
|
||||
veículo, % concluído e atrasos (complementa o dashboard, que olha o passado).
|
||||
|
||||
### 6. 👷 Sincronização de motoristas/veículos
|
||||
`GET /v1/accounts/drivers/` e `GET /v1/routes/vehicles/` ↔ usuários motoristas do sistema
|
||||
(hoje o vínculo é o nome digitado — sujeito a divergência).
|
||||
|
||||
### 7. 📊 Datamart e 🏷️ tags/skills
|
||||
Export paginado de analytics para enriquecer dashboards; tags/skills para classificar
|
||||
visitas por tipo de material.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
@@ -348,9 +348,9 @@
|
||||
<th class="py-2 pl-3 font-medium text-right">Valor</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody id="pagamentos-feitos-tbody">
|
||||
<% @pagamentos_feitos.each do |cm| %>
|
||||
<tr class="border-b border-white/5">
|
||||
<tr class="border-b border-white/5 pagamento-feito-row">
|
||||
<td class="py-2.5 pr-3 text-gray-300 whitespace-nowrap"><%= l cm.pago_em.to_date, format: :short %></td>
|
||||
<td class="py-2.5 px-3 text-white"><%= cm.motorista_nome %></td>
|
||||
<td class="py-2.5 px-3">
|
||||
@@ -364,6 +364,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="pagamentos-feitos-paginacao" class="flex items-center justify-between mt-3 hidden">
|
||||
<p class="text-gray-400 text-xs" id="pagamentos-feitos-info"></p>
|
||||
<div class="flex gap-1" id="pagamentos-feitos-abas"></div>
|
||||
</div>
|
||||
<% else %>
|
||||
<p class="text-gray-400 text-sm py-3">Nenhum pagamento realizado neste período.</p>
|
||||
<% end %>
|
||||
@@ -473,6 +477,55 @@
|
||||
})();
|
||||
</script>
|
||||
|
||||
<%# Paginação client-side da tabela de pagamentos realizados (10 por página) %>
|
||||
<script>
|
||||
(function () {
|
||||
function initPaginacaoPagamentos() {
|
||||
const tbody = document.getElementById('pagamentos-feitos-tbody');
|
||||
const nav = document.getElementById('pagamentos-feitos-paginacao');
|
||||
if (!tbody || !nav || nav.dataset.iniciado) return;
|
||||
nav.dataset.iniciado = '1';
|
||||
|
||||
const porPagina = 10;
|
||||
const linhas = Array.from(tbody.querySelectorAll('.pagamento-feito-row'));
|
||||
const paginas = Math.ceil(linhas.length / porPagina);
|
||||
if (paginas <= 1) return;
|
||||
|
||||
const abas = document.getElementById('pagamentos-feitos-abas');
|
||||
const info = document.getElementById('pagamentos-feitos-info');
|
||||
nav.classList.remove('hidden');
|
||||
|
||||
function mostrarPagina(p) {
|
||||
linhas.forEach(function (tr, i) {
|
||||
tr.style.display = (i >= (p - 1) * porPagina && i < p * porPagina) ? '' : 'none';
|
||||
});
|
||||
const de = (p - 1) * porPagina + 1;
|
||||
const ate = Math.min(p * porPagina, linhas.length);
|
||||
info.textContent = de + '–' + ate + ' de ' + linhas.length + ' pagamentos';
|
||||
abas.querySelectorAll('button').forEach(function (b) {
|
||||
const ativa = Number(b.dataset.pagina) === p;
|
||||
b.className = 'px-3 py-1.5 rounded-lg text-xs font-semibold transition-colors ' +
|
||||
(ativa ? 'bg-[#f97316] text-white'
|
||||
: 'bg-[#0a0a0a] text-gray-400 border border-white/5 hover:text-white');
|
||||
});
|
||||
}
|
||||
|
||||
for (let p = 1; p <= paginas; p++) {
|
||||
const btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.textContent = p;
|
||||
btn.dataset.pagina = p;
|
||||
btn.addEventListener('click', function () { mostrarPagina(p); });
|
||||
abas.appendChild(btn);
|
||||
}
|
||||
mostrarPagina(1);
|
||||
}
|
||||
|
||||
initPaginacaoPagamentos();
|
||||
document.addEventListener('turbo:load', initPaginacaoPagamentos);
|
||||
})();
|
||||
</script>
|
||||
|
||||
<%# Filtro de operação — submete o form ao marcar/desmarcar %>
|
||||
<script>
|
||||
(function () {
|
||||
|
||||
Reference in New Issue
Block a user