feat(savings_goals): drop Accounts section from index

The Accounts grid duplicated the sidebar account list. Removing it gives
the Goals section more breathing room and the page a tighter narrative:
header → KPIs → Goals.

Delete Savings::AccountCardComponent, Family#savings_subtype_accounts,
the @savings_accounts / @account_goal_counts controller refs, and the
related locale keys. Sidebar still shows the savings-subtype Depository
accounts under "Cash" — no information is lost.
This commit is contained in:
Guillem Arias
2026-05-11 14:23:00 +02:00
parent 3e05ea8670
commit f51e38f4fc
6 changed files with 1 additions and 81 deletions

View File

@@ -1,16 +0,0 @@
<div class="bg-container rounded-xl shadow-border-xs p-6">
<div class="flex items-center gap-3 mb-3">
<span class="inline-flex items-center justify-center w-9 h-9 rounded-full text-inverse text-sm font-semibold"
style="background-color: var(--color-blue-500);">
<%= initial %>
</span>
<div class="min-w-0 flex-1">
<p class="text-sm font-medium text-primary truncate"><%= account.name %></p>
<p class="text-xs text-secondary"><%= subtype_label %></p>
</div>
</div>
<p class="text-2xl font-medium text-primary tabular-nums privacy-sensitive">
<%= Money.new(account.balance, account.currency).format %>
</p>
<p class="text-xs text-subdued mt-1"><%= funds_label %></p>
</div>

View File

@@ -1,20 +0,0 @@
class Savings::AccountCardComponent < ApplicationComponent
def initialize(account:, goals_count: 0)
@account = account
@goals_count = goals_count
end
attr_reader :account, :goals_count
def initial
account.name.to_s.strip.first&.upcase || "?"
end
def subtype_label
(account.subtype || "savings").to_s.titleize
end
def funds_label
I18n.t("savings_goals.index.account_card.funds", count: goals_count)
end
end

View File

@@ -15,8 +15,6 @@ class SavingsGoalsController < ApplicationController
@completed_goals = all_goals.select { |g| g.state == "completed" }
@linkable_account_count = Current.family.accounts.where(accountable_type: "Depository").visible.count
@savings_accounts = Current.family.savings_subtype_accounts
@account_goal_counts = goal_count_per_account(@savings_accounts)
@kpi = kpi_payload(@active_goals)
@show_search = @active_goals.size > 6
end
@@ -195,17 +193,6 @@ class SavingsGoalsController < ApplicationController
}
end
def goal_count_per_account(accounts)
return {} if accounts.empty?
SavingsGoalAccount
.where(account_id: accounts.map(&:id))
.joins(:savings_goal)
.where.not(savings_goals: { state: %w[archived] })
.group(:account_id)
.count
end
def stats_for(goal)
avg = goal.average_monthly_contribution.to_d
sub_avg = if goal.monthly_target_amount && goal.monthly_target_amount.to_d > avg

View File

@@ -45,15 +45,6 @@ class Family < ApplicationRecord
has_many :savings_goals, dependent: :destroy
has_many :savings_contributions, through: :savings_goals
# Depository accounts with subtype = "savings". The /savings_goals
# index hero shows the total + sparkline across just these accounts;
# checking / HSA / CD / money-market are intentionally excluded.
def savings_subtype_accounts
accounts.where(accountable_type: "Depository").visible.alphabetically.select do |account|
account.subtype == "savings"
end
end
# Sum of contribution amounts within the given date range, returned as
# a BigDecimal in the family's primary currency. Powers the savings
# goals "Contributed · last 30d" KPI.

View File

@@ -4,7 +4,7 @@
<p class="text-sm text-secondary mt-1"><%= t(".subtitle") %></p>
</header>
<% if @counts["all"].zero? && @savings_accounts.empty? %>
<% if @counts["all"].zero? %>
<%= render "empty_state", linkable_account_count: @linkable_account_count %>
<% else %>
<%# KPI strip %>
@@ -67,21 +67,6 @@
</div>
</section>
<%# Accounts section %>
<% if @savings_accounts.any? %>
<section>
<div class="mb-3">
<h2 class="text-base font-semibold text-primary"><%= t(".accounts_section.heading") %></h2>
<p class="text-sm text-secondary"><%= t(".accounts_section.subtitle") %></p>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<% @savings_accounts.each do |account| %>
<%= render Savings::AccountCardComponent.new(account: account, goals_count: @account_goal_counts[account.id] || 0) %>
<% end %>
</div>
</section>
<% end %>
<%# Goals section %>
<section data-controller="savings-goals-filter"
data-savings-goals-filter-empty-query-value="<%= t(".search.empty_with_query", query: "__QUERY__") %>"

View File

@@ -30,9 +30,6 @@ en:
one: 1 paused
other: "%{count} paused"
on_track_sub_all_good: All active goals on pace
accounts_section:
heading: Accounts
subtitle: Your savings and emergency reserves
goals_section:
heading: Goals
subtitle: Save toward what matters.
@@ -55,10 +52,6 @@ en:
behind: Behind
no_target_date: Open-ended
paused: Paused
account_card:
funds:
one: Funds 1 goal
other: "Funds %{count} goals"
new:
heading: New savings goal
step1_subtitle: Step 1 of 2 · Goal details