abmp-npm 2.0.76 → 2.0.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -1
- package/pages/Home.js +27 -55
- package/pages/index.js +0 -1
- package/public/Utils/personalDetailsUtils.js +5 -1
- package/public/Utils/sharedUtils.js +32 -0
- package/public/consts.js +0 -1
- package/.claude/worktrees/fix-save-button-disable/.husky/pre-commit +0 -19
- package/.claude/worktrees/fix-save-button-disable/.prettierignore +0 -7
- package/.claude/worktrees/fix-save-button-disable/.prettierrc.json +0 -16
- package/.claude/worktrees/fix-save-button-disable/README.md +0 -1
- package/.claude/worktrees/fix-save-button-disable/backend/README-member-contact-flows.md +0 -136
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/daily-pull-execution-check.test.js +0 -124
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/login-email-sync.test.js +0 -49
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
- package/.claude/worktrees/fix-save-button-disable/backend/__tests__/url-uniqueness.test.js +0 -194
- package/.claude/worktrees/fix-save-button-disable/backend/automations-methods.js +0 -13
- package/.claude/worktrees/fix-save-button-disable/backend/cms-data-methods.js +0 -251
- package/.claude/worktrees/fix-save-button-disable/backend/consts.js +0 -58
- package/.claude/worktrees/fix-save-button-disable/backend/contacts-methods.js +0 -67
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/bulk-process-methods.js +0 -222
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/consts.js +0 -39
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/index.js +0 -5
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/process-member-methods.js +0 -213
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/schedule-methods.js +0 -41
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/sync-to-cms-methods.js +0 -161
- package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/utils.js +0 -151
- package/.claude/worktrees/fix-save-button-disable/backend/data-hooks.js +0 -29
- package/.claude/worktrees/fix-save-button-disable/backend/dev-only-methods.js +0 -58
- package/.claude/worktrees/fix-save-button-disable/backend/elevated-modules.js +0 -18
- package/.claude/worktrees/fix-save-button-disable/backend/forms-methods.js +0 -52
- package/.claude/worktrees/fix-save-button-disable/backend/http-functions/httpFunctions.js +0 -86
- package/.claude/worktrees/fix-save-button-disable/backend/http-functions/index.js +0 -3
- package/.claude/worktrees/fix-save-button-disable/backend/http-functions/interests.js +0 -35
- package/.claude/worktrees/fix-save-button-disable/backend/index.js +0 -19
- package/.claude/worktrees/fix-save-button-disable/backend/jobs.js +0 -158
- package/.claude/worktrees/fix-save-button-disable/backend/login/generate-member-session-token.js +0 -27
- package/.claude/worktrees/fix-save-button-disable/backend/login/index.js +0 -8
- package/.claude/worktrees/fix-save-button-disable/backend/login/qa-login-methods.js +0 -54
- package/.claude/worktrees/fix-save-button-disable/backend/login/sso-methods.js +0 -159
- package/.claude/worktrees/fix-save-button-disable/backend/member-contact-orchestration.js +0 -111
- package/.claude/worktrees/fix-save-button-disable/backend/members-area-methods.js +0 -88
- package/.claude/worktrees/fix-save-button-disable/backend/members-data-methods.js +0 -789
- package/.claude/worktrees/fix-save-button-disable/backend/pac-api-methods.js +0 -54
- package/.claude/worktrees/fix-save-button-disable/backend/routers/index.js +0 -3
- package/.claude/worktrees/fix-save-button-disable/backend/routers/methods.js +0 -191
- package/.claude/worktrees/fix-save-button-disable/backend/routers/utils.js +0 -128
- package/.claude/worktrees/fix-save-button-disable/backend/search-filters-methods.js +0 -124
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-primary-methods.js +0 -256
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js +0 -160
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/consts.js +0 -34
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/daily-pull-check-methods.js +0 -78
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/email-normalize-methods.js +0 -134
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/index.js +0 -10
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/migration-methods.js +0 -46
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-configs.js +0 -251
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-helpers-methods.js +0 -433
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-process-methods.js +0 -606
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-migration-methods.js +0 -378
- package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-space-fix-methods.js +0 -174
- package/.claude/worktrees/fix-save-button-disable/backend/utils.js +0 -277
- package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
- package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-ids.js +0 -159
- package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-urls.js +0 -201
- package/.claude/worktrees/fix-save-button-disable/eslint.config.js +0 -120
- package/.claude/worktrees/fix-save-button-disable/index.js +0 -5
- package/.claude/worktrees/fix-save-button-disable/package-lock.json +0 -12160
- package/.claude/worktrees/fix-save-button-disable/package.json +0 -60
- package/.claude/worktrees/fix-save-button-disable/pages/ContactUs.js +0 -129
- package/.claude/worktrees/fix-save-button-disable/pages/Home.js +0 -779
- package/.claude/worktrees/fix-save-button-disable/pages/LearnMore.js +0 -27
- package/.claude/worktrees/fix-save-button-disable/pages/LoadingPage.js +0 -29
- package/.claude/worktrees/fix-save-button-disable/pages/Profile.js +0 -354
- package/.claude/worktrees/fix-save-button-disable/pages/QAPage.js +0 -39
- package/.claude/worktrees/fix-save-button-disable/pages/SaveAlerts.js +0 -13
- package/.claude/worktrees/fix-save-button-disable/pages/SelectBannerImages.js +0 -46
- package/.claude/worktrees/fix-save-button-disable/pages/deleteConfirm.js +0 -19
- package/.claude/worktrees/fix-save-button-disable/pages/index.js +0 -12
- package/.claude/worktrees/fix-save-button-disable/pages/personalDetails.js +0 -2486
- package/.claude/worktrees/fix-save-button-disable/public/Utils/homePage.js +0 -798
- package/.claude/worktrees/fix-save-button-disable/public/Utils/personalDetailsUtils.js +0 -25
- package/.claude/worktrees/fix-save-button-disable/public/Utils/sharedUtils.js +0 -235
- package/.claude/worktrees/fix-save-button-disable/public/consts.js +0 -113
- package/.claude/worktrees/fix-save-button-disable/public/index.js +0 -5
- package/.claude/worktrees/fix-save-button-disable/public/messages.js +0 -16
- package/.claude/worktrees/fix-save-button-disable/public/sso-auth-methods.js +0 -43
- package/.husky/pre-commit +0 -19
- package/.prettierignore +0 -7
- package/.prettierrc.json +0 -16
- package/backend/__tests__/daily-pull-execution-check.test.js +0 -124
- package/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
- package/backend/__tests__/login-email-sync.test.js +0 -49
- package/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
- package/backend/__tests__/url-uniqueness.test.js +0 -194
- package/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
- package/dev-only-scripts/find-duplicate-ids.js +0 -159
- package/dev-only-scripts/find-duplicate-urls.js +0 -201
- package/eslint.config.js +0 -120
- package/pages/contactForLocation.js +0 -28
|
@@ -1,789 +0,0 @@
|
|
|
1
|
-
const { COLLECTIONS } = require('../public/consts');
|
|
2
|
-
const { isWixHostedImage, emailsMatch, normalizeEmail } = require('../public/Utils/sharedUtils');
|
|
3
|
-
|
|
4
|
-
const { MEMBERSHIPS_TYPES } = require('./consts');
|
|
5
|
-
const { createSiteContact } = require('./contacts-methods');
|
|
6
|
-
const { MEMBER_ACTIONS } = require('./daily-pull/consts');
|
|
7
|
-
const { wixData } = require('./elevated-modules');
|
|
8
|
-
const { updateMemberContactInfo } = require('./member-contact-orchestration');
|
|
9
|
-
const { createSiteMember, getCurrentMember } = require('./members-area-methods');
|
|
10
|
-
const {
|
|
11
|
-
chunkArray,
|
|
12
|
-
normalizeUrlForComparison,
|
|
13
|
-
sortByUrlCounterDescending,
|
|
14
|
-
queryAllItems,
|
|
15
|
-
generateGeoHash,
|
|
16
|
-
searchAllItems,
|
|
17
|
-
runIf,
|
|
18
|
-
withTransientErrorRetry,
|
|
19
|
-
} = require('./utils');
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Retrieves member data by member ID
|
|
23
|
-
* @param {string} memberId - The member ID to search for
|
|
24
|
-
* @returns {Promise<Object|null>} - Member data or null if not found
|
|
25
|
-
*/
|
|
26
|
-
async function findMemberByWixDataId(memberId) {
|
|
27
|
-
if (!memberId) {
|
|
28
|
-
throw new Error('Member ID is required');
|
|
29
|
-
}
|
|
30
|
-
try {
|
|
31
|
-
const member = await wixData.get(COLLECTIONS.MEMBERS_DATA, memberId);
|
|
32
|
-
return member;
|
|
33
|
-
} catch (error) {
|
|
34
|
-
throw new Error(`Failed to retrieve member data: ${error.message}`);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const hasDifferentEmails = memberData =>
|
|
39
|
-
Boolean(memberData.contactFormEmail) &&
|
|
40
|
-
!emailsMatch(memberData.contactFormEmail, memberData.email);
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Returns a shallow copy of a member record with its email fields normalized
|
|
44
|
-
* (lowercased + trimmed). Wix CRM and our uniqueness checks treat emails
|
|
45
|
-
* case-insensitively, so we persist them in canonical form to keep `.eq` lookups
|
|
46
|
-
* reliable. Only rewrites string values that are actually present.
|
|
47
|
-
* @param {Object} memberData
|
|
48
|
-
* @returns {Object}
|
|
49
|
-
*/
|
|
50
|
-
const normalizeMemberEmailFields = memberData => {
|
|
51
|
-
if (!memberData || typeof memberData !== 'object') return memberData;
|
|
52
|
-
const normalized = { ...memberData };
|
|
53
|
-
if (typeof normalized.email === 'string') {
|
|
54
|
-
normalized.email = normalizeEmail(normalized.email);
|
|
55
|
-
}
|
|
56
|
-
if (typeof normalized.contactFormEmail === 'string') {
|
|
57
|
-
normalized.contactFormEmail = normalizeEmail(normalized.contactFormEmail);
|
|
58
|
-
}
|
|
59
|
-
return normalized;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Whether a member's stored email fields are not already in canonical form
|
|
64
|
-
* (lowercased + trimmed) and therefore need the normalization backfill.
|
|
65
|
-
* @param {Object} member
|
|
66
|
-
* @returns {boolean}
|
|
67
|
-
*/
|
|
68
|
-
const memberNeedsEmailNormalization = member =>
|
|
69
|
-
(typeof member.email === 'string' &&
|
|
70
|
-
member.email.length > 0 &&
|
|
71
|
-
member.email !== normalizeEmail(member.email)) ||
|
|
72
|
-
(typeof member.contactFormEmail === 'string' &&
|
|
73
|
-
member.contactFormEmail.length > 0 &&
|
|
74
|
-
member.contactFormEmail !== normalizeEmail(member.contactFormEmail));
|
|
75
|
-
|
|
76
|
-
async function createContactAndMemberIfNew(memberData) {
|
|
77
|
-
if (!memberData) {
|
|
78
|
-
throw new Error('Member data is required');
|
|
79
|
-
}
|
|
80
|
-
try {
|
|
81
|
-
const toCreateMemberData = {
|
|
82
|
-
firstName: memberData.firstName,
|
|
83
|
-
lastName: memberData.lastName,
|
|
84
|
-
email: memberData.email,
|
|
85
|
-
phones: memberData.phones,
|
|
86
|
-
contactFormEmail: memberData.contactFormEmail,
|
|
87
|
-
};
|
|
88
|
-
const needsWixMember = !memberData.wixMemberId;
|
|
89
|
-
const needsWixContact = !memberData.wixContactId;
|
|
90
|
-
const hasContactEmailDifferentFromLogin = hasDifferentEmails(memberData);
|
|
91
|
-
console.log('needsWixMember', needsWixMember);
|
|
92
|
-
console.log('needsWixContact', needsWixContact);
|
|
93
|
-
console.log('hasContactEmailDifferentFromLogin', hasContactEmailDifferentFromLogin);
|
|
94
|
-
|
|
95
|
-
const [newWixMemberId, createdWixContactId] = await Promise.all([
|
|
96
|
-
runIf(needsWixMember, () => createSiteMember(toCreateMemberData)),
|
|
97
|
-
runIf(needsWixContact && hasContactEmailDifferentFromLogin, () =>
|
|
98
|
-
createSiteContact(toCreateMemberData)
|
|
99
|
-
),
|
|
100
|
-
]);
|
|
101
|
-
const memberContactId = newWixMemberId;
|
|
102
|
-
const newWixContactId = createdWixContactId || memberContactId;
|
|
103
|
-
console.log('newWixMemberId', newWixMemberId);
|
|
104
|
-
console.log('memberContactId', memberContactId);
|
|
105
|
-
console.log('newWixContactId', newWixContactId);
|
|
106
|
-
let memberDataWithContactId = {
|
|
107
|
-
...memberData,
|
|
108
|
-
wixMemberId: newWixMemberId || memberData.wixMemberId,
|
|
109
|
-
wixContactId: newWixContactId || memberData.wixContactId,
|
|
110
|
-
};
|
|
111
|
-
console.log('latest WixMemberId', memberDataWithContactId.wixMemberId);
|
|
112
|
-
console.log('latest WixContactId', memberDataWithContactId.wixContactId);
|
|
113
|
-
const updatedResult = await updateMember(memberDataWithContactId);
|
|
114
|
-
memberDataWithContactId = {
|
|
115
|
-
...memberDataWithContactId,
|
|
116
|
-
...updatedResult,
|
|
117
|
-
};
|
|
118
|
-
return memberDataWithContactId;
|
|
119
|
-
} catch (error) {
|
|
120
|
-
console.error('Error creating contact and member if new:', error);
|
|
121
|
-
throw new Error(`Failed to create contact and member if new: ${error.message}`);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** Performs bulk save operation for member data
|
|
126
|
-
* @param { Array } memberDataList - Array of member data objects to save
|
|
127
|
-
* @param { string } [collectionName] - The collection name to save the members to (default: COLLECTIONS.MEMBERS_DATA)
|
|
128
|
-
* @returns { Promise < Object >} - Bulk save operation result
|
|
129
|
-
*/
|
|
130
|
-
async function bulkSaveMembers(memberDataList, collectionName = COLLECTIONS.MEMBERS_DATA) {
|
|
131
|
-
if (!Array.isArray(memberDataList) || memberDataList.length === 0) {
|
|
132
|
-
throw new Error('Invalid member data list provided for bulk save');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
// Normalize email fields only for the members collection; other collections passed here
|
|
137
|
-
// (e.g. staging copies) don't have these fields and must be saved untouched.
|
|
138
|
-
const listToSave =
|
|
139
|
-
collectionName === COLLECTIONS.MEMBERS_DATA
|
|
140
|
-
? memberDataList.map(normalizeMemberEmailFields)
|
|
141
|
-
: memberDataList;
|
|
142
|
-
// bulkSave all with batches of 1000 items as this is the Velo limit for bulkSave
|
|
143
|
-
const batches = chunkArray(listToSave, 1000);
|
|
144
|
-
return await Promise.all(batches.map(batch => wixData.bulkSave(collectionName, batch)));
|
|
145
|
-
} catch (error) {
|
|
146
|
-
console.error('Error bulk saving members:', error);
|
|
147
|
-
throw new Error(`Bulk save failed: ${error.message}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Retrieves member data by member ID
|
|
153
|
-
* @param {string} memberId - The member ID to search for
|
|
154
|
-
* @returns {Promise<Object|null>} - Member data or null if not found
|
|
155
|
-
*/
|
|
156
|
-
async function findMemberById(memberId) {
|
|
157
|
-
if (!memberId) {
|
|
158
|
-
throw new Error('Member ID is required');
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
try {
|
|
162
|
-
const queryResult = await withTransientErrorRetry(() =>
|
|
163
|
-
wixData.query(COLLECTIONS.MEMBERS_DATA).eq('memberId', memberId).limit(2).find()
|
|
164
|
-
);
|
|
165
|
-
if (queryResult.items.length > 1) {
|
|
166
|
-
throw new Error(
|
|
167
|
-
`Multiple members found with memberId ${memberId} members _ids are : [${queryResult.items.map(member => member._id).join(', ')}]`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
return queryResult.items.length === 1 ? queryResult.items[0] : null;
|
|
171
|
-
} catch (error) {
|
|
172
|
-
console.error('Error finding member by ID:', error);
|
|
173
|
-
throw new Error(`Failed to retrieve member data: ${error.message}`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Retrieves existing members for a list of member IDs in bulk.
|
|
179
|
-
* Uses chunked `hasSome` queries so a full page of members costs a handful of
|
|
180
|
-
* requests instead of one query per member (the per-member fan-out made a whole
|
|
181
|
-
* page fail whenever a single query hit a transient "fetch failed").
|
|
182
|
-
* @param {Array<string|number>} memberIds - Member IDs to look up
|
|
183
|
-
* @returns {Promise<Map<string, Object>>} - Map of String(memberId) to member record (missing IDs are absent)
|
|
184
|
-
*/
|
|
185
|
-
async function findMembersByIds(memberIds) {
|
|
186
|
-
const uniqueIds = [...new Set((memberIds || []).filter(id => id !== undefined && id !== null))];
|
|
187
|
-
const membersById = new Map();
|
|
188
|
-
if (uniqueIds.length === 0) {
|
|
189
|
-
return membersById;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
try {
|
|
193
|
-
const idChunks = chunkArray(uniqueIds, 100);
|
|
194
|
-
const chunkResults = await Promise.all(
|
|
195
|
-
idChunks.map(idsChunk =>
|
|
196
|
-
withTransientErrorRetry(() =>
|
|
197
|
-
queryAllItems(
|
|
198
|
-
wixData.query(COLLECTIONS.MEMBERS_DATA).hasSome('memberId', idsChunk).limit(1000)
|
|
199
|
-
)
|
|
200
|
-
)
|
|
201
|
-
)
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
const duplicateIds = new Set();
|
|
205
|
-
chunkResults.flat().forEach(member => {
|
|
206
|
-
const key = String(member.memberId);
|
|
207
|
-
if (membersById.has(key)) {
|
|
208
|
-
duplicateIds.add(key);
|
|
209
|
-
}
|
|
210
|
-
membersById.set(key, member);
|
|
211
|
-
});
|
|
212
|
-
if (duplicateIds.size > 0) {
|
|
213
|
-
throw new Error(`Multiple members found with memberId(s): [${[...duplicateIds].join(', ')}]`);
|
|
214
|
-
}
|
|
215
|
-
return membersById;
|
|
216
|
-
} catch (error) {
|
|
217
|
-
console.error('Error finding members by IDs:', error);
|
|
218
|
-
throw new Error(`Failed to retrieve member data: ${error.message}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Method to get member by slug with flexible filtering options
|
|
224
|
-
* @param {Object} options - Query options
|
|
225
|
-
* @param {string} options.slug - The slug to search for
|
|
226
|
-
* @param {boolean} options.excludeDropped - Whether to exclude dropped members (default: true)
|
|
227
|
-
* @param {boolean} options.excludeSearchedMember - Whether to exclude a specific member (default: false)
|
|
228
|
-
* @param {string|number} [options.memberId] - Member ID to exclude when excludeSearchedMember is true (optional)
|
|
229
|
-
* @param {boolean} [options.normalizeSlugForComparison=false] - Whether to normalize the slug for comparison (default: false)
|
|
230
|
-
* @returns {Promise<Object|null>} - Member data or null if not found
|
|
231
|
-
*/
|
|
232
|
-
async function getMemberBySlug({
|
|
233
|
-
slug,
|
|
234
|
-
excludeDropped = true,
|
|
235
|
-
excludeSearchedMember = false,
|
|
236
|
-
memberId = null,
|
|
237
|
-
normalizeSlugForComparison = false,
|
|
238
|
-
}) {
|
|
239
|
-
if (!slug) return null;
|
|
240
|
-
|
|
241
|
-
try {
|
|
242
|
-
let query = wixData.search(COLLECTIONS.MEMBERS_DATA).expression(slug);
|
|
243
|
-
|
|
244
|
-
if (excludeDropped) {
|
|
245
|
-
query = query.ne('action', 'drop');
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (excludeSearchedMember && memberId) {
|
|
249
|
-
query = query.ne('memberId', memberId);
|
|
250
|
-
}
|
|
251
|
-
query = query.limit(1000);
|
|
252
|
-
const searchResult = await searchAllItems(query);
|
|
253
|
-
const membersList = searchResult.filter(
|
|
254
|
-
item => item.url && item.url.toLowerCase().includes(slug.toLowerCase())
|
|
255
|
-
); //replacement for contains - case insensitive
|
|
256
|
-
let matchingMembers = membersList.filter(
|
|
257
|
-
item => item.url && item.url.toLowerCase() === slug.toLowerCase()
|
|
258
|
-
);
|
|
259
|
-
if (normalizeSlugForComparison) {
|
|
260
|
-
matchingMembers = membersList
|
|
261
|
-
.filter(
|
|
262
|
-
//remove trailing "-1", "-2", etc.
|
|
263
|
-
item => item.url && normalizeUrlForComparison(item.url) === slug.toLowerCase()
|
|
264
|
-
)
|
|
265
|
-
.sort(sortByUrlCounterDescending);
|
|
266
|
-
}
|
|
267
|
-
if (matchingMembers.length > 1) {
|
|
268
|
-
const queryResultMsg = `Multiple members found with same slug ${slug} membersIds are : [${matchingMembers
|
|
269
|
-
.map(member => member.memberId)
|
|
270
|
-
.join(', ')}]`;
|
|
271
|
-
if (!normalizeSlugForComparison) {
|
|
272
|
-
throw new Error(queryResultMsg);
|
|
273
|
-
} else {
|
|
274
|
-
console.log(queryResultMsg);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return matchingMembers[0] || null;
|
|
278
|
-
} catch (error) {
|
|
279
|
-
const errorMessage = `Error getting member by slug: ${slug} : ${error.message}`;
|
|
280
|
-
console.error(errorMessage);
|
|
281
|
-
throw new Error(errorMessage);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async function getCMSMemberByWixMemberId(wixMemberId) {
|
|
286
|
-
if (!wixMemberId) {
|
|
287
|
-
throw new Error('Wix Member ID is required');
|
|
288
|
-
}
|
|
289
|
-
try {
|
|
290
|
-
const members = await wixData
|
|
291
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
292
|
-
.eq('wixMemberId', wixMemberId)
|
|
293
|
-
.limit(2)
|
|
294
|
-
.find()
|
|
295
|
-
.then(res => res.items);
|
|
296
|
-
if (members.length > 1) {
|
|
297
|
-
throw new Error(
|
|
298
|
-
`[getCMSMemberByWixMemberId] Multiple members found with wixMemberId ${wixMemberId} membersIds are : [${members.map(member => member.memberId).join(', ')}]`
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
return members[0] || null;
|
|
302
|
-
} catch (error) {
|
|
303
|
-
throw new Error(
|
|
304
|
-
`[getCMSMemberByWixMemberId] Failed to retrieve member by wixMemberId ${wixMemberId} data: ${error.message}`
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Gets all members with aboutyoustatus as null
|
|
310
|
-
* @returns {Promise<import('wix-data').WixDataQueryResult>} - WixDataQueryResult of member data
|
|
311
|
-
*/
|
|
312
|
-
const getAllEmptyAboutYouMembers = async () => {
|
|
313
|
-
try {
|
|
314
|
-
const membersQuery = wixData
|
|
315
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
316
|
-
.isEmpty('aboutYourSelf')
|
|
317
|
-
.isNotEmpty('aboutYouHtml');
|
|
318
|
-
return await queryAllItems(membersQuery);
|
|
319
|
-
} catch (error) {
|
|
320
|
-
console.error('Error getting empty about you members:', error);
|
|
321
|
-
throw new Error(`Failed to get empty about you members: ${error.message}`);
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* updates member data
|
|
327
|
-
* @param {Object} memberToUpdate - The member data to update
|
|
328
|
-
* @returns {Promise<Object|null>} - Member data or null if not found
|
|
329
|
-
*/
|
|
330
|
-
async function updateMember(memberToUpdate) {
|
|
331
|
-
try {
|
|
332
|
-
const updatedMember = await wixData.update(
|
|
333
|
-
COLLECTIONS.MEMBERS_DATA,
|
|
334
|
-
normalizeMemberEmailFields(memberToUpdate)
|
|
335
|
-
);
|
|
336
|
-
return updatedMember;
|
|
337
|
-
} catch (error) {
|
|
338
|
-
throw new Error(`Failed to update member data: ${error.message}`);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Whether the given email is already used by a DIFFERENT member (case-insensitive).
|
|
343
|
-
* Returns false when the email is free or belongs to the same member, so a member can
|
|
344
|
-
* always keep/normalize their own email.
|
|
345
|
-
* @param {string} email
|
|
346
|
-
* @param {string|number} memberId - The member requesting the change
|
|
347
|
-
* @returns {Promise<boolean>}
|
|
348
|
-
*/
|
|
349
|
-
async function isEmailAlreadyUsed(email, memberId) {
|
|
350
|
-
const member = await getMemberByContactEmail(email);
|
|
351
|
-
return member !== null && String(member.memberId) !== String(memberId);
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Finds the member that owns an email (in either the login or contact-form field),
|
|
355
|
-
* matching case-insensitively. Emails are normalized (lowercased + trimmed) on write and
|
|
356
|
-
* backfilled by the email-normalization migration, so stored values are canonical: a single
|
|
357
|
-
* `.eq` against the normalized email is an exact, case-insensitive lookup.
|
|
358
|
-
* Throws if two DIFFERENT members share the email (a data-integrity violation).
|
|
359
|
-
* @param {string} email
|
|
360
|
-
* @returns {Promise<Object|null>}
|
|
361
|
-
*/
|
|
362
|
-
async function getMemberByContactEmail(email) {
|
|
363
|
-
const normalized = normalizeEmail(email);
|
|
364
|
-
if (!normalized) return null;
|
|
365
|
-
|
|
366
|
-
const members = await wixData
|
|
367
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
368
|
-
.eq('contactFormEmail', normalized)
|
|
369
|
-
.or(wixData.query(COLLECTIONS.MEMBERS_DATA).eq('email', normalized))
|
|
370
|
-
.limit(2)
|
|
371
|
-
.find()
|
|
372
|
-
.then(res => res.items);
|
|
373
|
-
|
|
374
|
-
if (members.length > 1) {
|
|
375
|
-
throw new Error(
|
|
376
|
-
`[getMemberByContactEmail] Multiple members found with same loginemail or contactFormEmail ${email} membersIds are : [${members.map(member => member.memberId).join(', ')}]`
|
|
377
|
-
);
|
|
378
|
-
}
|
|
379
|
-
return members[0] || null;
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Saves member registration data (supports partial updates)
|
|
383
|
-
* @param {Object} data - Member data to save (can be partial - only fields being updated)
|
|
384
|
-
* @param {string} id - Member ID
|
|
385
|
-
* @returns {Promise<Object>} Result object with type and data/error
|
|
386
|
-
*/
|
|
387
|
-
async function saveRegistrationData(data, id) {
|
|
388
|
-
try {
|
|
389
|
-
console.log(' saveRegistrationData data._id', data._id);
|
|
390
|
-
console.log(' saveRegistrationData id', id);
|
|
391
|
-
if (data._id !== id) return { type: 'notAuthorized' };
|
|
392
|
-
|
|
393
|
-
if (data.url) {
|
|
394
|
-
const isDuplicate = await urlExists(data.url, data.memberId);
|
|
395
|
-
|
|
396
|
-
if (isDuplicate) {
|
|
397
|
-
return {
|
|
398
|
-
type: 'error',
|
|
399
|
-
error: 'URL slug is already taken. Please choose a different one.',
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (data.contactFormEmail) {
|
|
404
|
-
const isDuplicate = await isEmailAlreadyUsed(data.contactFormEmail, data.memberId);
|
|
405
|
-
if (isDuplicate) {
|
|
406
|
-
return {
|
|
407
|
-
type: 'error',
|
|
408
|
-
error: 'Contact Email is already taken. Please choose a different one.',
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
// Fetch existing data to merge with partial update
|
|
413
|
-
const existingMemberData = await findMemberByWixDataId(id);
|
|
414
|
-
|
|
415
|
-
if (!existingMemberData) {
|
|
416
|
-
return {
|
|
417
|
-
type: 'error',
|
|
418
|
-
error: 'Member not found',
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// Merge partial data with existing data (incoming data takes precedence)
|
|
423
|
-
const mergedData = {
|
|
424
|
-
...existingMemberData,
|
|
425
|
-
...data,
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
if (data.addresses && Array.isArray(data.addresses)) {
|
|
429
|
-
mergedData.locHash = generateGeoHash(data.addresses);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
const dataToSave = await updateMemberContactInfo(mergedData, existingMemberData);
|
|
433
|
-
const saveData = await updateMember(dataToSave);
|
|
434
|
-
return {
|
|
435
|
-
type: 'success',
|
|
436
|
-
saveData,
|
|
437
|
-
};
|
|
438
|
-
} catch (error) {
|
|
439
|
-
console.error(error);
|
|
440
|
-
return {
|
|
441
|
-
type: 'error',
|
|
442
|
-
error,
|
|
443
|
-
};
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Checks if a URL already exists in the database for a different member (case-insensitive)
|
|
449
|
-
* @param {string} url - The URL to check
|
|
450
|
-
* @param {string|number} excludeMemberId - Member ID to exclude from the check
|
|
451
|
-
* @returns {Promise<boolean>} - True if URL exists for another member
|
|
452
|
-
*/
|
|
453
|
-
async function urlExists(url, excludeMemberId) {
|
|
454
|
-
if (!url) return false;
|
|
455
|
-
|
|
456
|
-
try {
|
|
457
|
-
const member = await getMemberBySlug({
|
|
458
|
-
slug: url,
|
|
459
|
-
excludeDropped: false,
|
|
460
|
-
excludeSearchedMember: true,
|
|
461
|
-
memberId: excludeMemberId,
|
|
462
|
-
});
|
|
463
|
-
return member !== null;
|
|
464
|
-
} catch (error) {
|
|
465
|
-
console.error('Error checking URL existence:', error);
|
|
466
|
-
return false;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Checks URL uniqueness for a member
|
|
472
|
-
* @param {string} url - The URL to check
|
|
473
|
-
* @param {string} memberId - The member ID to exclude from the check
|
|
474
|
-
* @returns {Promise<Object>} Result object with isUnique boolean
|
|
475
|
-
*/
|
|
476
|
-
async function checkUrlUniqueness(url, memberId) {
|
|
477
|
-
if (!url || !memberId) {
|
|
478
|
-
throw new Error('Missing required parameters: url and memberId are required');
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
try {
|
|
482
|
-
const trimmedUrl = url.trim();
|
|
483
|
-
const exists = await urlExists(trimmedUrl, memberId);
|
|
484
|
-
|
|
485
|
-
return { isUnique: !exists };
|
|
486
|
-
} catch (error) {
|
|
487
|
-
console.error('Error checking URL uniqueness:', error);
|
|
488
|
-
throw new Error(`Failed to check URL uniqueness: ${error.message}`);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* Get all members with external profile images
|
|
493
|
-
* @returns {Promise<Array>} - Array of member IDs
|
|
494
|
-
*/
|
|
495
|
-
async function getAllMembersWithExternalImages() {
|
|
496
|
-
try {
|
|
497
|
-
const membersQuery = await wixData
|
|
498
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
499
|
-
.isNotEmpty('profileImage')
|
|
500
|
-
.ne('profileImage', null);
|
|
501
|
-
|
|
502
|
-
const allItems = await queryAllItems(membersQuery);
|
|
503
|
-
|
|
504
|
-
// Filter for external images (not 'wix hosted images')
|
|
505
|
-
const membersWithExternalImages = allItems.filter(
|
|
506
|
-
member => member.profileImage && !isWixHostedImage(member.profileImage)
|
|
507
|
-
);
|
|
508
|
-
|
|
509
|
-
return membersWithExternalImages;
|
|
510
|
-
} catch (error) {
|
|
511
|
-
console.error('Error getting members with external images:', error);
|
|
512
|
-
return [];
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
async function getMembersWithWixUrl() {
|
|
517
|
-
const membersQuery = wixData
|
|
518
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
519
|
-
.eq('isVisible', true)
|
|
520
|
-
.eq('showWixUrl', true)
|
|
521
|
-
.ne('action', MEMBER_ACTIONS.DROP)
|
|
522
|
-
.ne('memberships.membertype', MEMBERSHIPS_TYPES.PAC_STAFF)
|
|
523
|
-
.ne('memberships.membertype', MEMBERSHIPS_TYPES.STUDENT)
|
|
524
|
-
//.isNotEmpty('url') - not used because it's not working as expected
|
|
525
|
-
.limit(1000);
|
|
526
|
-
let currentResults = await membersQuery.find();
|
|
527
|
-
let i = 0;
|
|
528
|
-
const allItems = currentResults.items;
|
|
529
|
-
while (currentResults.hasNext()) {
|
|
530
|
-
if (i % 50 === 0) console.log(`page ${i}`);
|
|
531
|
-
currentResults = await currentResults.next();
|
|
532
|
-
allItems.push(...currentResults.items);
|
|
533
|
-
i++;
|
|
534
|
-
}
|
|
535
|
-
console.log('i is ', i);
|
|
536
|
-
const filtered = allItems.filter(
|
|
537
|
-
item => typeof item.url === 'string' && !item.url.includes('/') && item.url !== ''
|
|
538
|
-
);
|
|
539
|
-
console.log('filtered is ', filtered.length);
|
|
540
|
-
return filtered;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Gets all members who need contactFormEmail migration (missing contactFormEmail field)
|
|
545
|
-
* @returns {Promise<Array>} - Array of member data
|
|
546
|
-
*/
|
|
547
|
-
const getAllMembersWithoutContactFormEmail = async () => {
|
|
548
|
-
try {
|
|
549
|
-
const membersQuery = wixData
|
|
550
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
551
|
-
.isEmpty('contactFormEmail')
|
|
552
|
-
.isNotEmpty('email')
|
|
553
|
-
.limit(1000);
|
|
554
|
-
|
|
555
|
-
const allItems = await queryAllItems(membersQuery);
|
|
556
|
-
return allItems;
|
|
557
|
-
} catch (error) {
|
|
558
|
-
console.error('Error getting members without contactFormEmail:', error);
|
|
559
|
-
throw new Error(`Failed to get members without contactFormEmail: ${error.message}`);
|
|
560
|
-
}
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
/**
|
|
564
|
-
* Gets all members whose email or contactFormEmail is stored with non-canonical casing
|
|
565
|
-
* (or surrounding whitespace) and therefore needs the normalization backfill.
|
|
566
|
-
* Wix Data cannot compare a field to its own lowercase form, so we fetch members that have
|
|
567
|
-
* an email set and filter in memory.
|
|
568
|
-
* @returns {Promise<Array>} - Array of member data
|
|
569
|
-
*/
|
|
570
|
-
const getAllMembersNeedingEmailNormalization = async () => {
|
|
571
|
-
try {
|
|
572
|
-
const membersQuery = wixData
|
|
573
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
574
|
-
.isNotEmpty('email')
|
|
575
|
-
.or(wixData.query(COLLECTIONS.MEMBERS_DATA).isNotEmpty('contactFormEmail'))
|
|
576
|
-
.limit(1000);
|
|
577
|
-
|
|
578
|
-
const allItems = await queryAllItems(membersQuery);
|
|
579
|
-
return allItems.filter(memberNeedsEmailNormalization);
|
|
580
|
-
} catch (error) {
|
|
581
|
-
console.error('Error getting members needing email normalization:', error);
|
|
582
|
-
throw new Error(`Failed to get members needing email normalization: ${error.message}`);
|
|
583
|
-
}
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
/* Gets all updated login emails from the updated emails database
|
|
587
|
-
* @returns {Promise<Array>} - Array of updated email data
|
|
588
|
-
*/
|
|
589
|
-
const getAllUpdatedLoginEmails = async () => {
|
|
590
|
-
try {
|
|
591
|
-
const updatedEmailsQuery = await wixData
|
|
592
|
-
.query(COLLECTIONS.UPDATED_LOGIN_EMAILS)
|
|
593
|
-
.isNotEmpty('memberId')
|
|
594
|
-
.isNotEmpty('loginEmail')
|
|
595
|
-
.limit(1000);
|
|
596
|
-
return await queryAllItems(updatedEmailsQuery);
|
|
597
|
-
} catch (error) {
|
|
598
|
-
console.error('Error getting updated login emails:', error);
|
|
599
|
-
throw new Error(`Failed to get updated login emails: ${error.message}`);
|
|
600
|
-
}
|
|
601
|
-
};
|
|
602
|
-
/**
|
|
603
|
-
* Gets members by their member IDs for email sync
|
|
604
|
-
* @param {Array} memberIds - Array of member IDs to fetch
|
|
605
|
-
* @returns {Promise<Array>} - Array of member data
|
|
606
|
-
*/
|
|
607
|
-
const getMembersByIds = async memberIds => {
|
|
608
|
-
try {
|
|
609
|
-
const membersQuery = wixData
|
|
610
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
611
|
-
.hasSome('memberId', memberIds)
|
|
612
|
-
.limit(1000);
|
|
613
|
-
|
|
614
|
-
return await queryAllItems(membersQuery);
|
|
615
|
-
} catch (error) {
|
|
616
|
-
console.error('Error getting members by IDs:', error);
|
|
617
|
-
throw new Error(`Failed to get members by IDs: ${error.message}`);
|
|
618
|
-
}
|
|
619
|
-
};
|
|
620
|
-
|
|
621
|
-
const getMemberByEmail = async email => {
|
|
622
|
-
try {
|
|
623
|
-
// Login emails are normalized on write, so match against the normalized value (see
|
|
624
|
-
// getMemberByContactEmail) — an exact `.eq` is a case-insensitive lookup.
|
|
625
|
-
const normalized = normalizeEmail(email);
|
|
626
|
-
if (!normalized) return null;
|
|
627
|
-
const members = await wixData
|
|
628
|
-
.query(COLLECTIONS.MEMBERS_DATA)
|
|
629
|
-
.eq('email', normalized)
|
|
630
|
-
.limit(2)
|
|
631
|
-
.find()
|
|
632
|
-
.then(res => res.items);
|
|
633
|
-
if (members.length > 1) {
|
|
634
|
-
throw new Error(
|
|
635
|
-
`[getMemberByEmail] Multiple members found with email ${email} membersIds are : [${members.map(member => member.memberId).join(', ')}]`
|
|
636
|
-
);
|
|
637
|
-
}
|
|
638
|
-
return members[0] || null;
|
|
639
|
-
} catch (error) {
|
|
640
|
-
console.error('Error getting member by email:', error);
|
|
641
|
-
throw new Error(`Failed to get member by email: ${error.message}`);
|
|
642
|
-
}
|
|
643
|
-
};
|
|
644
|
-
|
|
645
|
-
const getQAUsers = async () => {
|
|
646
|
-
try {
|
|
647
|
-
return await wixData
|
|
648
|
-
.query(COLLECTIONS.QA_USERS)
|
|
649
|
-
.include('member')
|
|
650
|
-
.find()
|
|
651
|
-
.then(res => res.items.map(item => item.member));
|
|
652
|
-
} catch (error) {
|
|
653
|
-
console.error('Error getting QA users:', error);
|
|
654
|
-
throw new Error(`Failed to get QA users: ${error.message}`);
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
|
-
/**
|
|
658
|
-
* Ensures member has a contact - creates one if missing
|
|
659
|
-
* @param {Object} memberData - Member data from DB
|
|
660
|
-
* @returns {Promise<Object>} - Member data with contact and member IDs
|
|
661
|
-
*/
|
|
662
|
-
async function ensureWixMemberAndContactExist(memberData) {
|
|
663
|
-
if (!memberData) {
|
|
664
|
-
throw new Error('Member data is required');
|
|
665
|
-
}
|
|
666
|
-
if (!memberData.wixContactId || !memberData.wixMemberId) {
|
|
667
|
-
const memberDataWithContactId = await createContactAndMemberIfNew(memberData);
|
|
668
|
-
return memberDataWithContactId;
|
|
669
|
-
}
|
|
670
|
-
return memberData;
|
|
671
|
-
}
|
|
672
|
-
async function prepareMemberForSSOLogin(data) {
|
|
673
|
-
try {
|
|
674
|
-
console.log('data', data);
|
|
675
|
-
const memberId = data?.pac?.cst_recno;
|
|
676
|
-
if (!memberId) {
|
|
677
|
-
throw new Error(`Member ID is missing in passed data ${JSON.stringify(data)}`);
|
|
678
|
-
}
|
|
679
|
-
const memberData = await findMemberById(Number(memberId));
|
|
680
|
-
if (!memberData) {
|
|
681
|
-
throw new Error(`Member data not found for memberId ${memberId}`);
|
|
682
|
-
}
|
|
683
|
-
console.log('memberData', memberData);
|
|
684
|
-
return await ensureWixMemberAndContactExist(memberData);
|
|
685
|
-
} catch (error) {
|
|
686
|
-
console.error(`Error in prepareMemberForSSOLogin: ${error.message}`);
|
|
687
|
-
throw error;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
async function prepareMemberForQALogin(email) {
|
|
691
|
-
try {
|
|
692
|
-
console.log('qa email:', email);
|
|
693
|
-
if (!email) {
|
|
694
|
-
throw new Error(`Email is missing in passed data ${email}`);
|
|
695
|
-
}
|
|
696
|
-
const memberData = await getMemberByEmail(email);
|
|
697
|
-
if (!memberData) {
|
|
698
|
-
throw new Error(`Member data not found for email ${email}`);
|
|
699
|
-
}
|
|
700
|
-
console.log('memberData', memberData);
|
|
701
|
-
return await ensureWixMemberAndContactExist(memberData);
|
|
702
|
-
} catch (error) {
|
|
703
|
-
const errMsg = `[prepareMemberForQALogin] QA Login failed with error: ${error.message} for email: ${email}`;
|
|
704
|
-
console.error(errMsg);
|
|
705
|
-
throw new Error(errMsg);
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
/**
|
|
710
|
-
* Tracks a button click with member and location info.
|
|
711
|
-
* @param {Object} params - Parameters
|
|
712
|
-
* @param {string} params.pageName - Name of the page/popup where button was clicked
|
|
713
|
-
* @param {string} params.buttonName - Name/ID of the button that was clicked
|
|
714
|
-
* @param {Object} [params.data] - Optional data object to store with the click (e.g., form data being saved)
|
|
715
|
-
* @returns {Promise<Object>} - Saved record or null if member not found
|
|
716
|
-
*/
|
|
717
|
-
async function trackButtonClick({ pageName, buttonName, data }) {
|
|
718
|
-
const wixMember = await getCurrentMember();
|
|
719
|
-
|
|
720
|
-
if (!wixMember) {
|
|
721
|
-
console.warn('[trackButtonClick]: No logged in member found');
|
|
722
|
-
return null;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
const dbMember = await getCMSMemberByWixMemberId(wixMember._id);
|
|
726
|
-
|
|
727
|
-
if (!dbMember) {
|
|
728
|
-
console.warn(
|
|
729
|
-
`[trackButtonClick]: Member not found in MembersDataLatest for wixMemberId: ${wixMember._id}`
|
|
730
|
-
);
|
|
731
|
-
return null;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
const memberName = dbMember.fullName || 'Unknown';
|
|
735
|
-
const memberId = dbMember.memberId;
|
|
736
|
-
const memberEmail = dbMember.email;
|
|
737
|
-
|
|
738
|
-
const clickData = {
|
|
739
|
-
memberName,
|
|
740
|
-
memberId,
|
|
741
|
-
pageName,
|
|
742
|
-
buttonName,
|
|
743
|
-
memberEmail,
|
|
744
|
-
clickedAt: new Date(),
|
|
745
|
-
...(data && { data }),
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
try {
|
|
749
|
-
const result = await wixData.insert(COLLECTIONS.BUTTON_CLICKS, clickData);
|
|
750
|
-
console.log(`Tracked ${buttonName} click on ${pageName} for member ${memberId}`);
|
|
751
|
-
return result;
|
|
752
|
-
} catch (error) {
|
|
753
|
-
console.error(`Error tracking ${buttonName} click:`, error);
|
|
754
|
-
throw error;
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
async function getAllMembersWithWixMemberId() {
|
|
759
|
-
const membersQuery = wixData.query(COLLECTIONS.MEMBERS_DATA).isNotEmpty('wixMemberId');
|
|
760
|
-
return await queryAllItems(membersQuery);
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
module.exports = {
|
|
764
|
-
findMemberByWixDataId,
|
|
765
|
-
createContactAndMemberIfNew,
|
|
766
|
-
getAllMembersWithWixMemberId,
|
|
767
|
-
saveRegistrationData,
|
|
768
|
-
bulkSaveMembers,
|
|
769
|
-
findMemberById,
|
|
770
|
-
findMembersByIds,
|
|
771
|
-
getMemberBySlug,
|
|
772
|
-
getCMSMemberByWixMemberId,
|
|
773
|
-
getAllEmptyAboutYouMembers,
|
|
774
|
-
updateMember,
|
|
775
|
-
getAllMembersWithExternalImages,
|
|
776
|
-
getMembersWithWixUrl,
|
|
777
|
-
getAllMembersWithoutContactFormEmail,
|
|
778
|
-
getAllMembersNeedingEmailNormalization,
|
|
779
|
-
memberNeedsEmailNormalization,
|
|
780
|
-
getAllUpdatedLoginEmails,
|
|
781
|
-
getMembersByIds,
|
|
782
|
-
getMemberByEmail,
|
|
783
|
-
getQAUsers,
|
|
784
|
-
prepareMemberForSSOLogin,
|
|
785
|
-
prepareMemberForQALogin,
|
|
786
|
-
checkUrlUniqueness,
|
|
787
|
-
trackButtonClick,
|
|
788
|
-
isEmailAlreadyUsed,
|
|
789
|
-
};
|