Component Name: myBusinessAccount¶
Last Updated: 2025-09-29 Source Code: https://bitbucket.org/i2cinc/i2c.salesforce.metadata/src/STAGING/force-app/main/default/lwc/myBusinessAccount
API Name: c-myBusinessAccount Type: Page Component Target: lightningCommunity__Page, lightningCommunity__Default, lightning__AppPage, lightning__RecordPage
Business Purpose¶
This component provides a comprehensive business account management interface for AANP business/corporate members. It allows business account holders to view and update their account information, manage contact details, view orders and receipts, handle data sharing agreements with AANPCB, and manage subscriptions.
User Interface¶
Visual Description¶
- Layout: Single-column responsive layout with expandable accordion sections
- Key UI Elements: Avatar with photo upload, collapsible information sections, modal dialogs for editing, form inputs with validation
- Responsive: Fully responsive design adapting from mobile (stacked) to desktop (side-by-side) layouts
Screenshots¶
- Desktop view: Full-width accordion with side-by-side field display
- Mobile view: Stacked layout with full-width sections
Component Structure¶
Files¶
myBusinessAccount.html- Template/markupmyBusinessAccount.js- JavaScript controller (1078 lines)myBusinessAccount.js-meta.xml- Metadata configurationphoneCountryCodes.js- Phone country code mapping utility
HTML Template Structure¶
<template>
<section class="container my-account-container">
<div class="bg-white box">
<div class="avatar"><!-- Profile photo --></div>
<h2>Account Name</h2>
<div>Membership Type and Dues Info</div>
</div>
<!-- Accordion Sections -->
<div class="accordion-item" data-tab="myAccount">
<!-- My Account Information -->
</div>
<div class="accordion-item" data-tab="myAddresses">
<!-- My Addresses & Phone -->
</div>
<div class="accordion-item" data-tab="myOrders">
<!-- My Orders/Receipts -->
</div>
<!-- Modals for editing -->
<div class="modal" data-id="addCredentials">...</div>
<div class="modal" data-id="updateDataSharingAgreement">...</div>
<div class="modal" data-id="addPreferredAddress">...</div>
<div class="modal" data-id="editPhone">...</div>
</section>
</template>
Key Template Features: - Conditional rendering with lwc:if for showing/hiding sections - Multiple modal dialogs for different edit operations - Integration with child components (c-my-np-profile-display-field, c-my-np-profile-edit-modal, c-intl-tel-input, c-form-input, c-my-orders-receipts-tab) - File input for photo upload - Country/state picklist fields with dependent logic
JavaScript Controller¶
Properties (API)¶
@api userInfo¶
- Type:
Object - Required: No
- Default: undefined
- Description: User information object (can be passed in but also loaded via wire)
Example Usage:
@api accountType¶
- Type:
String - Required: No
- Default: 'Person'
- Description: Type of account being displayed (defaults to Person but component is designed for Business accounts)
Tracked Properties¶
@track accountInfo¶
- Type:
Object - Purpose: Stores all account field values for display and editing
- Updated When: On load from wire, and after successful updates
@track isLoading¶
- Type:
Boolean - Purpose: Controls loading spinner display during save operations
- Updated When: Set to true before Apex calls, false after completion
@track basePath¶
- Type:
String - Purpose: Stores community base path for navigation
- Updated When: Set in connectedCallback
Wire Adapters¶
@wire(getUserInfo, {"accountType":"business"})¶
@wire(getUserInfo,{"accountType":"business"})
wiredUserInfo({ error, data }) {
if (data) {
this.currentUser = data;
this.userInfoLoaded = true;
this.initializeComponentProperties();
}
}
Purpose: Retrieves current user and account information for business accounts Fields Retrieved: Full Account object with all business account fields Error Handling: Logs errors to console, sets userInfoLoaded flag
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })¶
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
handleObjectInfo({ error, data }) {
// Retrieves Business Account record type ID
}
Purpose: Gets Account object metadata to find Business Account record type Error Handling: Logs to console
@wire(getPicklistValues, { recordTypeId: "$accountRecordTypeId", fieldApiName: COUNTRY_CODE_FIELD })¶
@wire(getPicklistValues, { recordTypeId: '$accountRecordTypeId', fieldApiName: COUNTRY_CODE_FIELD })
wiredCountryPicklistValues({ error, data }) {
// Loads and sorts country picklist values
}
Purpose: Loads country picklist values with US and CA prioritized Error Handling: Logs errors to console
@wire(getPicklistValues, { recordTypeId: "$accountRecordTypeId", fieldApiName: STATE_CODE_FIELD })¶
Purpose: Loads state/province picklist values Dependencies: Depends on country selection
@wire(getPicklistValues, { recordTypeId: "$accountRecordTypeId", fieldApiName: NUMBER_OF_INDIVIDUALS_FIELD })¶
@wire(getPicklistValues, { recordTypeId: "$accountRecordTypeId", fieldApiName: NUMBER_OF_INDIVIDUALS_FIELD })
numberOfIndividualsResults({ error, data }) {
// Loads Number of Individuals picklist
}
Purpose: Loads picklist values for Number of Individuals field Error Handling: Sets undefined on error
@wire(getProductCategoryIdByName, { categoryName: 'Communities' })¶
@wire(getProductCategoryIdByName, { categoryName: 'Communities' })
wiredCategory({ error, data }) {
// Gets Communities category ID for navigation
}
Purpose: Retrieves product category ID for Communities to enable navigation Error Handling: Logs errors to console
Public Methods¶
None - component does not expose public methods
Event Handlers¶
toggleSection¶
toggleSection(event) {
const sectionId = event.currentTarget.dataset.tab;
// Expands/collapses accordion sections
}
Triggered By: Click on accordion header Event Type: click Event Detail: dataset.tab contains section ID Action: Toggles max-height CSS and arrow rotation
openModal¶
openModal(event) {
const itemId = event.currentTarget.dataset.item;
// Opens specific modal dialog
}
Triggered By: Click on edit buttons Event Type: click Event Detail: dataset.item contains modal ID Action: Shows modal and backdrop
closeModal¶
closeModal(event) {
const buttonId = event.currentTarget.dataset.close;
// Closes specific modal dialog
}
Triggered By: Click on cancel/close buttons Event Type: click Event Detail: dataset.close contains modal ID Action: Hides modal and backdrop
handleFileChange¶
handleFileChange(event) {
const file = event.target.files[0];
// Converts file to base64 and uploads
}
Triggered By: File input change Event Type: change Event Detail: File object Action: Reads file, converts to base64, calls uploadFile()
handleInputChange¶
handleInputChange(event) {
const value = event.target?.value;
this.accountInfo[event.target.name] = value;
}
Triggered By: Input field changes Event Type: change Event Detail: Input value Action: Updates accountInfo tracked property
handleCustomInputChange¶
handleCustomInputChange(event) {
const { fieldName, value } = event.detail;
// Handles custom input component events
}
Triggered By: Custom c-form-input component Event Type: inputchange (custom) Event Detail: { fieldName, value } Action: Updates accountInfo, handles multi-line address fields
handleAddressChangeSubmit¶
Triggered By: Address form submission Event Type: submit Action: Validates form, calls upsertAccount, closes modal
handleEditPhoneSubmit¶
Triggered By: Phone form submission Event Type: submit Action: Validates phone number, calls upsertAccount, closes modal
handleCredentialsSubmit¶
Triggered By: Credentials form submission Event Type: submit Action: Calls upsertAccount with credentials, closes modal
handleCountryChange¶
Triggered By: Country combobox selection Event Type: change Event Detail: Selected country code Action: Updates state options, determines if state is required
optInDataSharingAgreement¶
Triggered By: Button click in data sharing modal Event Type: click Action: Updates Account with opt-in, timestamp, and version
optOutDataSharingAgreement¶
Triggered By: Button click in opt-out modal Event Type: click Action: Updates Account with opt-out, timestamp, and version
Private Methods¶
initializeComponentProperties¶
Purpose: Initializes component data from currentUser Called By: wiredUserInfo after successful data load
mapAccountData¶
Purpose: Maps Account fields to accountInfo tracked property Called By: initializeComponentProperties
handleImage¶
Purpose: Decodes and displays account photo from Photo__c field Called By: initializeComponentProperties after file server URL is retrieved
decodeImageFromRecord¶
Purpose: Extracts image URL from Photo__c HTML field Called By: Internal helper
uploadFile¶
Purpose: Uploads selected profile photo to server Called By: handleFileChange after file is converted to base64
refreshPage¶
Purpose: Reloads entire page after photo upload Called By: uploadFile after successful upload
displayToastMessage¶
Purpose: Shows toast notification Called By: Various methods for success/error feedback
validateChangeAddressForm¶
Purpose: Validates all form inputs in address change modal Called By: handleAddressChangeSubmit
validateComboboxes¶
Purpose: Validates country and state combobox selections Called By: Internal validation logic
validatePhoneNumber¶
Purpose: Validates phone number using c-intl-tel-input component Called By: handleEditPhoneSubmit
toggleBackdrop¶
Purpose: Shows/hides modal backdrop Called By: openModal, closeModal
saveInfo¶
Purpose: Generic save handler for profile edit modal Called By: onsaveinfo event from c-my-np-profile-edit-modal
closeModalByDataClose¶
Purpose: Closes modal by data-close ID Called By: saveInfo after successful save
toggleSectionById¶
Purpose: Toggles specific accordion section by ID Called By: saveInfo to recalculate section height after data update
Events¶
Events Dispatched¶
None - component does not dispatch custom events to parent
Events Handled¶
oninputchange (from c-form-input)¶
Source: c-form-input child component
Purpose: Captures field value changes
Handler: handleCustomInputChange
onsaveinfo (from c-my-np-profile-edit-modal)¶
Source: c-my-np-profile-edit-modal child component
Purpose: Saves edited field value
Handler: saveInfo
onclosemodal (from c-my-np-profile-edit-modal)¶
Source: c-my-np-profile-edit-modal child component
Purpose: Closes edit modal
Handler: closeModal
onphonechange (from c-intl-tel-input)¶
Source: c-intl-tel-input child component
Purpose: Captures phone number changes and validation state
Handler: handleInputPhone
Styling (CSS)¶
CSS Variables Used¶
Not applicable - uses external stylesheets
Custom CSS Classes¶
.my-account-container: Main container.avatar-icon: Avatar circle with initials or photo.accordion-item: Collapsible section header.description: Collapsible section content.arrow: Chevron icon that rotates.modal-backdrop: Modal overlay- Various Bootstrap utility classes
SLDS Classes¶
- Lightning combobox uses SLDS internally
.slds-combobox__form-element
Responsive Breakpoints¶
- Mobile (<768px): Stacked layout, full-width buttons
- Tablet (768-1024px): Mixed layout
- Desktop (>1024px): Side-by-side field display
Dependencies¶
Lightning Web Components (Base)¶
lightning-iconlightning-comboboxlightning-spinnerlightning-formatted-number
Custom LWC Components¶
c-my-np-profile-display-field: Displays field with edit buttonc-my-np-profile-edit-modal: Reusable edit modalc-form-input: Custom form input with validationc-intl-tel-input: International phone number input with validationc-my-orders-receipts-tab: Orders and receipts display
Apex Classes¶
AccountController.getUserInfo(): Gets user and account infoAccountController.getFileServerUrl(): Gets file server base URLAccountController.uploadImage(): Uploads profile photoAccountController.updateUserEmail(): Updates user emailAccountController.upsertAccount(): Saves account changesCategoryController.getProductCategoryIdByName(): Gets category ID
Salesforce Objects & Fields¶
Account: Full business account object- BillingStreet, BillingCity, BillingStateCode, BillingCountryCode, BillingPostalCode
- Business_Main_Email__c, Phone, Phone_Type__c
- Name, Number_of_Individuals__c, Credentials__c
- Photo__c, Member_Type__c, Membership_End_Date__c
- DataSharing_Agreement__c, DataSharing_ArgreementVersion__c, DataSharing_Acceptance_Date__c
- Exclude_From_Third_Party_Solicitations__c, Business_Region_Territory__c
- Preferred_Method_of_Communication_Text__c
Static Resources¶
None
Labels¶
c.AANP_CE_ACTIVITY_URLc.AANP_CE_CENTER_URLc.AANP_CE_TRACKER_URLc.AANP_CE_OPPORTUNITIES_URLc.AANP_CE_EVAL_URL
Configuration¶
Component Meta XML¶
<targets>
<target>lightningCommunity__Page</target>
<target>lightningCommunity__Default</target>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
</targets>
Available On: - Community Page - Community Default - App Page - Record Page
Design Properties¶
None - no configurable properties in App Builder
User Interactions¶
Actions Available to Users¶
- Upload Profile Photo:
- Trigger: Click on avatar area, select file
-
Result: Photo uploads and displays immediately, page refreshes
-
Edit Business Name:
- Trigger: Click "Change Name" link
-
Result: Opens modal with text input, validates on save
-
Edit Number of Individuals:
- Trigger: Click "Change number of Individuals" link
-
Result: Opens modal with picklist, saves selection
-
Change Email Address:
- Trigger: Click "Change Email Address" link
-
Result: Opens modal, validates email format, sends verification
-
Change Business Address:
- Trigger: Click "Change Company Address" link
-
Result: Opens modal with full address form, validates country/state dependency
-
Edit Phone Number:
- Trigger: Click "Change my Phone Number" or "Add my Phone Number"
-
Result: Opens modal with international phone input, validates format
-
Manage Data Sharing Agreement:
- Trigger: Click data sharing links
-
Result: Opens modal explaining AANPCB data sharing, allows opt-in/opt-out
-
View Orders/Receipts:
- Trigger: Expand "My Orders/Receipts" accordion
-
Result: Loads and displays c-my-orders-receipts-tab component
-
Expand/Collapse Sections:
- Trigger: Click accordion headers
- Result: Animates section height, rotates chevron
Validation & Error Handling¶
Client-Side Validation: - Email format validation using regex pattern - Phone number format using c-intl-tel-input component - Required field validation on all inputs - Country-dependent state validation (US/CA require state) - Form input validation via c-form-input components
Error Messages: - Email update: "Error updating email, please try again." - Image upload: "Image upload failed" - Generic: "Form is invalid, please correct the errors." - Country/State validation: "Country is required." / "State is required."
Loading States: - Spinner shown during: photo upload, email update, phone update, address update, data sharing updates - Modal remains open during save with spinner in button
Data Flow¶
Input Data Flow¶
Wire Adapters
↓
wiredUserInfo → currentUser
↓
initializeComponentProperties → mapAccountData
↓
accountInfo (tracked) → Template binding
↓
Display to user
Output Data Flow¶
User edits field
↓
Modal opens → User enters data
↓
handleXXXSubmit validation
↓
upsertAccount Apex call
↓
Success → close modal, refresh wire if needed
Performance Considerations¶
Render Optimization: - Uses getters for computed values (homeAddressClass, workAddressClass, etc.) - Conditional rendering with lwc:if to reduce DOM size - Accordion collapses unused sections
Data Volume: - Max records displayed: N/A (single account) - No pagination needed
API Call Optimization: - Wire adapters cache data automatically - File upload refreshes entire page (could be optimized to refresh wire instead) - Multiple picklist wires load in parallel
Accessibility (a11y)¶
ARIA Labels: - Modal dialogs have aria-label on close buttons - Form inputs have associated labels
Keyboard Navigation: - Tab order follows natural DOM flow - Modal dialogs trap focus - All interactive elements keyboard accessible
Screen Reader Support: - Labels properly associated with inputs - Error messages announced when displayed - Modal title announced when opened
Color Contrast: - Passes WCAG AA: Needs verification with accessibility tool
Testing¶
Jest Tests¶
Test File: None Coverage: 0%
Test Scenarios: - ✗ No tests currently exist
Manual Testing Checklist¶
- [ ] Desktop browser (Chrome, Firefox, Safari)
- [ ] Mobile browser (iOS Safari, Android Chrome)
- [ ] Salesforce Mobile App
- [ ] Tablet view
- [ ] Accessibility (screen reader, keyboard-only)
- [ ] Business Account user profile/permissions
- [ ] Photo upload with various file types and sizes
- [ ] All modal interactions
- [ ] Country/state dependency logic
- [ ] Data sharing opt-in/opt-out workflow
- [ ] Email update verification workflow
Usage Examples¶
In App Builder¶
- Add to Community page as full-width component
- No configuration needed
- Component automatically loads current user's business account
In Parent Component¶
<!-- Basic usage on community page -->
<c-my-business-account></c-my-business-account>
<!-- With account type specified -->
<c-my-business-account account-type="Business"></c-my-business-account>
Programmatic Access¶
Not applicable - component does not expose public methods
Changes & History¶
- 2025-09-29: Latest changes to business account management
- Component appears to be actively maintained
⚠️ Pre-Go-Live Concerns¶
CRITICAL - Fix Before Go-Live¶
- Missing error handling on uploadImage: Photo upload fails silently with generic message, no retry mechanism
- Security: Passwords logged to console: Line 229 logs accountData which may contain sensitive info
- Full page refresh on photo upload: Very poor UX, should refresh wire data instead
- No loading state during photo upload: User has no feedback until page refreshes
- Missing null checks: handleImage assumes Photo__c has specific format (line 285-311)
- Email update doesn't refresh UI: Success message shown but displayed email doesn't update until manual refresh
HIGH - Address Soon After Go-Live¶
- No unit tests: Component has 1078 lines with zero test coverage
- Phone validation not re-validated on modal open: User could have invalid phone from previous session
- State picklist wire adapter incomplete: Line 685 has incomplete @wire definition
- Address parsing brittle: Multi-line address split by comma (lines 249-263) breaks for addresses with commas in street names
- Modal backdrop z-index issues: No z-index management for multiple modals
- Memory leak potential: Event listeners added in renderedCallback (lines 581-589) never removed
MEDIUM - Future Enhancement¶
- Add address validation service: Validate addresses against USPS or similar
- Add photo cropping: Allow users to crop/resize before upload
- Better error messages: More specific error messages for validation failures
- Add undo/cancel: Changes are saved immediately, no undo option
- Optimize re-renders: Component re-renders entire tree on any field change
- Add field-level save: Currently modals save one field at a time, could batch
- Loading skeleton: Show skeleton UI instead of blank during initial load
LOW - Monitor¶
- Unused imports: Several imports may not be used (CE_ACTIVITY_URL labels, etc.)
- Console.log statements: Many console.log statements in production code (lines 229, 243, etc.)
- Magic numbers: Data sharing agreement version hardcoded (line 27)
- Inconsistent error handling: Some methods use try/catch, others use .catch(), others have no error handling
- Code duplication: phoneCellClass, phoneWorkClass, phoneHomeClass follow same pattern (lines 891-910)
Maintenance Notes¶
Complexity: High Recommended Review Schedule: Quarterly
Key Maintainer Notes: - Component manages critical business account data including AANPCB data sharing agreements - Photo upload uses custom file server URL - ensure file server remains accessible - Country/state dependency logic is fragile - test thoroughly when updating - Component used on main business account page - any bugs affect all business members - Address parsing splits on commas - document this limitation for users with complex addresses - Phone number validation depends on c-intl-tel-input component - breaking changes there affect this component - Data sharing agreement version is hardcoded - update when agreement version changes (DATA_SHARING_AGREEMENT_VERSION constant)
Browser Compatibility: - Chrome: Latest - Firefox: Latest - Safari: Latest - Mobile: iOS 12+, Android 8+ - IE11: Not supported (uses modern JavaScript)