fix(savings_goals/show): chart axis includes backdated contributions, legend uses real colors

projection_payload's start_date was created_at, but demo seeds (and
manual imports) can have contributions backdated before created_at —
those points were getting clipped/pushed left of the chart's x-domain
and the saved-series line couldn't render. Use min(created_at,
earliest contribution date) so the axis spans the full history.

Legend "saved" line stroke was var(--text-primary) which doesn't
resolve (Tailwind utility, not CSS var) → invisible swatch. Wrap in
text-primary span + stroke="currentColor".

Legend "projection" line was hardcoded yellow — chart paints green for
on_track goals → mismatch. Pick legend color based on goal status so
it matches what the chart actually draws.
This commit is contained in:
Guillem Arias
2026-05-11 16:49:47 +02:00
parent 45b2701b4a
commit 6254a02602
2 changed files with 6 additions and 3 deletions

View File

@@ -146,9 +146,11 @@ class SavingsGoal < ApplicationRecord
{ date: c.contributed_at.to_s, value: running.to_f }
end
earliest = [ created_at.to_date, sorted.first&.contributed_at ].compact.min
{
saved_series: saved_series,
start_date: created_at.to_date.to_s,
start_date: earliest.to_s,
today: Date.current.to_s,
target_date: target_date&.to_s,
target_amount: target_amount.to_f,

View File

@@ -182,13 +182,14 @@
<h3 class="text-sm font-medium text-primary"><%= t(".projection.heading") %></h3>
<p class="text-xs text-secondary mt-0.5"><%= @stats[:projection_summary].html_safe %></p>
</div>
<% projection_color = @savings_goal.status == :on_track ? "var(--color-green-600)" : "var(--color-yellow-600)" %>
<div class="flex items-center gap-3 text-[11px] text-secondary shrink-0">
<span class="inline-flex items-center gap-1.5">
<svg width="18" height="6"><line x1="0" y1="3" x2="18" y2="3" stroke="var(--text-primary)" stroke-width="2" /></svg>
<svg width="18" height="6" class="text-primary"><line x1="0" y1="3" x2="18" y2="3" stroke="currentColor" stroke-width="2" /></svg>
<%= t(".projection.legend_saved") %>
</span>
<span class="inline-flex items-center gap-1.5">
<svg width="18" height="6"><line x1="0" y1="3" x2="18" y2="3" stroke="var(--color-yellow-600)" stroke-width="2" stroke-dasharray="3 3" /></svg>
<svg width="18" height="6"><line x1="0" y1="3" x2="18" y2="3" stroke="<%= projection_color %>" stroke-width="2" stroke-dasharray="3 3" /></svg>
<%= t(".projection.legend_projection") %>
</span>
</div>