Rende leggibili card, badge e testi mute in tema scuro.

Le righe task di oggi restavano crema con testo chiaro; i badge e gli heading senza dark: si perdevano sullo sfondo.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-03 07:36:48 +02:00
co-authored by Cursor
parent 8f73105dfe
commit b5737a7ee7
11 changed files with 104 additions and 47 deletions
+22
View File
@@ -123,6 +123,28 @@ html.dark .hover\:bg-slate-50:hover {
background-color: #27272a;
}
/* Testi “light-only” usati ovunque come mute/alert: in dark restano leggibili. */
html.dark .text-slate-500,
html.dark .text-slate-400 {
color: #a1a1aa;
}
html.dark .text-slate-600 {
color: #d4d4d8;
}
html.dark .text-rose-700 {
color: #fb7185;
}
html.dark .text-amber-700 {
color: #fbbf24;
}
html.dark .text-emerald-700 {
color: #34d399;
}
html.dark input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]),
html.dark select,
html.dark textarea {
+31 -31
View File
@@ -79,41 +79,41 @@ module ApplicationHelper
def status_badge(status)
colors = {
"prospect" => "bg-sky-100 text-sky-800",
"active_customer" => "bg-emerald-100 text-emerald-800",
"inactive_customer" => "bg-slate-100 text-slate-700",
"partner" => "bg-violet-100 text-violet-800",
"lost" => "bg-rose-100 text-rose-800"
"prospect" => "bg-sky-100 text-sky-800 dark:bg-sky-950 dark:text-sky-200",
"active_customer" => "bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200",
"inactive_customer" => "bg-slate-100 text-slate-700 dark:bg-zinc-800 dark:text-zinc-300",
"partner" => "bg-violet-100 text-violet-800 dark:bg-violet-950 dark:text-violet-200",
"lost" => "bg-rose-100 text-rose-800 dark:bg-rose-950 dark:text-rose-200"
}
content_tag :span, Catalog.label_for(Catalog::ORGANIZATION_STATUSES, status),
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-slate-100 text-slate-700'}"
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-slate-100 text-slate-700 dark:bg-zinc-800 dark:text-zinc-300'}"
end
def stage_badge(stage)
colors = {
"to_contact" => "bg-slate-100 text-slate-700",
"contacted" => "bg-sky-100 text-sky-800",
"replied" => "bg-cyan-100 text-cyan-800",
"interested" => "bg-amber-100 text-amber-800",
"demo_trial" => "bg-orange-100 text-orange-800",
"first_use" => "bg-lime-100 text-lime-800",
"proposal" => "bg-indigo-100 text-indigo-800",
"won" => "bg-emerald-100 text-emerald-800",
"lost" => "bg-rose-100 text-rose-800"
"to_contact" => "bg-slate-100 text-slate-700 dark:bg-zinc-800 dark:text-zinc-300",
"contacted" => "bg-sky-100 text-sky-800 dark:bg-sky-950 dark:text-sky-200",
"replied" => "bg-cyan-100 text-cyan-800 dark:bg-cyan-950 dark:text-cyan-200",
"interested" => "bg-amber-100 text-amber-800 dark:bg-amber-950 dark:text-amber-200",
"demo_trial" => "bg-orange-100 text-orange-800 dark:bg-orange-950 dark:text-orange-200",
"first_use" => "bg-lime-100 text-lime-800 dark:bg-lime-950 dark:text-lime-200",
"proposal" => "bg-indigo-100 text-indigo-800 dark:bg-indigo-950 dark:text-indigo-200",
"won" => "bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200",
"lost" => "bg-rose-100 text-rose-800 dark:bg-rose-950 dark:text-rose-200"
}
content_tag :span, Catalog.label_for(Catalog::PIPELINE_STAGES, stage),
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[stage] || 'bg-slate-100 text-slate-700'}"
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[stage] || 'bg-slate-100 text-slate-700 dark:bg-zinc-800 dark:text-zinc-300'}"
end
def priority_badge(priority)
colors = {
"low" => "bg-slate-100 text-slate-600",
"normal" => "bg-sky-100 text-sky-700",
"high" => "bg-amber-100 text-amber-800",
"urgent" => "bg-rose-100 text-rose-800"
"low" => "bg-slate-100 text-slate-600 dark:bg-zinc-800 dark:text-zinc-300",
"normal" => "bg-sky-100 text-sky-700 dark:bg-sky-950 dark:text-sky-200",
"high" => "bg-amber-100 text-amber-800 dark:bg-amber-950 dark:text-amber-200",
"urgent" => "bg-rose-100 text-rose-800 dark:bg-rose-950 dark:text-rose-200"
}
content_tag :span, Catalog.label_for(Catalog::TASK_PRIORITIES, priority),
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[priority] || 'bg-slate-100'}"
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[priority] || 'bg-slate-100 text-slate-700 dark:bg-zinc-800 dark:text-zinc-300'}"
end
def format_money(value)
@@ -139,7 +139,7 @@ module ApplicationHelper
end
def progress_bar(percentage, color: "bg-emerald-500")
content_tag :div, class: "h-3 w-full overflow-hidden rounded-full bg-slate-200 dark:bg-zinc-700" do
content_tag :div, class: "h-3 w-full overflow-hidden rounded-full bg-zinc-200 dark:bg-zinc-600" do
content_tag :div, "", class: "h-full #{color} transition-all", style: "width: #{percentage.to_i}%"
end
end
@@ -167,7 +167,7 @@ module ApplicationHelper
"cancelled" => "bg-rose-100 text-rose-800 dark:bg-rose-950 dark:text-rose-200"
}
content_tag :span, Catalog.label_for(Catalog::MAILING_STATUSES, status),
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-zinc-100 text-zinc-700'}"
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-200'}"
end
def mailing_recipient_status_badge(status)
@@ -179,7 +179,7 @@ module ApplicationHelper
"failed" => "bg-rose-100 text-rose-800 dark:bg-rose-950 dark:text-rose-200"
}
content_tag :span, Catalog.label_for(Catalog::MAILING_RECIPIENT_STATUSES, status),
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-zinc-100 text-zinc-700'}"
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-200'}"
end
def mailing_open_badge(recipient)
@@ -203,7 +203,7 @@ module ApplicationHelper
"B" => "bg-fuchsia-100 text-fuchsia-800 dark:bg-fuchsia-950 dark:text-fuchsia-200"
}
content_tag :span, "Test #{variant}",
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[variant] || 'bg-zinc-100 text-zinc-700'}"
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[variant] || 'bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-200'}"
end
def sanitize_email_html(html)
@@ -218,14 +218,14 @@ module ApplicationHelper
return if status.blank?
colors = {
"not_detected" => "bg-zinc-100 text-zinc-700",
"limited" => "bg-amber-100 text-amber-800",
"yes_partial" => "bg-sky-100 text-sky-800",
"yes" => "bg-emerald-100 text-emerald-800",
"yes_sportcam" => "bg-emerald-100 text-emerald-800"
"not_detected" => "bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300",
"limited" => "bg-amber-100 text-amber-800 dark:bg-amber-950 dark:text-amber-200",
"yes_partial" => "bg-sky-100 text-sky-800 dark:bg-sky-950 dark:text-sky-200",
"yes" => "bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200",
"yes_sportcam" => "bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200"
}
content_tag :span, Catalog.label_for(Catalog::STREAMING_STATUSES, status),
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-zinc-100 text-zinc-700'}"
class: "inline-flex items-center rounded-md px-2 py-0.5 text-xs font-medium #{colors[status] || 'bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300'}"
end
def yes_no(value)
+3 -3
View File
@@ -22,11 +22,11 @@
<h2 class="mb-3 text-lg font-semibold">Cosa devo fare oggi</h2>
<div class="grid gap-4 lg:grid-cols-3">
<div>
<h3 class="mb-2 text-sm font-semibold uppercase tracking-wide text-rose-700">In ritardo (<%= @overdue_tasks.size %>)</h3>
<h3 class="mb-2 text-sm font-semibold uppercase tracking-wide text-rose-700 dark:text-rose-400">In ritardo (<%= @overdue_tasks.size %>)</h3>
<%= render "shared/task_list", tasks: @overdue_tasks %>
</div>
<div>
<h3 class="mb-2 text-sm font-semibold uppercase tracking-wide text-amber-700">Da fare oggi (<%= @today_tasks.size %>)</h3>
<h3 class="mb-2 text-sm font-semibold uppercase tracking-wide text-amber-700 dark:text-amber-400">Da fare oggi (<%= @today_tasks.size %>)</h3>
<%= render "shared/task_list", tasks: @today_tasks %>
</div>
<div>
@@ -55,7 +55,7 @@
["Task scaduti", @metrics.overdue_tasks_count]
].each do |label, value| %>
<div class="rounded-xl border border-zinc-200 bg-white text-zinc-900 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-100 p-4">
<div class="text-xs font-medium uppercase tracking-wide text-slate-500"><%= label %></div>
<div class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400"><%= label %></div>
<div class="mt-1 text-2xl font-semibold tabular-nums"><%= value %></div>
</div>
<% end %>
+1 -1
View File
@@ -2,7 +2,7 @@
<h1 class="text-2xl font-semibold">Anteprima import</h1>
<div class="overflow-x-auto rounded-xl border border-zinc-200 bg-white text-zinc-900 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-100">
<table class="min-w-full text-xs">
<thead class="bg-slate-50">
<thead class="bg-zinc-50 dark:bg-zinc-800">
<tr><% @preview[:headers].each do |h| %><th class="px-2 py-2 text-left"><%= h %></th><% end %></tr>
</thead>
<tbody>
+1 -1
View File
@@ -118,7 +118,7 @@
<% if mailing.draft? && mailing.tested? %>
<div class="mt-1 text-xs text-emerald-700 dark:text-emerald-300">Prova ok</div>
<% elsif mailing.draft? %>
<div class="mt-1 text-xs text-zinc-500">Manca prova</div>
<div class="mt-1 text-xs text-amber-700 dark:text-amber-400">Manca prova</div>
<% end %>
</td>
<td class="px-4 py-3 text-sm text-zinc-500">
+1 -1
View File
@@ -96,7 +96,7 @@
<div>
<div class="font-medium">
<%= contact.full_name %>
<% if contact.primary_contact? %><span class="ml-1 rounded bg-emerald-100 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-emerald-800">Principale</span><% end %>
<% if contact.primary_contact? %><span class="ml-1 rounded bg-emerald-100 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200">Principale</span><% end %>
</div>
<div class="break-anywhere text-sm text-slate-500"><%= [contact.role, contact.email, contact.phone.presence || contact.mobile].compact_blank.join(" · ") %></div>
</div>
+6 -6
View File
@@ -1,27 +1,27 @@
<div class="overflow-hidden rounded-xl border border-zinc-200 bg-white text-zinc-900 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-100">
<div class="divide-y divide-zinc-100 dark:divide-zinc-800">
<% tasks.each do |task| %>
<div class="flex flex-col gap-3 px-4 py-3 sm:flex-row sm:items-center <%= 'bg-rose-50' if task.overdue? %> <%= 'bg-amber-50' if task.due_today? %>">
<div class="flex flex-col gap-3 px-4 py-3 sm:flex-row sm:items-center <%= 'bg-rose-50 dark:bg-rose-950' if task.overdue? %> <%= 'bg-amber-50 dark:bg-amber-950' if task.due_today? && !task.overdue? %>">
<div class="min-w-0 flex-1">
<div class="flex flex-wrap items-center gap-2">
<%= link_to task.organization.name, task.organization, class: "font-medium text-zinc-900 hover:underline dark:text-zinc-100" %>
<%= priority_badge(task.priority) %>
<span class="text-xs text-zinc-500"><%= task.task_type_label %></span>
<span class="text-xs text-zinc-500 dark:text-zinc-400"><%= task.task_type_label %></span>
</div>
<div class="mt-0.5 text-sm text-zinc-700 dark:text-zinc-200"><%= task.title %></div>
<div class="mt-0.5 text-xs text-zinc-500">
<div class="mt-0.5 text-xs text-zinc-500 dark:text-zinc-400">
<%= task.contact&.full_name || "—" %> · <%= format_dt(task.due_at) %>
<% if task.assigned_user %>· <%= task.assigned_user.full_name %><% end %>
</div>
</div>
<div class="flex w-full flex-wrap items-center gap-2 sm:w-auto">
<%= button_to "Completa", complete_task_path(task), method: :patch, class: "rounded-md bg-emerald-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-emerald-700" %>
<%= link_to "Modifica", edit_task_path(task), class: "rounded-md border border-zinc-300 px-3 py-1.5 text-xs font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-600 dark:text-zinc-200 dark:hover:bg-zinc-800" %>
<%= button_to "Completa", complete_task_path(task), method: :patch, class: "rounded-md bg-emerald-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-emerald-700 dark:bg-emerald-700 dark:hover:bg-emerald-600" %>
<%= link_to "Modifica", edit_task_path(task), class: "rounded-md border border-zinc-300 bg-white px-3 py-1.5 text-xs font-medium text-zinc-700 hover:bg-zinc-50 dark:border-zinc-500 dark:bg-zinc-700 dark:text-zinc-50 dark:hover:bg-zinc-600" %>
</div>
</div>
<% end %>
<% if tasks.blank? %>
<div class="px-4 py-6 text-center text-sm text-slate-500">Nessun task</div>
<div class="px-4 py-6 text-center text-sm text-zinc-500 dark:text-zinc-400">Nessun task</div>
<% end %>
</div>
</div>
+2 -2
View File
@@ -4,11 +4,11 @@
<%= link_to "Nuovo task", new_task_path, class: "#{btn_primary} w-full sm:w-auto" %>
</div>
<section>
<h2 class="mb-2 text-sm font-semibold uppercase text-rose-700">In ritardo</h2>
<h2 class="mb-2 text-sm font-semibold uppercase text-rose-700 dark:text-rose-400">In ritardo</h2>
<%= render "shared/task_list", tasks: @overdue_tasks %>
</section>
<section>
<h2 class="mb-2 text-sm font-semibold uppercase text-amber-700">Oggi</h2>
<h2 class="mb-2 text-sm font-semibold uppercase text-amber-700 dark:text-amber-400">Oggi</h2>
<%= render "shared/task_list", tasks: @today_tasks %>
</section>
<section>
+2 -2
View File
@@ -5,12 +5,12 @@
</div>
<section>
<h2 class="mb-2 text-sm font-semibold uppercase tracking-wide text-rose-700">In ritardo</h2>
<h2 class="mb-2 text-sm font-semibold uppercase tracking-wide text-rose-700 dark:text-rose-400">In ritardo</h2>
<%= render "shared/task_list", tasks: @overdue_tasks %>
</section>
<section>
<h2 class="mb-2 text-sm font-semibold uppercase tracking-wide text-amber-700">Oggi</h2>
<h2 class="mb-2 text-sm font-semibold uppercase tracking-wide text-amber-700 dark:text-amber-400">Oggi</h2>
<%= render "shared/task_list", tasks: @today_tasks %>
</section>
@@ -23,4 +23,14 @@ class DashboardControllerTest < ActionDispatch::IntegrationTest
assert_match(/Da qui in poi/, response.body)
assert_no_match(/dal passo precedente/, response.body)
end
test "today task rows use dark-mode surfaces" do
login_as users(:admin)
get project_root_path(project_code: "matchlivetv")
assert_response :success
assert_includes response.body, "dark:bg-amber-950"
assert_includes response.body, "dark:bg-amber-950 dark:text-amber-200"
assert_includes response.body, "dark:bg-zinc-700 dark:text-zinc-50"
end
end
+25
View File
@@ -0,0 +1,25 @@
require "test_helper"
class ApplicationHelperTest < ActionView::TestCase
test "priority badge includes dark theme colors" do
html = priority_badge("high")
assert_includes html, "bg-amber-100"
assert_includes html, "dark:bg-amber-950"
assert_includes html, "dark:text-amber-200"
end
test "stage badge includes dark theme colors" do
html = stage_badge("interested")
assert_includes html, "dark:bg-amber-950"
assert_includes html, "dark:text-amber-200"
end
test "status badge includes dark theme colors" do
html = status_badge("prospect")
assert_includes html, "dark:bg-sky-950"
assert_includes html, "dark:text-sky-200"
end
end