abmp-npm 1.1.90 → 1.1.91

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.
@@ -3,7 +3,33 @@ const { auth } = require('@wix/essentials');
3
3
 
4
4
  const elevatedGetContact = auth.elevate(contacts.getContact);
5
5
  const elevatedUpdateContact = auth.elevate(contacts.updateContact);
6
+ const elevatedCreateContact = auth.elevate(contacts.createContact);
6
7
 
8
+ /**
9
+ * Create a contact in Wix CRM
10
+ * @param {Object} contactData - Contact data
11
+ * @param {boolean} allowDuplicates - Allow duplicates if contact with same email already exists, will be true only when handling existing members, after that should be removed
12
+ * @returns {Promise<Object>} - Contact data
13
+ */
14
+ async function createContact(contactData, allowDuplicates = false) {
15
+ if (!contactData || !(contactData.contactFormEmail || contactData.email)) {
16
+ throw new Error('Contact data is required');
17
+ }
18
+ const phones =
19
+ Array.isArray(contactData.phones) && contactData.phones.length > 0 ? contactData.phones : [];
20
+ const contactInfo = {
21
+ name: {
22
+ first: contactData.firstName,
23
+ last: contactData.lastName,
24
+ },
25
+ emails: [
26
+ { items: [{ email: contactData.contactFormEmail || contactData.email, primary: true }] },
27
+ ],
28
+ phones: [{ items: phones.map(phone => ({ phone })) }],
29
+ };
30
+ const createContactResponse = await elevatedCreateContact(contactInfo, { allowDuplicates });
31
+ return createContactResponse.contact._id;
32
+ }
7
33
  /**
8
34
  * Generic contact update helper function
9
35
  * @param {string} contactId - The contact ID in Wix CRM
@@ -14,18 +40,13 @@ async function updateContactInfo(contactId, updateInfoCallback, operationName) {
14
40
  if (!contactId) {
15
41
  throw new Error('Contact ID is required');
16
42
  }
17
- console.log('updateContactInfo contactId', contactId);
18
- console.log('updateContactInfo operationName', operationName);
43
+
19
44
  try {
20
45
  const contact = await elevatedGetContact(contactId);
21
- console.log('updateContactInfo contact', contact);
22
46
  const currentInfo = contact.info;
23
- console.log('updateContactInfo currentInfo', currentInfo);
24
47
  const updatedInfo = updateInfoCallback(currentInfo);
25
- console.log('updateContactInfo updatedInfo', updatedInfo);
26
- const updatedContact = await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
27
- console.log('updateContactInfo updatedContact', updatedContact);
28
- return updatedContact;
48
+
49
+ await elevatedUpdateContact(contactId, updatedInfo, contact.revision);
29
50
  } catch (error) {
30
51
  console.error(`Error in ${operationName}:`, error);
31
52
  throw new Error(`Failed to ${operationName}: ${error.message}`);
@@ -38,8 +59,6 @@ async function updateContactInfo(contactId, updateInfoCallback, operationName) {
38
59
  * @param {string} newEmail - The new email address
39
60
  */
40
61
  async function updateContactEmail(contactId, newEmail) {
41
- console.log('updateContactEmail contactId', contactId);
42
- console.log('updateContactEmail newEmail', newEmail);
43
62
  if (!newEmail) {
44
63
  throw new Error('New email is required');
45
64
  }
@@ -62,27 +81,33 @@ async function updateContactEmail(contactId, newEmail) {
62
81
  }
63
82
 
64
83
  /**
65
- * Updates contact names in Wix CRM
66
- * @param {string} contactId - The contact ID in Wix CRM
67
- * @param {string} firstName - The new first name
68
- * @param {string} lastName - The new last name
84
+ * Updates contact names in Wix CRM for both contact and member
85
+ * @param {Object} params - Parameters object
86
+ * @param {string} params.wixContactId - The contact ID in Wix CRM
87
+ * @param {string} params.wixMemberId - The member ID in Wix CRM
88
+ * @param {string} params.firstName - The new first name
89
+ * @param {string} params.lastName - The new last name
69
90
  */
70
- async function updateContactNames(contactId, firstName, lastName) {
91
+ async function updateMemberAndContactNames({ wixContactId, wixMemberId, firstName, lastName }) {
92
+ //TODO: rethink if we should keep all info just in contact, meaning no need to update the member
71
93
  if (!firstName && !lastName) {
72
94
  throw new Error('At least one name field is required');
73
95
  }
74
96
 
75
- return await updateContactInfo(
76
- contactId,
77
- currentInfo => ({
78
- ...currentInfo,
79
- name: {
80
- first: firstName || currentInfo?.name?.first || '',
81
- last: lastName || currentInfo?.name?.last || '',
82
- },
83
- }),
84
- 'update contact names'
85
- );
97
+ const createNameUpdate = currentInfo => ({
98
+ ...currentInfo,
99
+ name: {
100
+ first: firstName || currentInfo?.name?.first || '',
101
+ last: lastName || currentInfo?.name?.last || '',
102
+ },
103
+ });
104
+
105
+ const updatePromises = [
106
+ wixContactId && updateContactInfo(wixContactId, createNameUpdate, 'update contact names'),
107
+ wixMemberId && updateContactInfo(wixMemberId, createNameUpdate, 'update member names'),
108
+ ].filter(Boolean);
109
+
110
+ return await Promise.all(updatePromises);
86
111
  }
87
112
 
88
113
  /**
@@ -95,7 +120,6 @@ async function updateContactNames(contactId, firstName, lastName) {
95
120
  const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
96
121
  const hasChanged = existingValues.some((val, idx) => val !== newValues[idx]);
97
122
  if (!hasChanged) return null;
98
- console.log('updateIfChanged hasChanged', hasChanged);
99
123
  return updater(...argsBuilder(newValues));
100
124
  };
101
125
 
@@ -105,18 +129,18 @@ const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
105
129
  * @param {Object} existingMemberData - Existing member data
106
130
  */
107
131
  const updateMemberContactInfo = async (data, existingMemberData) => {
108
- const { contactId } = existingMemberData;
109
- console.log('updateMemberContactInfo contactId', contactId);
132
+ const { wixContactId, wixMemberId } = existingMemberData;
133
+
110
134
  const updateConfig = [
111
135
  {
112
136
  fields: ['contactFormEmail'],
113
137
  updater: updateContactEmail,
114
- args: ([email]) => [contactId, email],
138
+ args: ([email]) => [wixContactId, email],
115
139
  },
116
140
  {
117
141
  fields: ['firstName', 'lastName'],
118
- updater: updateContactNames,
119
- args: ([firstName, lastName]) => [contactId, firstName, lastName],
142
+ updater: updateMemberAndContactNames,
143
+ args: ([firstName, lastName]) => [{ firstName, lastName, wixContactId, wixMemberId }],
120
144
  },
121
145
  ];
122
146
 
@@ -128,11 +152,10 @@ const updateMemberContactInfo = async (data, existingMemberData) => {
128
152
  })
129
153
  .filter(Boolean);
130
154
 
131
- const resp = await Promise.all(updatePromises);
132
- console.log('updateMemberContactInfo updatePromises', resp);
133
- return resp;
155
+ await Promise.all(updatePromises);
134
156
  };
135
157
 
136
158
  module.exports = {
137
159
  updateMemberContactInfo,
160
+ createContact,
138
161
  };
@@ -168,7 +168,7 @@ const bulkProcessAndSaveMemberData = async ({
168
168
  const toChangeWixMembersEmails = [];
169
169
  const toSaveMembersData = uniqueUrlsMembersData.map(member => {
170
170
  const { isLoginEmailChanged, isNewToDb: _isNewToDb, ...restMemberData } = member;
171
- if (member.contactId && isLoginEmailChanged) {
171
+ if (member.wixMemberId && isLoginEmailChanged) {
172
172
  toChangeWixMembersEmails.push(member);
173
173
  }
174
174
  return restMemberData; //we don't want to store the isLoginEmailChanged in the database, it's just a flag to know if we need to change the login email in Members area
@@ -35,7 +35,17 @@ const extractBaseUrl = url => {
35
35
  return url;
36
36
  };
37
37
  const incrementUrlCounter = (existingUrl, baseUrl) => {
38
- if (existingUrl && existingUrl === baseUrl) {
38
+ if (!existingUrl || !baseUrl) {
39
+ return baseUrl;
40
+ }
41
+ // Normalize for comparison (case-insensitive)
42
+ const normalizedExisting = existingUrl.toLowerCase();
43
+ const normalizedBase = baseUrl.toLowerCase();
44
+
45
+ if (
46
+ normalizedExisting === normalizedBase ||
47
+ normalizedExisting.startsWith(`${normalizedBase}-`)
48
+ ) {
39
49
  console.log(
40
50
  `Found member with same url ${existingUrl} for baseUrl ${baseUrl}, increasing counter by 1`
41
51
  );
@@ -44,6 +54,9 @@ const incrementUrlCounter = (existingUrl, baseUrl) => {
44
54
  const lastCounter = isNumeric ? parseInt(lastSegment, 10) : 0;
45
55
  return `${baseUrl}-${lastCounter + 1}`;
46
56
  }
57
+
58
+ // No conflict, return baseUrl with counter 1 to be safe
59
+ return `${baseUrl}-1`;
47
60
  };
48
61
  /**
49
62
  * Validates core member data requirements
@@ -1,3 +1,5 @@
1
+ const { COLLECTIONS } = require('../public/consts');
2
+
1
3
  const { ensureUniqueUrlsInBatch } = require('./daily-pull/bulk-process-methods');
2
4
  const { wixData } = require('./elevated-modules');
3
5
  const { bulkSaveMembers } = require('./members-data-methods');
@@ -15,4 +17,14 @@ async function deduplicateURls(collectionName, duplicateUrlsList) {
15
17
  return await bulkSaveMembers(membersWithUniqueUrls, collectionName);
16
18
  }
17
19
 
18
- module.exports = { deduplicateURls };
20
+ async function copyContactIdToWixMemberId() {
21
+ const query = wixData.query(COLLECTIONS.MEMBERS_DATA).isNotEmpty('contactId');
22
+ const members = await queryAllItems(query);
23
+ const updatedMembers = members.map(member => ({
24
+ ...member,
25
+ wixMemberId: member.contactId,
26
+ }));
27
+ return await bulkSaveMembers(updatedMembers, COLLECTIONS.MEMBERS_DATA);
28
+ }
29
+
30
+ module.exports = { deduplicateURls, copyContactIdToWixMemberId };
@@ -16,7 +16,7 @@ const contactSubmission = async (data, memberDataId) => {
16
16
  console.log('Member contact form is not enabled for user, skipping contact submission!');
17
17
  return;
18
18
  }
19
- let memberContactId = memberData.contactId;
19
+ let memberContactId = memberData.wixContactId;
20
20
  if (!memberContactId) {
21
21
  /**
22
22
  * Create a member contact here since some members may have never logged in
@@ -27,7 +27,7 @@ const contactSubmission = async (data, memberDataId) => {
27
27
  */
28
28
  console.info('Member contact id not found for user, creating new contact!');
29
29
  const member = await createContactAndMemberIfNew(memberData);
30
- memberContactId = member.contactId;
30
+ memberContactId = member.wixContactId;
31
31
  }
32
32
  console.log('memberContactId', memberContactId);
33
33
  const emailTriggered = await triggerAutomation(automationEmailTriggerId, {
@@ -40,7 +40,7 @@ const contactSubmission = async (data, memberDataId) => {
40
40
  data = {
41
41
  ...data,
42
42
  phone: Number(data.phone),
43
- memberContactId: memberContactId,
43
+ memberContactId,
44
44
  memberEmail: memberData.contactFormEmail,
45
45
  };
46
46
  await wixData.insert(COLLECTIONS.CONTACT_US_SUBMISSIONS, data);
@@ -2,10 +2,11 @@ const { auth } = require('@wix/essentials');
2
2
  const { members, authentication } = require('@wix/members');
3
3
  const elevatedCreateMember = auth.elevate(members.createMember);
4
4
 
5
- function prepareContactData(partner) {
5
+ function prepareMemberData(partner) {
6
6
  const phones = Array.isArray(partner.phones) ? partner.phones : []; //some users don't have phones
7
7
  const options = {
8
8
  member: {
9
+ //Keeping contact creation in member data for future purposes, in case we need to use it later
9
10
  contact: {
10
11
  ...partner,
11
12
  phones,
@@ -22,9 +23,8 @@ async function createMemberFunction(member) {
22
23
  }
23
24
  const createSiteMember = async memberDetails => {
24
25
  try {
25
- const options = prepareContactData(memberDetails);
26
- const contactId = await createMemberFunction(options);
27
- return contactId;
26
+ const options = prepareMemberData(memberDetails);
27
+ return await createMemberFunction(options);
28
28
  } catch (error) {
29
29
  console.error(`Error in createSiteMember ${error.message}`);
30
30
  throw error;
@@ -37,22 +37,25 @@ const getCurrentMember = async () => {
37
37
  };
38
38
 
39
39
  /**
40
- * Updates Wix member login email if the member has a contactId (registered Wix member)
41
- * @param {Object} member - Member object with contactId and email
40
+ * Updates Wix member login email if the member has a wixMemberId (registered Wix member)
41
+ * @param {Object} member - Member object with wixMemberId and email
42
42
  * @param {Object} result - Result object to track Wix member updates
43
43
  */
44
44
  async function updateWixMemberLoginEmail(member, result = {}) {
45
- if (!member.contactId) {
46
- console.log(`Member ${member.memberId} has no contactId - skipping Wix login email update`);
45
+ if (!member.wixMemberId) {
46
+ console.log(`Member ${member.memberId} has no wixMemberId - skipping Wix login email update`);
47
47
  return;
48
48
  }
49
49
 
50
50
  try {
51
51
  console.log(
52
- `Updating Wix login email for member ${member.memberId} (contactId: ${member.contactId})`
52
+ `Updating Wix login email for member ${member.memberId} (wixMemberId: ${member.wixMemberId})`
53
53
  );
54
54
 
55
- const updatedWixMember = await authentication.changeLoginEmail(member.contactId, member.email);
55
+ const updatedWixMember = await authentication.changeLoginEmail(
56
+ member.wixMemberId,
57
+ member.email
58
+ );
56
59
 
57
60
  console.log(
58
61
  `✅ Successfully updated Wix login email for member ${member.memberId}: ${updatedWixMember.loginEmail}`
@@ -75,7 +78,7 @@ async function updateWixMemberLoginEmail(member, result = {}) {
75
78
  }
76
79
  result.wixMemberErrors.push({
77
80
  memberId: member.memberId,
78
- contactId: member.contactId,
81
+ wixMemberId: member.wixMemberId,
79
82
  email: member.email,
80
83
  error: error.message,
81
84
  });
@@ -1,10 +1,10 @@
1
1
  const { COLLECTIONS } = require('../public/consts');
2
2
 
3
3
  const { MEMBERSHIPS_TYPES } = require('./consts');
4
- const { updateMemberContactInfo } = require('./contacts-methods');
4
+ const { updateMemberContactInfo, createContact } = require('./contacts-methods');
5
5
  const { MEMBER_ACTIONS } = require('./daily-pull/consts');
6
6
  const { wixData } = require('./elevated-modules');
7
- const { createSiteMember } = require('./members-area-methods');
7
+ const { createSiteMember, getCurrentMember } = require('./members-area-methods');
8
8
  const {
9
9
  chunkArray,
10
10
  normalizeUrlForComparison,
@@ -42,10 +42,14 @@ async function createContactAndMemberIfNew(memberData) {
42
42
  phones: memberData.phones,
43
43
  contactFormEmail: memberData.contactFormEmail || memberData.email,
44
44
  };
45
- const contactId = await createSiteMember(toCreateMemberData);
45
+ const [wixMemberId, wixContactId] = await Promise.all([
46
+ createSiteMember(toCreateMemberData),
47
+ createContact(toCreateMemberData),
48
+ ]);
46
49
  let memberDataWithContactId = {
47
50
  ...memberData,
48
- contactId,
51
+ wixMemberId,
52
+ wixContactId,
49
53
  };
50
54
  const updatedResult = await updateMember(memberDataWithContactId);
51
55
  memberDataWithContactId = {
@@ -498,9 +502,60 @@ async function prepareMemberForQALogin(email) {
498
502
  }
499
503
  }
500
504
 
505
+ /**
506
+ * Tracks a button click with member and location info.
507
+ * @param {Object} params - Parameters
508
+ * @param {string} params.pageName - Name of the page/popup where button was clicked
509
+ * @param {string} params.buttonName - Name/ID of the button that was clicked
510
+ * @returns {Promise<Object>} - Saved record or null if member not found
511
+ */
512
+ async function trackButtonClick({ pageName, buttonName }) {
513
+ const wixMember = await getCurrentMember();
514
+
515
+ if (!wixMember) {
516
+ console.warn('[trackButtonClick]: No logged in member found');
517
+ return null;
518
+ }
519
+
520
+ const dbMember = await getMemberByContactId(wixMember._id);
521
+
522
+ if (!dbMember) {
523
+ console.warn(
524
+ `[trackButtonClick]: Member not found in MembersDataLatest for contactId: ${wixMember._id}`
525
+ );
526
+ return null;
527
+ }
528
+
529
+ const memberName = dbMember.fullName || 'Unknown';
530
+ const memberId = dbMember.memberId;
531
+
532
+ const clickData = {
533
+ memberName,
534
+ memberId,
535
+ pageName,
536
+ buttonName,
537
+ clickedAt: new Date(),
538
+ };
539
+
540
+ try {
541
+ const result = await wixData.insert(COLLECTIONS.BUTTON_CLICKS, clickData);
542
+ console.log(`Tracked ${buttonName} click on ${pageName} for member ${memberId}`);
543
+ return result;
544
+ } catch (error) {
545
+ console.error(`Error tracking ${buttonName} click:`, error);
546
+ throw error;
547
+ }
548
+ }
549
+
550
+ async function getAllMembersWithWixMemberId() {
551
+ const membersQuery = wixData.query(COLLECTIONS.MEMBERS_DATA).isNotEmpty('wixMemberId');
552
+ return await queryAllItems(membersQuery);
553
+ }
554
+
501
555
  module.exports = {
502
556
  findMemberByWixDataId,
503
557
  createContactAndMemberIfNew,
558
+ getAllMembersWithWixMemberId,
504
559
  saveRegistrationData,
505
560
  bulkSaveMembers,
506
561
  findMemberById,
@@ -518,4 +573,5 @@ module.exports = {
518
573
  prepareMemberForSSOLogin,
519
574
  prepareMemberForQALogin,
520
575
  checkUrlUniqueness,
576
+ trackButtonClick,
521
577
  };
@@ -16,6 +16,8 @@ const TASKS_NAMES = {
16
16
  migrateUrlsChunk: 'migrateUrlsChunk',
17
17
  scheduleGenerateMissingUrls: 'scheduleGenerateMissingUrls',
18
18
  generateUrlsChunk: 'generateUrlsChunk',
19
+ scheduleCreateContactsFromMembers: 'scheduleCreateContactsFromMembers',
20
+ createContactsFromMembers: 'createContactsFromMembers',
19
21
  };
20
22
 
21
23
  module.exports = {
@@ -16,6 +16,8 @@ const {
16
16
  migrateContactFormEmails,
17
17
  scheduleEmailSync,
18
18
  syncMemberLoginEmails,
19
+ scheduleCreateContactsFromMembers,
20
+ createContactsFromMembers,
19
21
  } = require('./tasks-process-methods');
20
22
  const {
21
23
  scheduleMigrateExistingUrls,
@@ -153,6 +155,20 @@ const TASKS = {
153
155
  shouldSkipCheck: () => false,
154
156
  estimatedDurationSec: 80,
155
157
  },
158
+ [TASKS_NAMES.scheduleCreateContactsFromMembers]: {
159
+ name: TASKS_NAMES.scheduleCreateContactsFromMembers,
160
+ getIdentifier: () => 'SHOULD_NEVER_SKIP',
161
+ process: scheduleCreateContactsFromMembers,
162
+ shouldSkipCheck: () => false,
163
+ estimatedDurationSec: 80,
164
+ },
165
+ [TASKS_NAMES.createContactsFromMembers]: {
166
+ name: TASKS_NAMES.createContactsFromMembers,
167
+ getIdentifier: task => task.data,
168
+ process: createContactsFromMembers,
169
+ shouldSkipCheck: () => false,
170
+ estimatedDurationSec: 80,
171
+ },
156
172
  };
157
173
 
158
174
  module.exports = { TASKS };
@@ -13,6 +13,8 @@ const {
13
13
  bulkSaveMembers,
14
14
  getAllUpdatedLoginEmails,
15
15
  getMembersByIds,
16
+ createContactAndMemberIfNew,
17
+ getAllMembersWithWixMemberId,
16
18
  } = require('../members-data-methods');
17
19
  const {
18
20
  getCompleteStateList,
@@ -530,6 +532,46 @@ const syncMemberLoginEmails = async data => {
530
532
  throw new Error(errorMessage);
531
533
  }
532
534
  };
535
+ /**
536
+ * Schedules tasks to create contacts from members
537
+ * dev-only task, run only once by the developers
538
+ */
539
+ const scheduleCreateContactsFromMembers = async () => {
540
+ const members = await getAllMembersWithWixMemberId();
541
+ console.log(
542
+ `Starting to schedule create contacts from members tasks for ${members.length} members in chunks of 500 members`
543
+ );
544
+ const membersChunks = chunkArray(members, 500);
545
+ for (let chunkIndex = 0; chunkIndex < membersChunks.length; chunkIndex++) {
546
+ const chunk = membersChunks[chunkIndex];
547
+ const toScheduleTask = {
548
+ name: TASKS_NAMES.createContactsFromMembers,
549
+ data: { chunk, chunkIndex },
550
+ };
551
+ await taskManager().schedule(toScheduleTask);
552
+ console.log(`Scheduled task for chunk ${chunkIndex} with ${chunk.length} members`);
553
+ }
554
+ console.log(`Successfully scheduled ${membersChunks.length} tasks for ${members.length} members`);
555
+ };
556
+
557
+ /**
558
+ * Creates contacts from members
559
+ * dev-only task, run only once by the developers
560
+ */
561
+ const createContactsFromMembers = async data => {
562
+ const { chunk, chunkIndex } = data;
563
+ console.log(`Creating contacts from ${chunk.length} members in chunk ${chunkIndex}`);
564
+ const createPromises = chunk.map(member => createContactAndMemberIfNew(member));
565
+ const createResults = await Promise.all(createPromises);
566
+ console.log(
567
+ `Created ${createResults.length} contacts from ${chunk.length} members in chunk ${chunkIndex}`
568
+ );
569
+ const saveResult = await bulkSaveMembers(createResults);
570
+ console.log(
571
+ `Successfully saved ${saveResult.totalSaved} contacts from ${chunk.length} members in chunk ${chunkIndex}`
572
+ );
573
+ return saveResult;
574
+ };
533
575
 
534
576
  module.exports = {
535
577
  scheduleTaskForEmptyAboutYouMembers,
@@ -542,4 +584,6 @@ module.exports = {
542
584
  migrateContactFormEmails,
543
585
  scheduleEmailSync,
544
586
  syncMemberLoginEmails,
587
+ scheduleCreateContactsFromMembers, // run only once by the developers
588
+ createContactsFromMembers,
545
589
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abmp-npm",
3
- "version": "1.1.90",
3
+ "version": "1.1.91",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "check-cycles": "madge --circular .",
package/pages/Home.js CHANGED
@@ -216,12 +216,19 @@ const homePageOnReady = async ({
216
216
  $item('#milesAwayText').text = '';
217
217
  }
218
218
 
219
- // 7) "Show maps" button enabled only if there's at least one visible address
219
+ // 7) "Show maps" button enabled only if there's a full address with valid coordinates
220
220
  const visible = checkAddressIsVisible(addresses);
221
- if (visible.length && visible[0].addressStatus === ADDRESS_STATUS_TYPES.FULL_ADDRESS) {
221
+ const fullAddressWithValidCoords = visible.find(
222
+ addr =>
223
+ addr.addressStatus === ADDRESS_STATUS_TYPES.FULL_ADDRESS &&
224
+ addr.latitude &&
225
+ addr.longitude
226
+ );
227
+
228
+ if (fullAddressWithValidCoords) {
222
229
  $item('#showMaps').enable();
223
230
  $item('#showMaps').show();
224
- const { latitude, longitude } = visible[0];
231
+ const { latitude, longitude } = fullAddressWithValidCoords;
225
232
  $item('#showMaps').link = `https://maps.google.com/?q=${latitude},${longitude}`;
226
233
  $item('#showMaps').target = '_blank';
227
234
  } else {
@@ -0,0 +1,27 @@
1
+ const PAGE_NAME = 'Learn More';
2
+ const BUTTON_NAME = 'Upgrade Now';
3
+
4
+ /**
5
+ * Creates the Learn More popup handler
6
+ * @param {Object} params - Parameters
7
+ * @param {Function} params.$w - Wix $w selector
8
+ * @param {Function} params.trackClick - Backend function to track the click (handles member lookup internally)
9
+ */
10
+ function learnMoreOnReady({ $w: _$w, trackClick }) {
11
+ _$w('#learnMoreBtn').onClick(async () => {
12
+ try {
13
+ await trackClick({
14
+ pageName: PAGE_NAME,
15
+ buttonName: BUTTON_NAME,
16
+ });
17
+
18
+ console.log(`Tracked ${BUTTON_NAME} click on ${PAGE_NAME}`);
19
+ } catch (error) {
20
+ console.error('Error tracking button click:', error);
21
+ }
22
+ });
23
+ }
24
+
25
+ module.exports = {
26
+ learnMoreOnReady,
27
+ };
package/pages/index.js CHANGED
@@ -8,4 +8,5 @@ module.exports = {
8
8
  ...require('./SelectBannerImages.js'),
9
9
  ...require('./deleteConfirm.js'),
10
10
  ...require('./SaveAlerts.js'),
11
+ ...require('./LearnMore.js'),
11
12
  };
package/public/consts.js CHANGED
@@ -13,6 +13,7 @@ const COLLECTIONS = {
13
13
  STATE_CITY_MAP: 'City',
14
14
  UPDATED_LOGIN_EMAILS: 'updatedLoginEmails',
15
15
  QA_USERS: 'QA_Users', //Make QA users configurable per site
16
+ BUTTON_CLICKS: 'ButtonClicks',
16
17
  };
17
18
 
18
19
  /**