Files

143 lines
7.5 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<% ctx = { status: params[:status], canal: params[:canal] }.compact_blank %>
<%
# Pílula de filtro: uma só definição para os dois grupos (situação e canal),
# senão o estilo do "ativo" fatalmente diverge entre eles com o tempo.
pilula = lambda do |ativo|
base = 'px-4 py-2 rounded-xl text-sm border transition-colors'
ativo ? "#{base} bg-[#f97316] text-white border-[#f97316] font-semibold"
: "#{base} bg-[#0a0a0a] text-gray-400 border-white/10 hover:border-white/20 hover:text-white"
end
%>
<div class="space-y-6">
<div>
<h1 class="text-2xl font-bold text-white flex items-center gap-2">
<%= icone :historico, espaco: false %> Envios
</h1>
<p class="text-gray-400 text-sm mt-0.5">
O que saiu, para quem e se chegou. Uma falha de envio nunca trava o fechamento —
então é aqui que ela aparece.
</p>
</div>
<%= render 'shared/flash' %>
<%# Filtros %>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 p-4 flex flex-wrap items-center gap-4">
<div class="flex flex-wrap items-center gap-2">
<span class="text-xs font-semibold text-gray-500 uppercase tracking-wider mr-1">Situação</span>
<% [['', 'Todos'], ['enviado', 'Enviados'], ['falhou', 'Falhados'], ['pendente', 'Pendentes']].each do |valor, rotulo| %>
<%= link_to rotulo, admin_envios_path(ctx.merge(status: valor.presence).compact),
data: { turbo: false }, class: pilula.call(params[:status].to_s == valor) %>
<% end %>
</div>
<span class="hidden sm:block w-px h-6 bg-white/10"></span>
<div class="flex flex-wrap items-center gap-2">
<span class="text-xs font-semibold text-gray-500 uppercase tracking-wider mr-1">Canal</span>
<% [['', 'Todos'], ['whatsapp', 'WhatsApp'], ['email', 'E-mail']].each do |valor, rotulo| %>
<%= link_to rotulo, admin_envios_path(ctx.merge(canal: valor.presence).compact),
data: { turbo: false }, class: pilula.call(params[:canal].to_s == valor) %>
<% end %>
</div>
<% if @total_falhas.positive? %>
<span class="ml-auto inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-bold
bg-red-500/15 border border-red-500/30 text-red-300">
<%= icone :erro, cor: nil, tamanho: 'w-3.5 h-3.5', espaco: false %>
<%= @total_falhas %> falha(s) neste filtro
</span>
<% end %>
</div>
<%# Tabela %>
<div class="bg-[#1a1a1a] rounded-2xl border border-white/5 overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full">
<thead>
<tr class="border-b border-white/10">
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-400 uppercase tracking-wider">Quando</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-400 uppercase tracking-wider">Evento</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-400 uppercase tracking-wider">Destinatário</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-400 uppercase tracking-wider">Canal</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-400 uppercase tracking-wider">Situação</th>
<th class="px-6 py-4 text-left text-xs font-semibold text-gray-400 uppercase tracking-wider">Mensagem</th>
</tr>
</thead>
<tbody class="divide-y divide-white/5">
<% @envios.each do |envio| %>
<tr class="hover:bg-white/5 transition-colors align-top">
<td class="px-6 py-4 text-gray-400 text-sm whitespace-nowrap">
<%= envio.created_at.strftime('%d/%m/%Y') %>
<span class="block text-xs text-gray-600"><%= envio.created_at.strftime('%H:%M') %></span>
</td>
<td class="px-6 py-4 text-gray-300 text-sm"><%= envio.evento_notificacao&.nome || '—' %></td>
<td class="px-6 py-4">
<span class="text-white text-sm"><%= envio.contato&.nome || envio.user&.nome || '—' %></span>
<span class="block text-xs text-gray-500 font-mono mt-0.5"><%= envio.destino %></span>
</td>
<td class="px-6 py-4">
<% wpp = envio.canal == 'whatsapp' %>
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-bold
<%= wpp ? 'bg-green-500/15 border border-green-500/30 text-green-300'
: 'bg-blue-500/15 border border-blue-500/30 text-blue-300' %>">
<%= icone(wpp ? :telefone : :email, cor: nil, tamanho: 'w-3.5 h-3.5', espaco: false) %>
<%= wpp ? 'WhatsApp' : 'E-mail' %>
</span>
</td>
<td class="px-6 py-4">
<% cfg = case envio.status
when 'enviado' then { cor: 'bg-green-600 text-white', icone: :sucesso, label: 'Enviado' }
when 'falhou' then { cor: 'bg-red-600 text-white', icone: :erro, label: 'Falhou' }
else { cor: 'bg-yellow-500 text-black', icone: :relogio, label: envio.status.to_s.capitalize }
end %>
<%= badge_com_icone(cfg) %>
<% if envio.falhou? && envio.erro.present? %>
<span class="block text-xs text-red-300/80 max-w-[22rem] mt-1.5"><%= envio.erro.truncate(160) %></span>
<% end %>
</td>
<td class="px-6 py-4 text-gray-400 text-sm max-w-[24rem]">
<span class="block truncate" title="<%= envio.corpo %>"><%= envio.corpo.to_s.truncate(90) %></span>
</td>
</tr>
<% end %>
<% if @envios.empty? %>
<tr>
<td colspan="6" class="px-6 py-16 text-center text-gray-500">
<div class="mb-3"><%= icone :vazio, tamanho: 'w-10 h-10', cor: 'text-gray-600', espaco: false %></div>
<p>Nenhum envio registrado ainda.</p>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<% if @envios.any? && @pagy.pages > 1 %>
<% pag = ->(p) { admin_envios_path(ctx.merge(page: p)) } %>
<nav class="flex items-center justify-center gap-1.5 px-6 py-4 flex-wrap border-t border-white/10">
<% if @pagy.prev %>
<%= link_to '', pag.call(@pagy.prev), data: { turbo: false },
class: 'min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg border border-white/10 text-white hover:border-[#f97316] transition-colors' %>
<% end %>
<% @pagy.series.each do |item| %>
<% if item == :gap %>
<span class="px-2 text-gray-500">…</span>
<% elsif item.is_a?(String) %>
<span class="min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg bg-[#f97316] text-white font-bold"><%= item %></span>
<% else %>
<%= link_to item, pag.call(item), data: { turbo: false },
class: 'min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg border border-white/10 text-white hover:border-[#f97316] transition-colors' %>
<% end %>
<% end %>
<% if @pagy.next %>
<%= link_to '', pag.call(@pagy.next), data: { turbo: false },
class: 'min-w-[40px] min-h-[40px] flex items-center justify-center rounded-lg border border-white/10 text-white hover:border-[#f97316] transition-colors' %>
<% end %>
</nav>
<% end %>
</div>
</div>