feat(savings_goals/show): catch-up callout for behind goals

For behind (non-paused) goals with a target_date, render a DS::Alert
warning under the header surfacing the actionable insight from the
index card: "Save $X/mo to catch up · Bump your monthly contribution
to stay on track for <date> · [+ Add $X]".

The CTA prefills the contribution flow with the target monthly amount
in the button label so the user sees exactly what to commit to.

Mirrors the goal-card footer pattern shipped during the index refactor —
the detail page now carries the pace narrative forward instead of
hiding it inside the projection paragraph.
This commit is contained in:
Guillem Arias
2026-05-11 16:02:31 +02:00
parent 8483da1400
commit 89d354e714
2 changed files with 29 additions and 0 deletions

View File

@@ -80,6 +80,30 @@
</div>
</header>
<% if @savings_goal.status == :behind && @savings_goal.monthly_target_amount && !@savings_goal.paused? %>
<%# Catch-up callout %>
<% catch_up_money = Money.new(@savings_goal.monthly_target_amount, @savings_goal.currency) %>
<%= render DS::Alert.new(variant: "warning", title: t("savings_goals.show.catch_up.title", amount: catch_up_money.format)) do %>
<p class="text-secondary">
<% if @savings_goal.target_date %>
<%= t("savings_goals.show.catch_up.body_with_date", date: I18n.l(@savings_goal.target_date, format: :long)) %>
<% else %>
<%= t("savings_goals.show.catch_up.body") %>
<% end %>
</p>
<div class="mt-2">
<%= render DS::Link.new(
text: t("savings_goals.show.catch_up.cta", amount: catch_up_money.format),
variant: "primary",
size: "sm",
href: new_savings_goal_contribution_path(@savings_goal),
icon: "plus",
frame: :modal
) %>
</div>
<% end %>
<% end %>
<%# Top row: ring card + projection chart card %>
<section class="grid grid-cols-1 lg:grid-cols-[320px_minmax(0,1fr)] gap-3">
<div class="bg-container rounded-xl shadow-border-xs p-5 flex flex-col items-center justify-center text-center">

View File

@@ -114,6 +114,11 @@ en:
no_pace: No contributions yet. Add some to start a projection.
behind: At %{current}/mo you'll fall short. Bump to <strong class="text-primary">%{required}/mo</strong> to hit it on time.
on_track: At your current pace, you'll reach this goal around <strong class="text-primary">%{date}</strong>.
catch_up:
title: "Save %{amount}/mo to catch up"
body_with_date: "Bump your monthly contribution to stay on track for %{date}."
body: Bump your monthly contribution to stay on track.
cta: "Add %{amount}"
source:
initial: Initial
manual: Manual