Rende usabili i filtri destinatari e permette di eliminare le bozze email.
CI / scan_ruby (push) Failing after 12m54s
CI / scan_js (push) Successful in 12m34s
CI / lint (push) Failing after 13m10s

Le listbox non applicavano sport e altri criteri; ora i filtri sono checkbox, c'è «mai contattati» e dal cruscotto si cancellano le bozze. La lista organizzazioni allinea le colonne al foglio campagna.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-07 07:57:50 +02:00
co-authored by Cursor
parent e492c43bf8
commit 3e73e708e4
16 changed files with 1114 additions and 90 deletions
+40 -18
View File
@@ -46,6 +46,7 @@
</div>
<%= opp ? stage_badge(opp.pipeline_stage) : nil %>
</div>
<div class="mt-1 break-anywhere text-xs text-zinc-500"><%= org.email.presence || "—" %></div>
<div class="mt-2 flex flex-wrap items-center gap-2 text-xs text-zinc-500">
<%= streaming_badge(org.streaming_status) %>
<% if opp&.ab_variant.present? %><%= ab_variant_badge(opp.ab_variant) %><% end %>
@@ -63,31 +64,52 @@
<table class="min-w-full divide-y divide-zinc-100 dark:divide-zinc-800 text-sm">
<thead class="bg-zinc-50 text-left text-xs uppercase tracking-wide text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
<tr>
<th class="px-4 py-3">N.</th>
<th class="px-4 py-3">Organizzazione</th>
<th class="px-4 py-3">Regione</th>
<th class="px-4 py-3">M/F</th>
<th class="px-4 py-3">Streaming</th>
<th class="px-4 py-3">Test</th>
<th class="px-4 py-3">Stage</th>
<th class="px-4 py-3">Invio</th>
<th class="px-3 py-3">N.</th>
<th class="px-3 py-3">Regione</th>
<th class="px-3 py-3">Prov.</th>
<th class="px-3 py-3">Società</th>
<th class="px-3 py-3">M/F</th>
<th class="px-3 py-3">Email verificata</th>
<th class="px-3 py-3">Sito / profilo</th>
<th class="px-3 py-3">Streaming rilevato</th>
<th class="px-3 py-3">Evidenza / fit commerciale</th>
<th class="px-3 py-3">Test A/B</th>
<th class="px-3 py-3">Stato invio</th>
<th class="px-3 py-3">Data invio</th>
<th class="px-3 py-3">Esito</th>
<th class="px-3 py-3">Demo / Trial</th>
<th class="px-3 py-3">Conversione</th>
<th class="px-3 py-3">Piano</th>
<th class="px-3 py-3">Fonte contatto / ricerca</th>
<th class="px-3 py-3">Data verifica</th>
<th class="px-3 py-3">Note follow-up</th>
</tr>
</thead>
<tbody class="divide-y divide-zinc-100 dark:divide-zinc-800">
<% @organizations.each do |org| %>
<% opp = org.campaign_opportunity(current_project) %>
<tr class="hover:bg-zinc-50 dark:hover:bg-zinc-800/80">
<td class="px-4 py-3 tabular-nums text-zinc-500"><%= org.list_position || "—" %></td>
<td class="px-4 py-3">
<td class="whitespace-nowrap px-3 py-3 tabular-nums text-zinc-500"><%= org.list_position || "—" %></td>
<td class="whitespace-nowrap px-3 py-3"><%= org.region.presence || "—" %></td>
<td class="whitespace-nowrap px-3 py-3"><%= org.province.presence || "—" %></td>
<td class="px-3 py-3">
<%= link_to org.name, org, class: "font-medium text-zinc-900 hover:underline dark:text-zinc-100" %>
<div class="text-xs text-slate-500"><%= org.email.presence || org.organization_type_label %></div>
</td>
<td class="px-4 py-3"><%= [org.region, org.province].compact_blank.join(" · ").presence || "—" %></td>
<td class="px-4 py-3"><%= org.team_gender_label.presence || "—" %></td>
<td class="px-4 py-3"><%= streaming_badge(org.streaming_status) || "—" %></td>
<% opp = org.campaign_opportunity(current_project) %>
<td class="px-4 py-3"><%= opp&.ab_variant.presence || "—" %></td>
<td class="px-4 py-3"><%= opp ? stage_badge(opp.pipeline_stage) : "—" %></td>
<td class="px-4 py-3"><%= opp&.send_status_label.presence || "—" %></td>
<td class="whitespace-nowrap px-3 py-3"><%= org.team_gender_label.presence || "—" %></td>
<td class="px-3 py-3"><%= mailto_link(org.email, class: "text-sky-700 hover:underline dark:text-sky-400") %></td>
<td class="px-3 py-3"><%= external_link(org.website, class: "text-sky-700 hover:underline dark:text-sky-400") %></td>
<td class="whitespace-nowrap px-3 py-3"><%= streaming_badge(org.streaming_status) || "—" %></td>
<td class="px-3 py-3 text-zinc-600 dark:text-zinc-300"><%= table_clip(org.commercial_fit) %></td>
<td class="px-3 py-3"><%= opp&.ab_variant.present? ? ab_variant_badge(opp.ab_variant) : "—" %></td>
<td class="whitespace-nowrap px-3 py-3"><%= opp&.send_status_label.presence || "—" %></td>
<td class="whitespace-nowrap px-3 py-3"><%= format_date(opp&.sent_on) %></td>
<td class="px-3 py-3"><%= table_clip(opp&.outcome, length: 24) %></td>
<td class="whitespace-nowrap px-3 py-3"><%= opp ? yes_no(opp.demo_trial) : "—" %></td>
<td class="whitespace-nowrap px-3 py-3"><%= opp ? yes_no(opp.converted) : "—" %></td>
<td class="whitespace-nowrap px-3 py-3"><%= opp&.product.presence || "—" %></td>
<td class="px-3 py-3"><%= external_link(org.source_url, class: "text-sky-700 hover:underline dark:text-sky-400") %></td>
<td class="whitespace-nowrap px-3 py-3"><%= format_date(org.verified_at) %></td>
<td class="px-3 py-3 text-zinc-600 dark:text-zinc-300"><%= table_clip(org.notes) %></td>
</tr>
<% end %>
</tbody>