From 33189c2673e38f4db390f1cc953ae14a1254410e Mon Sep 17 00:00:00 2001 From: Guillem Arias Date: Fri, 15 May 2026 13:25:03 +0200 Subject: [PATCH] ux(goals): polish detail page + unbreak render - Fix render-blocker: Money#symbol doesn't exist (use #currency.symbol). - Sanitize projection_summary so the _html locale renders markup instead of escaping it. - Switch donut + card ring track to --budget-unused-fill; --budget-unallocated-fill resolves to the same gray as bg-surface in light mode so the unfilled arc was invisible on the detail page. - Mobile detail: drop avatar, right-align action buttons, stack projection header (subtitle + legend) so the subtitle reads on one line; bump legend gap on mobile. - Nowrap the projected reach-date so e.g. "Jul 2026" stays together. --- app/components/goals/card_component.html.erb | 2 +- .../controllers/goal_projection_chart_controller.js | 4 ++-- app/models/goal.rb | 8 ++++---- app/views/goals/show.html.erb | 12 +++++++----- config/locales/views/goals/en.yml | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/components/goals/card_component.html.erb b/app/components/goals/card_component.html.erb index cc5b6f43f..df05906f4 100644 --- a/app/components/goals/card_component.html.erb +++ b/app/components/goals/card_component.html.erb @@ -24,7 +24,7 @@ cy="<%= Goals::CardComponent::RING_SIZE / 2.0 %>" r="<%= ring_radius %>" fill="none" - stroke="var(--budget-unallocated-fill)" + stroke="var(--budget-unused-fill)" stroke-width="<%= Goals::CardComponent::RING_STROKE %>" /> = 1_000_000 short = (amount_f / 1_000_000.0).round(1) diff --git a/app/views/goals/show.html.erb b/app/views/goals/show.html.erb index 8411afc33..ba697b0e2 100644 --- a/app/views/goals/show.html.erb +++ b/app/views/goals/show.html.erb @@ -1,7 +1,9 @@
- <%= render Goals::AvatarComponent.new(goal: @goal, size: "xl") %> +

<%= @goal.name %>

@@ -16,7 +18,7 @@ <% end %>
-
+
<% unless @goal.completed? || @goal.status == :reached %> <%# Demote to outline when the catch-up alert below owns the primary action. One primary per surface. %> @@ -217,13 +219,13 @@
<% else %>
-
+

<%= t(".projection.heading") %>

-

<%= @goal.projection_summary %>

+

<%= sanitize @goal.projection_summary %>

<% projection_color = @goal.status == :on_track ? "var(--color-green-600)" : "var(--color-yellow-600)" %> -
+
<%= t(".projection.legend_saved") %> diff --git a/config/locales/views/goals/en.yml b/config/locales/views/goals/en.yml index 05bd65b9e..0c65ea36e 100644 --- a/config/locales/views/goals/en.yml +++ b/config/locales/views/goals/en.yml @@ -137,7 +137,7 @@ en: no_target_date: No target date set. Set one to project a finish line. no_pace: No deposits yet. Add money to a linked account to start a projection. behind: Falling short at current pace. - on_track_html: At your current pace, you'll reach this goal around %{date}. + on_track_html: At your current pace, you'll reach this goal around %{date}. aria_label: "Projection chart for %{name}" catch_up: title: "Save %{amount}/mo more to catch up"