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

@@ -2,6 +2,18 @@ import { Controller } from "@hotwired/stimulus";
// Connects to data-controller="onboarding"
export default class extends Controller {
static targets = ["nameField", "monikerRadio"]
static values = {
householdNameLabel: String,
householdNamePlaceholder: String,
groupNameLabel: String,
groupNamePlaceholder: String
}
connect() {
this.updateNameFieldForCurrentMoniker();
}
setLocale(event) {
this.refreshWithParam("locale", event.target.value);
}
@@ -18,6 +30,30 @@ export default class extends Controller {
document.documentElement.setAttribute("data-theme", event.target.value);
}
updateNameFieldForCurrentMoniker(event = null) {
if (!this.hasNameFieldTarget) {
return;
}
const selectedMonikerRadio = event?.target?.dataset?.onboardingMoniker ? event.target : this.monikerRadioTargets.find((radio) => radio.checked);
const selectedMoniker = selectedMonikerRadio?.dataset?.onboardingMoniker;
const isGroup = selectedMoniker === "Group";
this.nameFieldTarget.placeholder = isGroup ? this.groupNamePlaceholderValue : this.householdNamePlaceholderValue;
const label = this.nameFieldTarget.closest(".form-field")?.querySelector(".form-field__label");
if (!label) {
return;
}
if (isGroup) {
label.textContent = this.groupNameLabelValue;
return;
}
label.textContent = this.householdNameLabelValue;
}
refreshWithParam(key, value) {
const url = new URL(window.location);
url.searchParams.set(key, value);