mirror of
https://github.com/we-promise/sure.git
synced 2026-05-30 15:59:02 +00:00
Functional data-entry surface on the (still preview) /retirement page. The polished combined-page UI is PR4; this ships plain forms + lists so a preview user can populate a plan end to end. - RetirementScoped concern: tier-1 preview gate + tier-2 family killswitch + per-owner plan bootstrap (Goal::Retirement.for_owner find-or-creates, so children always have a parent). RetirementController now uses it. - Nested controllers under Retirement::: PensionSources (full CRUD), Statements (new/create + soft-delete destroy — append-only audit), Adjustments (full CRUD), Buckets (replace-all account selection, same-family filtered). All scoped to the current user's own plan, so cross-user access is impossible by construction. - Routes nested under `resource :retirement` via `scope module:`. - Views: show page rewritten into management sections (sources, adjustments, bucket checkboxes, statement journal) + plain styled_form_with forms. Money carries privacy-sensitive. - Goal gains a target_amount_required? hook (true); Goal::Retirement overrides it false — the forecast owns the target (PR3), so a plan can exist before any target is set. - EN locale for the new surface. 111 controller+model tests green. Note: delete uses Turbo confirm for now; PR4 swaps in the skinned DS::Dialog per the design.
26 lines
1.4 KiB
Plaintext
26 lines
1.4 KiB
Plaintext
<%# locals: (statement:, pension_sources:) %>
|
|
<%= styled_form_with model: statement, url: retirement_statements_path, method: :post, class: "space-y-4" do |f| %>
|
|
<% if statement.errors.any? %>
|
|
<div class="text-destructive text-sm space-y-1">
|
|
<% statement.errors.full_messages.each do |message| %><p><%= message %></p><% end %>
|
|
</div>
|
|
<% end %>
|
|
|
|
<%= f.collection_select :pension_source_id, pension_sources, :id, :name, { label: t("retirement.statements.form.pension_source") } %>
|
|
<%= f.date_field :received_on, label: t("retirement.statements.form.received_on"), required: true %>
|
|
<%= f.money_field :projected_monthly_amount, currency_method: :projected_currency, label: t("retirement.statements.form.projected_monthly_amount"), required: true %>
|
|
|
|
<div class="grid grid-cols-2 gap-3">
|
|
<%= f.number_field :projected_at_age, label: t("retirement.statements.form.projected_at_age") %>
|
|
<%= f.number_field :current_points, step: "0.01", label: t("retirement.statements.form.current_points") %>
|
|
</div>
|
|
|
|
<%= f.text_field :raw_source_doc, label: t("retirement.statements.form.raw_source_doc") %>
|
|
<%= f.text_area :notes, rows: 2, label: t("retirement.statements.form.notes") %>
|
|
|
|
<div class="flex items-center justify-end gap-3 pt-2">
|
|
<%= link_to t("retirement.statements.form.cancel"), retirement_path, class: "text-sm text-secondary" %>
|
|
<%= f.submit t("retirement.statements.form.save") %>
|
|
</div>
|
|
<% end %>
|