diff --git a/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.html b/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.html
index aed5701f6..6f0e42cf2 100644
--- a/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.html
+++ b/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.html
@@ -88,7 +88,9 @@
-
+
+ @if (form().get('organization')?.errors?.['required'] && form().get('organization')?.touched) {
+
Organization name is required
+ }
+ @if (form().get('organization_url')?.errors?.['required'] && form().get('organization_url')?.touched) {
+
Organization website is required
+ }
+ @if (form().get('organization_url')?.errors?.['pattern'] && form().get('organization_url')?.touched) {
+
Please enter a valid URL
+ }
diff --git a/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.ts b/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.ts
index 3688156b2..3deb7b992 100644
--- a/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.ts
+++ b/apps/lfx-one/src/app/modules/committees/components/member-form/member-form.component.ts
@@ -9,7 +9,7 @@ import { CalendarComponent } from '@components/calendar/calendar.component';
import { InputTextComponent } from '@components/input-text/input-text.component';
import { OrganizationSearchComponent } from '@components/organization-search/organization-search.component';
import { SelectComponent } from '@components/select/select.component';
-import { APPOINTED_BY_OPTIONS, LINKEDIN_PROFILE_PATTERN, MEMBER_ROLES, VOTING_STATUSES } from '@lfx-one/shared/constants';
+import { APPOINTED_BY_OPTIONS, LINKEDIN_PROFILE_PATTERN, MEMBER_ROLES, VOTING_STATUSES, WEBSITE_URL_PATTERN } from '@lfx-one/shared/constants';
import { Committee, CommitteeMember, CreateCommitteeMemberRequest, MemberFormValue } from '@lfx-one/shared/interfaces';
import { formatDateToISOString, parseISODateString } from '@lfx-one/shared/utils';
import { CommitteeService } from '@services/committee.service';
@@ -43,6 +43,11 @@ export class MemberFormComponent {
// Wizard mode: returns data instead of calling API (used when committee doesn't exist yet)
public readonly wizardMode: boolean;
+ // Organization fields are required when voting is enabled OR business email is required
+ public get orgRequired(): boolean {
+ return !!(this.committee?.enable_voting || this.committee?.business_email_required);
+ }
+
// Member options
public roleOptions = MEMBER_ROLES;
public votingStatusOptions = VOTING_STATUSES;
@@ -205,8 +210,8 @@ export class MemberFormComponent {
email: new FormControl('', [Validators.required, Validators.email]),
job_title: new FormControl(''),
linkedin_profile: new FormControl('', [Validators.pattern(LINKEDIN_PROFILE_PATTERN)]),
- organization: new FormControl(''),
- organization_url: new FormControl(''),
+ organization: new FormControl('', this.orgRequired ? [Validators.required] : []),
+ organization_url: new FormControl('', this.orgRequired ? [Validators.required, Validators.pattern(WEBSITE_URL_PATTERN)] : [Validators.pattern(WEBSITE_URL_PATTERN)]),
role: new FormControl('', this.committee?.enable_voting ? [Validators.required] : []),
voting_status: new FormControl('', this.committee?.enable_voting ? [Validators.required] : []),
appointed_by: new FormControl(''),
diff --git a/packages/shared/src/constants/validation.constants.ts b/packages/shared/src/constants/validation.constants.ts
index fd1743ec5..8da96649c 100644
--- a/packages/shared/src/constants/validation.constants.ts
+++ b/packages/shared/src/constants/validation.constants.ts
@@ -27,3 +27,6 @@
* - linkedin.com (missing path)
*/
export const LINKEDIN_PROFILE_PATTERN = /^(https?:\/\/)?([a-z]{2,3}\.)?linkedin\.com\/.*$/;
+
+/** Website URL pattern matching the upstream backend validation */
+export const WEBSITE_URL_PATTERN = /^(https?:\/\/)?[^\s/$.?#].[^\s]*$/;