Add family moniker selection and dynamic UI labels (#981)

* Add family moniker selection and dynamic UI labels

Introduce a Family moniker persisted in the database with allowed values Family/Group, add required onboarding selection for it, and thread moniker-aware copy through key user-facing views and locales. Also add helper methods and tests for onboarding form presence and family moniker behavior.

* Small copy edits/change moniker question order

* Conditional Group/Family onboarding flow fixes

* Fix label

* Grouping of fields

* Profile Info page Group/Family changes

* Only admins can change Group/Family moniker

* Repetitive defaults

* Moniker in Account model

* Moniker in User model

* Auth fix

* Sure product is also a moniker

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
Juan José Mata
2026-02-13 19:30:29 +01:00
committed by GitHub
parent d9acf19038
commit 868a0ae4d8
26 changed files with 180 additions and 29 deletions

View File

@@ -74,6 +74,11 @@ class Account < ApplicationRecord
end
class << self
def human_attribute_name(attribute, options = {})
options = { moniker: Current.family&.moniker_label || "Family" }.merge(options)
super(attribute, options)
end
def create_and_sync(attributes, skip_initial_sync: false)
attributes[:accountable_attributes] ||= {} # Ensure accountable is created, even if empty
# Default cash_balance to balance unless explicitly provided (e.g., Crypto sets it to 0)

View File

@@ -17,6 +17,9 @@ class Family < ApplicationRecord
[ "YYYYMMDD", "%Y%m%d" ]
].freeze
MONIKERS = [ "Family", "Group" ].freeze
has_many :users, dependent: :destroy
has_many :accounts, dependent: :destroy
has_many :invitations, dependent: :destroy
@@ -43,6 +46,16 @@ class Family < ApplicationRecord
validates :locale, inclusion: { in: I18n.available_locales.map(&:to_s) }
validates :date_format, inclusion: { in: DATE_FORMATS.map(&:last) }
validates :month_start_day, inclusion: { in: 1..28 }
validates :moniker, inclusion: { in: MONIKERS }
def moniker_label
moniker.presence || "Family"
end
def moniker_label_plural
moniker_label == "Group" ? "Groups" : "Families"
end
def uses_custom_month_start?
month_start_day != 1