Additional Components & Reference
Author: Carmine Antonio Bonavoglia Creation Date: 10/11/2025
Last Reviewer: Carmine Antonio Bonavoglia Last Updated: 10/11/2025
Component Hierarchy & Architecture
Profile Page (Parent)
│
├─ PersonalInformation
│ └─ Read-only user info (name, email, company, role)
│
├─ ChangePassword
│ └─ Form with:
│ ├─ Current password
│ ├─ New password (validation)
│ └─ Save with Firebase re-authentication
│
├─ NotificationsSection
│ └─ 8 notification groups:
│ ├─ Admin
│ ├─ Catalogue
│ ├─ Orders
│ ├─ Subscription
│ ├─ Support
│ ├─ Teams
│ ├─ Weekly 3D Assets
│ └─ Weekly 3D Modelling
│
├─ TeamsSection (COMPLEX - "My Teams")
│ ├─ State Management:
│ │ ├─ editingTeam (which team in edit mode)
│ │ ├─ editingTeamName (buffered name edit)
│ │ ├─ pendingChanges (role changes: {email → newRole})
│ │ ├─ originalTeamData (for cancel restoration)
│ │ ├─ isAddMemberModalOpen (modal visibility)
│ │ ├─ addMemberTeamId (selected team)
│ │ ├─ deleteConfirmVisible (confirmation dialog)
│ │ └─ memberToDelete ({teamId, memberEmail})
│ │
│ ├─ Team Card (per team):
│ │ ├─ Team name (editable in edit mode)
│ │ ├─ Status badge
│ │ ├─ Member count
│ │ ├─ Created date
│ │ ├─ Subscription info
│ │ ├─ Members table with:
│ │ │ ├─ First/Last Name
│ │ │ ├─ Role (select dropdown in edit mode)
│ │ │ ├─ Status (Active/Pending)
│ │ │ ├─ Joined date
│ │ │ └─ Actions (dropdown: Remove/Resend Invite)
│ │ └─ Buttons: Edit/Add Member (or Save/Cancel in edit mode)
│ │
│ ├─ Add Member Modal (AddMemberModal)
│ │ ├─ Radio toggle: "Invite New User" / "Add Existing User"
│ │ ├─ New user form:
│ │ │ ├─ First Name
│ │ │ ├─ Last Name
│ │ │ ├─ Email prefix (+ domain from Client doc)
│ │ │ └─ Team Admin checkbox
│ │ ├─ Existing user select:
│ │ │ ├─ Dropdown of available profiles
│ │ │ └─ Team Admin checkbox
│ │ ├─ Confirmation modal:
│ │ │ └─ Confirm + Firebase function call
│ │ └─ Email sending via Firebase Cloud Function
│ │
│ └─ Delete Confirmation Modal
│ └─ Remove member + send notifications
│
├─ TeamSection (SECONDARY - Team Members View)
│ └─ Simple table of team members:
│ ├─ Avatar (with role-based color)
│ ├─ Name
│ ├─ Subscription count
│ ├─ Catalogue count
│ ├─ Role
│ └─ Actions (view details → MemberDetailsModal)
│
├─ MemberDetailsModal
│ ├─ Member info card:
│ │ ├─ Avatar + name/email
│ │ ├─ Role (select in edit mode)
│ │ └─ Edit button
│ │
│ ├─ Catalogues section:
│ │ ├─ Assigned catalogues table
│ │ ├─ Add Catalogues button (in edit mode)
│ │ └─ Remove buttons (in edit mode)
│ │
│ ├─ Subscriptions section:
│ │ └─ Auto-calculated based on assigned catalogues
│ │
│ ├─ AddCatalogueModal (nested)
│ │ └─ Multi-select table of unassigned catalogues
│ │
│ └─ Tutorial panel (right side)
│
├─ AssociatedBrands
│ └─ Subscriptions table:
│ ├─ Subscription Type
│ ├─ Start/End dates
│ ├─ Days left
│ ├─ Name
│ ├─ Services (tags)
│ ├─ % Consumed
│ └─ Status
│
└─ MFASetup
└─ Firebase Phone Auth:
├─ Phone number input
├─ Send verification code
├─ Verify code
└─ Enable MFA
AssociatedBrands Component
Purpose
Display user's subscription/brand associations with consumption tracking.
Props
{
loading: boolean,
subscriptions: Array<{
subscriptionType: string,
startDate: Date,
endDate: Date,
store: string,
service_list: Array<string>,
status: string
}>,
percentageData: Array<{
bandwidthDetails: { totalBandWidth: string },
consumptionLimit: number
}>
}
Table Columns
| Column | Render Logic |
|---|---|
| Subscription Type | Text |
| Start Date | toLocaleDateString() |
| End Date | toLocaleDateString() |
| Days Left | dayjs(endDate).diff(dayjs(), 'day') or "Expired" |
| Name | Text |
| Services | Tag array (blue) |
| % Consumed | (totalBandwidth / consumptionLimit * 100).toFixed(2)% → Red if >100% |
| Status | Green tag "Active" or Red "Expired" based on endDate < now |
Features
- Subscription tracking — Display all active/expired subscriptions
- Consumption display — Show bandwidth/data consumption percentage
- Date formatting — Locale-specific date display
- Service tags — Color-coded service indicators
- Days remaining — Calculate and display days until expiration
MFASetup Component
Purpose
Enable Firebase Phone-based multi-factor authentication.
Features
- Firebase Phone Auth — Uses Firebase Authentication with phone verification
- reCAPTCHA v3 — Invisible verification (currently in testing mode)
- Verify email first — Check
auth.currentUser.emailVerifiedbefore enabling MFA - Two-step flow:
- Input phone + send verification code
- Input received code + verify + enable MFA
Implementation Notes
auth.appVerificationDisabledForTesting = trueenables testing without phone- reCAPTCHA container:
<div id="recaptcha-container" style={{ display: "none" }} /> - Verification ID stored in
window.verificationId PhoneAuthProvider+multiFactor(user).enroll()enroll phone factor
Currently Disabled UI
The MFA setup UI is commented out in the current implementation:
{
/* All UI is hidden */
}
// The button, alert, and entire MFA form are commented out
Workflow: Enable MFA
Step 1: Verify Email
const verifyEmail = async () => {
const user = auth.currentUser;
if (!user.emailVerified) {
await sendEmailVerification(user);
message.info('Please verify your email first');
return false;
}
return true;
};
Step 2: Request Phone Verification
const handleSendVerificationCode = async (phoneNumber) => {
try {
// Create reCAPTCHA verifier
const verifier = new RecaptchaVerifier('recaptcha-container', {
size: 'invisible'
}, auth);
const confirmationResult = await signInWithPhoneNumber(
auth,
phoneNumber,
verifier
);
window.confirmationResult = confirmationResult;
message.success('Verification code sent');
} catch (error) {
message.error('Failed to send verification code');
}
};
Step 3: Verify Code & Enroll
const handleVerifyCode = async (code) => {
try {
const credential = await window.confirmationResult.confirm(code);
// Enroll phone as MFA factor
const user = auth.currentUser;
const phoneAuthProvider = new PhoneAuthProvider(auth);
await multiFactor(user).enroll(
phoneAuthProvider.credential(credential)
);
message.success('MFA enabled successfully');
} catch (error) {
message.error('Invalid code or verification failed');
}
};
Integration Points & Dependencies
API Services
import {
fetchNotificationPreferences,
updateNotificationPreferences,
updateTeamName,
updateMemberRole,
removeMemberFromTeam,
addMemberToTeam,
addExistingMemberToTeam,
fetchAvailableClientProfiles,
fetchClientCatalogues,
updateProfileDetails,
fetchTeamMembers,
} from "../../services/api/profileApi";
import {
createTeamNotification,
notifyAllTeamAdmins,
} from "../../services/api/notificationService";
import { getSubscriptions } from "../../services/api/subscriptionApi";
Firebase
import { auth } from "../../data/base";
import { doc, getDoc } from "firebase/firestore";
import {
updatePassword,
reauthenticateWithCredential,
EmailAuthProvider,
PhoneAuthProvider,
RecaptchaVerifier,
multiFactor,
sendEmailVerification,
signInWithPhoneNumber,
} from "firebase/auth";
Utilities
import { secureGetItem } from "../../data/utils";
Ant Design Components Used
- Modal, Form, Input, Button, Table, Select, Tag, Badge
- Avatar, Spin, Alert, Divider, Row, Col, Card, Typography
- Radio, Checkbox, Switch, Dropdown
- DatePicker, TimePicker, Progress
- Tooltip, Popover, Popconfirm
Key Patterns & Anti-Patterns
✅ Good Patterns
-
Buffered State for Edits — Role changes staged in
pendingChangesbefore save- Allows user to make multiple changes and save once
- Preserves original data for cancel restoration
-
Deep Copy for Cancel —
originalTeamDatastores deep copy for restoration- Prevents accidental mutations
- Enables safe rollback on cancel
-
Notification Orchestration — Two-level notifications (member + admins)
- Direct notification to affected member
- Broadcast notification to all admins
- Non-blocking on failure
-
Optimistic Updates — UI updates before API call, rolls back on error
- Better UX (instant feedback)
- Rollback on network/server error
-
Conditional RBAC — Permission checks before rendering edit controls
- Prevents unauthorized actions at UI level
- Server-side validation still required
-
Hierarchical Role Mapping — Clear server → display role conversion
- Centralized role transformation logic
- Easy to modify role hierarchy
⚠️ Complexity Notes
-
Modal Coordination — Multiple nested modals (AddMemberModal, ConfirmInvitationModal, AddCatalogueModal)
- Require careful state tracking
- Complex event flow and callbacks
- Risk of state inconsistency
-
Subscription Recalculation — useEffect dependency chain can lead to infinite loops
- Mitigated with
isFirstEditRenderflag - Watch out for circular dependencies
- Mitigated with
-
Notification Errors Non-Fatal — Notifications may fail silently
- Operation completes but user doesn't receive email
- Log errors for debugging but don't block
-
Email Domain from Client — Tight coupling to Client document structure
- If Client doc structure changes, AddMemberModal breaks
- Consider abstraction layer
⚠️ Anti-Patterns to Avoid
-
Direct Firestore Updates — Always use API wrapper services
- Easier to test and mock
- Centralized error handling
-
Rendering in useEffect — Use state to trigger re-renders
- Avoid setState in useEffect without dependencies
- Watch for infinite loops
-
Missing Error Boundaries — Always catch async errors
- User won't know operation failed
- Silent failures are hard to debug
-
Race Conditions — Multiple async operations can conflict
- Example: User saves while editing roles
- Use debouncing or request queuing
Performance Considerations
Lazy Loading
- Fetch team data only on component mount
- Load notifications preferences on demand
- Images loaded only when modal opens
Memoization
const mappedTeams = useMemo(() => {
return teams.map(team => ({
...team,
displayRole: mapRole(team.role)
}));
}, [teams]);
Pagination
- Large team lists should paginate
- Consider virtual scrolling for 100+ members
- Limit API results per request
Caching
- Cache notification preferences locally
- Use React Query or SWR for data synchronization
- Implement cache invalidation on updates
Testing Strategy
Unit Tests
- Test role mapping logic
- Test notification preference calculations
- Test error handling
Integration Tests
- Test full team member add workflow
- Test role change workflow
- Test password change flow
E2E Tests
- User adds team member end-to-end
- User edits member roles end-to-end
- User manages notifications end-to-end
Related Files & Architecture
Profile folder components:
/src/components/Profile/PersonalInformation.js/src/components/Profile/ChangePassword.js/src/components/Profile/NotificationsSection.js/src/components/Profile/TeamsSection.js← Most complex/src/components/Profile/TeamSection.js/src/components/Profile/AddMemberModal.js← Complex modal/src/components/Profile/MemberDetailsModal.js← Complex modal/src/components/Profile/AssociatedBrands.js/src/components/Profile/MFASetup.js/src/components/Profile/BrandIdentity/
API services:
/src/services/api/profileApi.js/src/services/api/notificationService.js/src/services/api/subscriptionApi.js
Theme & utilities:
/src/theme/theme.js/src/data/utils.js(secureGetItem)/src/data/base.js(Firebase config)