<%= progress_percent %>%
diff --git a/app/components/savings/goal_card_component.rb b/app/components/savings/goal_card_component.rb
index 738f5b6a3..554bf862c 100644
--- a/app/components/savings/goal_card_component.rb
+++ b/app/components/savings/goal_card_component.rb
@@ -21,10 +21,11 @@ class Savings::GoalCardComponent < ApplicationComponent
end
def bar_color_class
- case progress_percent
- when 0...25 then "bg-gray-400"
- when 25...75 then "bg-blue-500"
- else "bg-green-600"
+ case goal.status
+ when :reached then "bg-green-500"
+ when :behind then "bg-yellow-500"
+ when :on_track then "bg-blue-500"
+ else "bg-gray-400"
end
end
end
diff --git a/app/components/savings/progress_ring_component.html.erb b/app/components/savings/progress_ring_component.html.erb
index 871fab614..55b313104 100644
--- a/app/components/savings/progress_ring_component.html.erb
+++ b/app/components/savings/progress_ring_component.html.erb
@@ -20,8 +20,8 @@
transform="rotate(-90 <%= Savings::ProgressRingComponent::SIZE / 2.0 %> <%= Savings::ProgressRingComponent::SIZE / 2.0 %>)" />
- <%= percent %>%
- <%= current_label %>
- of <%= target_label %>
+ <%= t("savings_goals.show.ring.saved") %>
+ <%= current_label %>
+ of <%= target_label %>
diff --git a/app/components/savings/progress_ring_component.rb b/app/components/savings/progress_ring_component.rb
index b67f4b9ae..4989f2b1b 100644
--- a/app/components/savings/progress_ring_component.rb
+++ b/app/components/savings/progress_ring_component.rb
@@ -1,5 +1,5 @@
class Savings::ProgressRingComponent < ApplicationComponent
- SIZE = 180
+ SIZE = 220
STROKE = 14
RADIUS = (SIZE - STROKE) / 2.0
CIRCUMFERENCE = 2 * Math::PI * RADIUS
@@ -19,10 +19,11 @@ class Savings::ProgressRingComponent < ApplicationComponent
end
def stroke_color
- case percent
- when 0...25 then "var(--color-gray-400)"
- when 25...75 then "var(--color-blue-500)"
- else "var(--color-green-600)"
+ case goal.status
+ when :reached then "var(--color-green-500)"
+ when :behind then "var(--color-yellow-500)"
+ when :on_track then "var(--color-blue-500)"
+ else "var(--color-gray-400)"
end
end
diff --git a/app/components/savings/status_pill_component.html.erb b/app/components/savings/status_pill_component.html.erb
index 8db06d50a..b1037bb75 100644
--- a/app/components/savings/status_pill_component.html.erb
+++ b/app/components/savings/status_pill_component.html.erb
@@ -1,4 +1,4 @@
-
- <%= helpers.icon(icon_name, size: "xs", color: "current") %>
+
+ <%= helpers.icon(icon_name, size: "sm", color: icon_color) %>
<%= label %>
diff --git a/app/components/savings/status_pill_component.rb b/app/components/savings/status_pill_component.rb
index fa26f5575..bac6d9fdb 100644
--- a/app/components/savings/status_pill_component.rb
+++ b/app/components/savings/status_pill_component.rb
@@ -1,9 +1,9 @@
class Savings::StatusPillComponent < ApplicationComponent
VARIANTS = {
- on_track: { classes: "bg-green-600/10 text-green-700", icon: "check" },
- behind: { classes: "bg-yellow-500/10 text-yellow-700", icon: "alert-triangle" },
- reached: { classes: "bg-green-600/10 text-green-700", icon: "circle-check-big" },
- no_target_date: { classes: "bg-container-inset text-secondary", icon: "calendar-off" }
+ on_track: { classes: "bg-green-500/10 text-success", icon: "check-circle", icon_color: "green" },
+ behind: { classes: "bg-yellow-500/10 text-warning", icon: "alert-triangle", icon_color: "yellow" },
+ reached: { classes: "bg-green-500/10 text-success", icon: "circle-check-big", icon_color: "green" },
+ no_target_date: { classes: "bg-surface-inset text-secondary", icon: "calendar-off", icon_color: "default" }
}.freeze
def initialize(goal:)
@@ -26,6 +26,10 @@ class Savings::StatusPillComponent < ApplicationComponent
variant[:icon]
end
+ def icon_color
+ variant[:icon_color]
+ end
+
def classes
variant[:classes]
end
diff --git a/app/javascript/controllers/savings_goal_stepper_controller.js b/app/javascript/controllers/savings_goal_stepper_controller.js
index 913d5be69..64dd380b4 100644
--- a/app/javascript/controllers/savings_goal_stepper_controller.js
+++ b/app/javascript/controllers/savings_goal_stepper_controller.js
@@ -52,10 +52,13 @@ export default class extends Controller {
}
validateStep1() {
+ const requiredInputs = this.step1PanelTarget.querySelectorAll(
+ 'input[name="savings_goal[name]"], input[name="savings_goal[target_amount]"]'
+ );
let ok = true;
- this.step1FieldTargets.forEach((field) => {
- if (!field.checkValidity()) {
- field.reportValidity();
+ requiredInputs.forEach((input) => {
+ if (typeof input.checkValidity === "function" && !input.checkValidity()) {
+ input.reportValidity();
ok = false;
}
});
@@ -95,11 +98,13 @@ export default class extends Controller {
updateReview() {
if (!this.hasReviewPanelTarget) return;
- if (this.hasReviewNameTarget && this.hasNameFieldTarget) {
- this.reviewNameTarget.textContent = this.nameFieldTarget.value || "—";
+ if (this.hasReviewNameTarget) {
+ const nameInput = this.element.querySelector('input[name="savings_goal[name]"]');
+ this.reviewNameTarget.textContent = nameInput?.value || "—";
}
- if (this.hasReviewAmountTarget && this.hasTargetAmountFieldTarget) {
- this.reviewAmountTarget.textContent = this.targetAmountFieldTarget.value || "—";
+ if (this.hasReviewAmountTarget) {
+ const amountInput = this.element.querySelector('input[name="savings_goal[target_amount]"]');
+ this.reviewAmountTarget.textContent = amountInput?.value || "—";
}
if (this.hasReviewDateTarget) {
const dateInput = this.element.querySelector('input[type="date"][name="savings_goal[target_date]"]');
diff --git a/app/models/demo/generator.rb b/app/models/demo/generator.rb
index 0b35b9a40..1e226f86b 100644
--- a/app/models/demo/generator.rb
+++ b/app/models/demo/generator.rb
@@ -1279,7 +1279,7 @@ class Demo::Generator
end
def generate_savings_goals!(family)
- depository_accounts = family.accounts.depository.visible.to_a
+ depository_accounts = family.accounts.where(accountable_type: "Depository").visible.to_a
return if depository_accounts.empty?
currency = depository_accounts.first.currency
diff --git a/app/views/savings_goals/index.html.erb b/app/views/savings_goals/index.html.erb
index 40489c9c0..5d2da4dd4 100644
--- a/app/views/savings_goals/index.html.erb
+++ b/app/views/savings_goals/index.html.erb
@@ -1,20 +1,20 @@
-<%= content_for :page_title, t(".title") %>
-<%= content_for :page_actions do %>
- <% if @linkable_account_count > 0 %>
- <%= render DS::Link.new(
- text: t(".new_goal"),
- variant: "primary",
- href: new_savings_goal_path,
- icon: "plus",
- frame: :modal
- ) %>
- <% end %>
-<% end %>
+
+
+ <%= t(".title") %>
+ <% if @linkable_account_count > 0 %>
+ <%= render DS::Link.new(
+ text: t(".new_goal"),
+ variant: "primary",
+ href: new_savings_goal_path,
+ icon: "plus",
+ frame: :modal
+ ) %>
+ <% end %>
+
-<% if @savings_goals.empty? && @counts["all"].zero? %>
- <%= render "empty_state", linkable_account_count: @linkable_account_count %>
-<% else %>
-
+ <% if @savings_goals.empty? && @counts["all"].zero? %>
+ <%= render "empty_state", linkable_account_count: @linkable_account_count %>
+ <% else %>
<% SavingsGoalsController::STATE_FILTERS.each do |state| %>
<% active = state == @state_filter %>
@@ -39,5 +39,5 @@
<%= t(".empty_filtered", state: t(".tabs.#{@state_filter}").downcase) %>
<% end %>
-
-<% end %>
+ <% end %>
+