<%# Editor de blocos de UM evento em UM canal. O estado vive num array JS; o HTML dos cards é desenhado a partir dele e serializado num hidden ao salvar. Desenhar a partir do estado (em vez de ler o DOM) é o que faz arrastar, remover e reordenar não perderem conteúdo. %> <% outro_canal = @canal == 'email' ? 'whatsapp' : 'email' %>

<%= icone :editar, espaco: false %> Mensagem — <%= @evento.nome %>

<% wpp = @canal != 'email' %> <%= icone(wpp ? :telefone : :email, cor: nil, tamanho: 'w-3.5 h-3.5', espaco: false) %> <%= wpp ? 'WhatsApp' : 'E-mail' %> <%= @evento.gatilho_label %>
<%= link_to template_admin_evento_path(@evento, canal: outro_canal), data: { turbo: false }, class: 'inline-flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm border border-white/10 text-gray-300 hover:border-white/20 hover:text-white transition-colors whitespace-nowrap' do %> <%= icone(outro_canal == 'email' ? :email : :telefone, cor: nil, tamanho: 'w-4 h-4', espaco: false) %> Editar <%= outro_canal == 'email' ? 'e-mail' : 'WhatsApp' %> <% end %> <%= link_to admin_eventos_path, data: { turbo: false }, class: 'inline-flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm border border-white/10 text-gray-300 hover:border-white/20 hover:text-white transition-colors whitespace-nowrap' do %> <%= icone :voltar, cor: nil, tamanho: 'w-4 h-4', espaco: false %> Voltar <% end %>
<%= render 'shared/flash' %> <% if @template.errors.any? %>

<%= pluralize(@template.errors.count, 'erro', 'erros') %> encontrado<%= @template.errors.count > 1 ? 's' : '' %>:

<% end %> <%= form_with url: template_admin_evento_path(@evento, canal: @canal), method: :patch, data: { turbo: false }, id: 'form-template' do |f| %> <%= hidden_field_tag :blocos, @template.blocos.to_json, id: 'campo-blocos' %>
<%# ── Paleta ──────────────────────────────────────────── %>

Blocos

Arraste para a mensagem — ou clique.

<% Notificacao::Blocos::CATALOGO.each do |tipo, meta| %>
<%= meta[:rotulo] %> <%= meta[:dica] %>
<% end %>
<%# ── Variáveis ─────────────────────────────────────── %> <%# ── EMOJIS ───────────────────────────────────────── Digitar emoji no teclado do computador é o passo que trava o ADM; aqui ele clica. A lista é curta e curada de propósito — um seletor completo viraria uma biblioteca externa (e CSP) para inserir 3 caracteres. %>

Emojis

<% %w[✅ ❌ ⚠️ 📌 📢 💰 💵 🧾 📅 🕒 🚚 📦 📍 👤 👍 🙏 ⭐ 🔴 🟢 🟡 ➡️ 📄 📷 🔔 ✍️ 😀 🎉].each do |emoji| %> <% end %>

Variáveis

Clique num campo da mensagem e depois numa variável para inseri-la ali.

<%# Agrupadas por ORIGEM e sem esconder o que não se aplica: a variável de outro gatilho aparece apagada, com o aviso de que sai em branco. Antes, a tela só listava as 6 do contexto — qualquer outro dado exigia deploy. %> <% @variaveis.each do |origem, itens| %> <% next if itens.empty? %>

<%= Notificacao::CatalogoVariaveis::ORIGENS[origem] %>

<% itens.each do |v| %> <% end %>
<% end %>

As apagadas (·) não existem neste gatilho e sairiam em branco. <%= link_to 'Criar variável própria', admin_variaveis_path, class: 'text-orange-500 hover:underline' %>.

<%# ── Mensagem ────────────────────────────────────────── %>
<% if @canal == 'email' %>
<%= text_field_tag :assunto, @template.assunto, id: 'assunto', class: 'campo-editavel w-full px-4 py-3 bg-[#0a0a0a] border border-white/10 rounded-xl text-white placeholder-gray-600 focus:outline-none focus:border-[#f97316] focus:ring-1 focus:ring-[#f97316] transition-colors text-sm' %>
<% end %>

Mensagem

<%= icone :vazio, tamanho: 'w-8 h-8', cor: 'text-gray-600', espaco: false %>

Arraste um bloco para cá. Sem blocos, o evento continua usando o texto padrão do sistema.

<%= submit_tag 'Salvar mensagem', class: 'px-6 py-3 bg-[#f97316] hover:bg-orange-500 text-white font-semibold rounded-xl transition-colors cursor-pointer min-h-[48px]' %>
<%# ── Preview ─────────────────────────────────────────── %>

Preview

Com valores de exemplo, renderizado pelo mesmo código do envio.

<%# iframe sandbox: o HTML do e-mail é montado pelo nosso renderizador (que escapa tudo), mas exibir dentro de um sandbox sem scripts evita que os estilos do e-mail vazem para o admin — e vice-versa. %>

      
<% end %>