From d601682c00013d7378d94146042d85ddb9f5bce7 Mon Sep 17 00:00:00 2001 From: Tushar Verma Date: Mon, 2 Feb 2026 08:50:03 +0530 Subject: [PATCH 1/8] Add StudioEmailField and StudioPasswordField components --- .../components/form/StudioEmailField.vue | 72 +++++++++++++++++++ .../components/form/StudioPasswordField.vue | 64 +++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 contentcuration/contentcuration/frontend/accounts/components/form/StudioEmailField.vue create mode 100644 contentcuration/contentcuration/frontend/accounts/components/form/StudioPasswordField.vue diff --git a/contentcuration/contentcuration/frontend/accounts/components/form/StudioEmailField.vue b/contentcuration/contentcuration/frontend/accounts/components/form/StudioEmailField.vue new file mode 100644 index 0000000000..c4a9fe1095 --- /dev/null +++ b/contentcuration/contentcuration/frontend/accounts/components/form/StudioEmailField.vue @@ -0,0 +1,72 @@ + + + + + + + diff --git a/contentcuration/contentcuration/frontend/accounts/components/form/StudioPasswordField.vue b/contentcuration/contentcuration/frontend/accounts/components/form/StudioPasswordField.vue new file mode 100644 index 0000000000..d3ae6d6c2c --- /dev/null +++ b/contentcuration/contentcuration/frontend/accounts/components/form/StudioPasswordField.vue @@ -0,0 +1,64 @@ + + + + + + + From e29609963e70e3ea6d5882492ad43e3f59d23ade Mon Sep 17 00:00:00 2001 From: Tushar Verma Date: Mon, 2 Feb 2026 09:36:53 +0530 Subject: [PATCH 2/8] add custom validateForm method and replaced basic fields with new components and added emailValidateMessage translation --- .../frontend/accounts/pages/Create.vue | 128 ++++++++++++++---- 1 file changed, 104 insertions(+), 24 deletions(-) diff --git a/contentcuration/contentcuration/frontend/accounts/pages/Create.vue b/contentcuration/contentcuration/frontend/accounts/pages/Create.vue index 12074ef1ea..f11438c1e1 100644 --- a/contentcuration/contentcuration/frontend/accounts/pages/Create.vue +++ b/contentcuration/contentcuration/frontend/accounts/pages/Create.vue @@ -46,43 +46,45 @@

{{ $tr('basicInformationHeader') }}

- - - - - @@ -231,8 +233,9 @@ import { mapActions, mapGetters, mapState } from 'vuex'; import { uses, sources } from '../constants'; import TextField from 'shared/views/form/TextField'; - import EmailField from 'shared/views/form/EmailField'; - import PasswordField from 'shared/views/form/PasswordField'; + import KTextbox from 'kolibri-design-system/lib/KTextbox'; + import StudioEmailField from '../components/form/StudioEmailField'; + import StudioPasswordField from '../components/form/StudioPasswordField'; import TextArea from 'shared/views/form/TextArea'; import CountryField from 'shared/views/form/CountryField'; import PolicyModals from 'shared/views/policies/PolicyModals'; @@ -249,8 +252,9 @@ DropdownWrapper, ImmersiveModalLayout, TextField, - EmailField, - PasswordField, + KTextbox, + StudioEmailField, + StudioPasswordField, TextArea, CountryField, PolicyModals, @@ -480,10 +484,85 @@ showOtherField(id) { return id === uses.OTHER && this.form.uses.includes(id); }, + validateForm() { + // Custom validation to replace Vuetify form validation + let isValid = true; + + // Reset all errors first + this.errors = { + first_name: null, + last_name: null, + email: null, + password1: null, + password2: null, + uses: null, + locations: null, + source: null, + }; + + // Validate first name + if (!this.form.first_name || this.form.first_name.trim() === '') { + this.errors.first_name = commonStrings.$tr('fieldRequired'); + isValid = false; + } + + // Validate last name + if (!this.form.last_name || this.form.last_name.trim() === '') { + this.errors.last_name = commonStrings.$tr('fieldRequired'); + isValid = false; + } + + // Validate email + if (!this.form.email || this.form.email.trim() === '') { + this.errors.email = commonStrings.$tr('fieldRequired'); + isValid = false; + } else if (!/\S+@\S+\.\S+/.test(this.form.email)) { + this.errors.email = this.$tr('emailValidationMessage'); + isValid = false; + } + + // Validate password1 + if (!this.form.password1) { + this.errors.password1 = commonStrings.$tr('fieldRequired'); + isValid = false; + } else if (this.form.password1.length < 8) { + this.errors.password1 = this.$tr('passwordValidationMessage'); + isValid = false; + } + + // Validate password2 (confirmation) + if (!this.form.password2) { + this.errors.password2 = commonStrings.$tr('fieldRequired'); + isValid = false; + } else if (this.form.password1 !== this.form.password2) { + this.errors.password2 = this.$tr('passwordMatchMessage'); + isValid = false; + } + + // Validate usage selection + if (!this.form.uses || this.form.uses.length === 0) { + this.errors.uses = commonStrings.$tr('fieldRequired'); + isValid = false; + } + + // Validate location selection + if (!this.form.locations || this.form.locations.length === 0) { + this.errors.locations = commonStrings.$tr('fieldRequired'); + isValid = false; + } + + // Validate source selection + if (!this.form.source) { + this.errors.source = commonStrings.$tr('fieldRequired'); + isValid = false; + } + + return isValid; + }, submit() { // We need to check the "acceptedAgreement" here explicitly because it is not a // Vuetify form field and does not trigger the form validation. - if (this.$refs.form.validate() && this.acceptedAgreement) { + if (this.validateForm() && this.acceptedAgreement) { // Prevent double submission if (this.submitting) { return Promise.resolve(); @@ -551,6 +630,7 @@ firstNameLabel: 'First name', lastNameLabel: 'Last name', emailExistsMessage: 'An account with this email already exists', + emailValidationMessage: 'Please enter a valid email address', passwordLabel: 'Password', confirmPasswordLabel: 'Confirm password', passwordMatchMessage: "Passwords don't match", From 5cbe5cc67cf9a8c54a109c873eeff47980a5cb06 Mon Sep 17 00:00:00 2001 From: Tushar Verma Date: Mon, 2 Feb 2026 09:58:47 +0530 Subject: [PATCH 3/8] Refactor usage fields to use KCheckbox and KTextbox components, and implement toggleUsage method for form handling --- .../frontend/accounts/pages/Create.vue | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/contentcuration/contentcuration/frontend/accounts/pages/Create.vue b/contentcuration/contentcuration/frontend/accounts/pages/Create.vue index f11438c1e1..ff0a0cd497 100644 --- a/contentcuration/contentcuration/frontend/accounts/pages/Create.vue +++ b/contentcuration/contentcuration/frontend/accounts/pages/Create.vue @@ -99,26 +99,30 @@ v-for="option in usageOptions" :key="option.id" > - - - + -