From 4bcca3e4aff89b0b0ab459398f739f1507baaa48 Mon Sep 17 00:00:00 2001 From: Guillem Arias Date: Mon, 11 May 2026 21:18:41 +0200 Subject: [PATCH] ux(goals/show): balance-sheet-style funding widget; drop redundant stat row MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lower half of the goal detail used to be: (stat row: monthly pace + total contributions) + (bottom row: contributions list + funding breakdown card). Two of those four pieces were redundant: - Total Contributions stat duplicated the count badge that already sits beside the Contributions heading below. - Monthly Pace stat repeated the same numbers the catch-up alert surfaces above and the chart subtitle reads. Adopt the dashboard Balance Sheet pattern (app/views/pages/dashboard/_ balance_sheet.html.erb) for the funding widget: inline header with total ("Funding accounts · $13,250"), thin gap-separated segment bar, color-dot legend with percent, and a bg-container-inset table with the shared `pages/dashboard/group_weight` 5-stick weight indicator + value column. New show.html.erb bottom: just two full-width sections — funding widget, then chronological contributions list. Both rendered only when the goal has contributions (matches the empty-state branch added earlier). Locale: goals.show.funding_table.{name, weight, value}. --- ...ding_accounts_breakdown_component.html.erb | 74 ++++++++++++++----- app/views/goals/show.html.erb | 54 +++----------- config/locales/views/goals/en.yml | 4 + 3 files changed, 68 insertions(+), 64 deletions(-) diff --git a/app/components/goals/funding_accounts_breakdown_component.html.erb b/app/components/goals/funding_accounts_breakdown_component.html.erb index cc44eb1c4..a40934758 100644 --- a/app/components/goals/funding_accounts_breakdown_component.html.erb +++ b/app/components/goals/funding_accounts_breakdown_component.html.erb @@ -1,27 +1,61 @@ <% if total.zero? %>

<%= t("goals.show.no_contributions_yet") %>

<% else %> -
- <% rows.each do |row| %> - <% next if row[:amount].to_d.zero? %> -
- <% end %> -
+
+

+ <%= t("goals.show.funding_accounts_heading") %> + · + <%= Money.new(total, goal.currency).format(precision: 0) %> +

- +
+ +
+ <% rows.each_with_index do |row, idx| %> +
+
+ <%= render Goals::AvatarComponent.new(name: row[:account].name, color: Goals::AvatarComponent.color_for(row[:account].name), size: "sm") %> +

<%= row[:account].name %>

+
+
+
+ <%= render "pages/dashboard/group_weight", weight: percent_for(row[:amount]), color: Goals::AvatarComponent.color_for(row[:account].name) %> +
+
+

<%= row[:money].format(precision: 0) %>

+
+
+
+ <% if idx < rows.size - 1 %> + <%= render "shared/ruler", classes: "mx-4" %> + <% end %> + <% end %> +
+ + <% end %> diff --git a/app/views/goals/show.html.erb b/app/views/goals/show.html.erb index 9640d0d2f..0faa35cb2 100644 --- a/app/views/goals/show.html.erb +++ b/app/views/goals/show.html.erb @@ -269,44 +269,15 @@ <% end %> - <%# Stat row — combo pace card + contributions count. Reached, paused, - or archived goals hide the pace combo since the comparison is moot - or misleading. %> - <% goal_reached = @goal.completed? || @goal.status == :reached %> - <% hide_pace = goal_reached || @goal.archived? || @goal.paused? %> -
gap-3"> - <% unless hide_pace %> - <%# Combo: Avg vs Target pace %> -
-

<%= t(".stats.monthly_pace") %>

-
-

<%= Money.new(@stats[:avg_monthly], @goal.currency).format %>

-

/mo

-
- <% if @goal.monthly_target_amount && @goal.monthly_target_amount.to_d.positive? %> - <% delta = @goal.monthly_target_amount.to_d - @stats[:avg_monthly].to_d %> - <% if delta.positive? %> -

<%= t(".stats.behind_by", amount: Money.new(delta, @goal.currency).format) %>

- <% else %> -

<%= t(".stats.above_target_pace") %>

- <% end %> - <% else %> -

<%= t(".stats.no_required_pace") %>

- <% end %> -
- <% end %> + <% unless @contributions.empty? %> + <%# Funding breakdown — balance-sheet-style widget (heading · total / + thin bar / dot legend / weight table). %> +
+ <%= render Goals::FundingAccountsBreakdownComponent.new(goal: @goal, rows: @funding_breakdown) %> +
- <%# Total contributions %> -
-

<%= t(".stats.total_contributions") %>

-

<%= @stats[:contributions_count] %>

-

<%= t(".stats.across_all_accounts") %>

-
-
- - <%# Bottom row: contributions + funding accounts %> -
-
+ <%# Contributions — chronological list, full width. %> +

<%= t(".contributions_heading") %>

<%= @contributions.size %> @@ -314,13 +285,8 @@
<%= render "contributions_list", contributions: @contributions %>
-
- -
-

<%= t(".funding_accounts_heading") %>

- <%= render Goals::FundingAccountsBreakdownComponent.new(goal: @goal, rows: @funding_breakdown) %> -
-
+
+ <% end %> <% if @goal.notes.present? %>
diff --git a/config/locales/views/goals/en.yml b/config/locales/views/goals/en.yml index 0eea272ff..7f72d706a 100644 --- a/config/locales/views/goals/en.yml +++ b/config/locales/views/goals/en.yml @@ -94,6 +94,10 @@ en: contributions_heading: Contributions add_contribution: Add contribution funding_accounts_heading: Funding accounts + funding_table: + name: Name + weight: Weight + value: Value no_contributions_yet: No contributions yet. delete_contribution: Delete contribution confirm_delete_contribution: Delete this contribution?