mirror of
https://github.com/we-promise/sure.git
synced 2026-04-17 02:54:10 +00:00
* Add budget rollover: copy from previous month When navigating to an uninitialized budget month, show a prompt offering to copy amounts from the most recent initialized budget. Copies budgeted_spending, expected_income, and all matching category allocations. Also fixes over-allocation warning showing on uninitialized budgets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Redirect copy_previous to categories wizard for review Matches the normal budget setup flow (edit → categories → show) so users can review/tweak copied allocations before confirming. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Address code review: eager-load categories, guard against overwrite - Add .includes(:budget_categories) to most_recent_initialized_budget to avoid N+1 when copy_from! iterates source categories - Guard copy_previous action against overwriting already-initialized budgets (prevents crafted POST from clobbering existing data) - Add i18n key for already_initialized flash message Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add invariant guards to copy_from! for defensive safety Validate that source budget belongs to the same family and precedes the target budget before copying. Protects against misuse from other callers beyond the controller. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix button overflow on small screens in copy previous prompt Stack buttons vertically on mobile, side-by-side on sm+ breakpoint. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
27 lines
887 B
Plaintext
27 lines
887 B
Plaintext
<%# locals: (budget:, source_budget:) %>
|
|
|
|
<div class="flex flex-col gap-4 items-center justify-center h-full">
|
|
<%= icon "copy", size: "lg" %>
|
|
|
|
<div class="text-center">
|
|
<p class="text-primary font-medium"><%= t("budgets.copy_previous_prompt.title") %></p>
|
|
<p class="text-secondary text-sm mt-1"><%= t("budgets.copy_previous_prompt.description", source_name: source_budget.name) %></p>
|
|
</div>
|
|
|
|
<div class="flex flex-col sm:flex-row items-center gap-2">
|
|
<%= render DS::Button.new(
|
|
text: t("budgets.copy_previous_prompt.copy_button", source_name: source_budget.name),
|
|
href: copy_previous_budget_path(budget),
|
|
method: :post,
|
|
icon: "copy"
|
|
) %>
|
|
|
|
<%= render DS::Link.new(
|
|
text: t("budgets.copy_previous_prompt.fresh_button"),
|
|
variant: "secondary",
|
|
icon: "plus",
|
|
href: edit_budget_path(budget)
|
|
) %>
|
|
</div>
|
|
</div>
|