abmp-npm 1.8.25 → 1.8.26
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/backend/members-data-methods.js +173 -1
- package/backend/utils.js +47 -1
- package/package.json +1 -1
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
const { contacts } = require('@wix/crm');
|
|
2
|
+
|
|
1
3
|
const { COLLECTIONS } = require('../public/consts');
|
|
2
4
|
|
|
3
5
|
const { MEMBER_ACTIONS } = require('./consts');
|
|
4
6
|
const { wixData } = require('./elevated-modules');
|
|
5
7
|
const { createSiteMember, getCurrentMember } = require('./members-area-methods');
|
|
6
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
formatDateToMonthYear,
|
|
10
|
+
getAddressDisplayOptions,
|
|
11
|
+
isStudent,
|
|
12
|
+
generateGeoHash,
|
|
13
|
+
urlExists,
|
|
14
|
+
} = require('./utils');
|
|
7
15
|
|
|
8
16
|
/**
|
|
9
17
|
* Retrieves member data by member ID
|
|
@@ -124,8 +132,172 @@ async function validateMemberToken(memberIdInput) {
|
|
|
124
132
|
}
|
|
125
133
|
}
|
|
126
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Generic contact update helper function
|
|
137
|
+
* @param {string} contactId - The contact ID in Wix CRM
|
|
138
|
+
* @param {function} updateInfoCallback - Function that returns the updated info object
|
|
139
|
+
* @param {string} operationName - Name of the operation for logging
|
|
140
|
+
*/
|
|
141
|
+
async function updateContactInfo(contactId, updateInfoCallback, operationName) {
|
|
142
|
+
if (!contactId) {
|
|
143
|
+
throw new Error('Contact ID is required');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const contact = await contacts.getContact(contactId);
|
|
148
|
+
const currentInfo = contact.info;
|
|
149
|
+
const updatedInfo = updateInfoCallback(currentInfo);
|
|
150
|
+
|
|
151
|
+
await contacts.updateContact(contactId, { info: updatedInfo });
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error(`Error in ${operationName}:`, error);
|
|
154
|
+
throw new Error(`Failed to ${operationName}: ${error.message}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Updates contact email in Wix CRM
|
|
160
|
+
* @param {string} contactId - The contact ID in Wix CRM
|
|
161
|
+
* @param {string} newEmail - The new email address
|
|
162
|
+
*/
|
|
163
|
+
async function updateContactEmail(contactId, newEmail) {
|
|
164
|
+
if (!newEmail) {
|
|
165
|
+
throw new Error('New email is required');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return updateContactInfo(
|
|
169
|
+
contactId,
|
|
170
|
+
currentInfo => ({
|
|
171
|
+
...currentInfo,
|
|
172
|
+
emails: {
|
|
173
|
+
items: [
|
|
174
|
+
{
|
|
175
|
+
email: newEmail,
|
|
176
|
+
primary: true,
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
'update contact email'
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Updates contact names in Wix CRM
|
|
187
|
+
* @param {string} contactId - The contact ID in Wix CRM
|
|
188
|
+
* @param {string} firstName - The new first name
|
|
189
|
+
* @param {string} lastName - The new last name
|
|
190
|
+
*/
|
|
191
|
+
async function updateContactNames(contactId, firstName, lastName) {
|
|
192
|
+
if (!firstName && !lastName) {
|
|
193
|
+
throw new Error('At least one name field is required');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return updateContactInfo(
|
|
197
|
+
contactId,
|
|
198
|
+
currentInfo => ({
|
|
199
|
+
...currentInfo,
|
|
200
|
+
name: {
|
|
201
|
+
first: firstName || currentInfo?.name?.first || '',
|
|
202
|
+
last: lastName || currentInfo?.name?.last || '',
|
|
203
|
+
},
|
|
204
|
+
}),
|
|
205
|
+
'update contact names'
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Update fields if they have changed
|
|
211
|
+
* @param {Array} existingValues - Current values for comparison
|
|
212
|
+
* @param {Array} newValues - New values to compare against
|
|
213
|
+
* @param {Function} updater - Function to call if values changed
|
|
214
|
+
* @param {Function} argsBuilder - Function to build arguments for updater
|
|
215
|
+
*/
|
|
216
|
+
const updateIfChanged = (existingValues, newValues, updater, argsBuilder) => {
|
|
217
|
+
const hasChanged = existingValues.some((val, idx) => val !== newValues[idx]);
|
|
218
|
+
if (!hasChanged) return null;
|
|
219
|
+
return updater(...argsBuilder(newValues));
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Updates member contact information in CRM if fields have changed
|
|
224
|
+
* @param {string} id - Member ID
|
|
225
|
+
* @param {Object} data - New member data
|
|
226
|
+
*/
|
|
227
|
+
const updateMemberContactInfo = async (id, data) => {
|
|
228
|
+
const existing = await findMemberByWixDataId(id);
|
|
229
|
+
const { contactId } = existing;
|
|
230
|
+
|
|
231
|
+
const updateConfig = [
|
|
232
|
+
{
|
|
233
|
+
fields: ['contactFormEmail'],
|
|
234
|
+
updater: updateContactEmail,
|
|
235
|
+
args: ([email]) => [contactId, email],
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
fields: ['firstName', 'lastName'],
|
|
239
|
+
updater: updateContactNames,
|
|
240
|
+
args: ([firstName, lastName]) => [contactId, firstName, lastName],
|
|
241
|
+
},
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
const updatePromises = updateConfig
|
|
245
|
+
.map(({ fields, updater, args }) => {
|
|
246
|
+
const existingValues = fields.map(field => existing[field]);
|
|
247
|
+
const newValues = fields.map(field => data[field]);
|
|
248
|
+
return updateIfChanged(existingValues, newValues, updater, args);
|
|
249
|
+
})
|
|
250
|
+
.filter(Boolean);
|
|
251
|
+
|
|
252
|
+
await Promise.all(updatePromises);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Saves member registration data
|
|
257
|
+
* @param {Object} data - Member data to save
|
|
258
|
+
* @param {string} id - Member ID
|
|
259
|
+
* @returns {Promise<Object>} Result object with type and data/error
|
|
260
|
+
*/
|
|
261
|
+
async function saveRegistrationData(data, id) {
|
|
262
|
+
try {
|
|
263
|
+
console.log(' saveRegistrationData data._id', data._id);
|
|
264
|
+
console.log(' saveRegistrationData id', id);
|
|
265
|
+
if (data._id !== id) return { type: 'notAuthorized' };
|
|
266
|
+
|
|
267
|
+
if (data.url) {
|
|
268
|
+
const isDuplicate = await urlExists(data.url, data.memberId);
|
|
269
|
+
|
|
270
|
+
if (isDuplicate) {
|
|
271
|
+
return {
|
|
272
|
+
type: 'error',
|
|
273
|
+
error: 'URL slug is already taken. Please choose a different one.',
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (data.addresses && Array.isArray(data.addresses)) {
|
|
279
|
+
data.locHash = generateGeoHash(data.addresses);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
await updateMemberContactInfo(id, data);
|
|
283
|
+
|
|
284
|
+
const saveData = await wixData.update(COLLECTIONS.MEMBERS_DATA, data);
|
|
285
|
+
return {
|
|
286
|
+
type: 'success',
|
|
287
|
+
saveData,
|
|
288
|
+
};
|
|
289
|
+
} catch (error) {
|
|
290
|
+
console.error(error);
|
|
291
|
+
return {
|
|
292
|
+
type: 'error',
|
|
293
|
+
error,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
127
298
|
module.exports = {
|
|
128
299
|
findMemberByWixDataId,
|
|
129
300
|
createContactAndMemberIfNew,
|
|
130
301
|
validateMemberToken,
|
|
302
|
+
saveRegistrationData,
|
|
131
303
|
};
|
package/backend/utils.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
const { encode } = require('ngeohash');
|
|
2
|
+
|
|
1
3
|
const { COLLECTIONS } = require('../public/consts');
|
|
2
4
|
|
|
3
|
-
const { CONFIG_KEYS } = require('./consts');
|
|
5
|
+
const { CONFIG_KEYS, PRECISION } = require('./consts');
|
|
4
6
|
const { wixData } = require('./elevated-modules');
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -104,6 +106,48 @@ async function getInterestAll() {
|
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Generate geohash from addresses
|
|
111
|
+
* @param {Array} addresses - Array of address objects with latitude and longitude
|
|
112
|
+
* @returns {Array} Array of geohash strings
|
|
113
|
+
*/
|
|
114
|
+
function generateGeoHash(addresses) {
|
|
115
|
+
const geohash = addresses
|
|
116
|
+
?.filter(address => (isNaN(address?.latitude) && isNaN(address?.longitude) ? false : address))
|
|
117
|
+
?.map(address => encode(address.latitude, address.longitude, PRECISION));
|
|
118
|
+
return geohash && geohash.length > 0 ? geohash : [];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Checks if a URL already exists in the database for a different member (case-insensitive)
|
|
123
|
+
* @param {string} url - The URL to check
|
|
124
|
+
* @param {string|number} excludeMemberId - Member ID to exclude from the check
|
|
125
|
+
* @returns {Promise<boolean>} - True if URL exists for another member
|
|
126
|
+
*/
|
|
127
|
+
async function urlExists(url, excludeMemberId) {
|
|
128
|
+
if (!url) return false;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
let query = wixData.query(COLLECTIONS.MEMBERS_DATA).contains('url', url).ne('action', 'drop');
|
|
132
|
+
|
|
133
|
+
if (excludeMemberId) {
|
|
134
|
+
query = query.ne('memberId', excludeMemberId);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const { items } = await query.find();
|
|
138
|
+
|
|
139
|
+
// Case-insensitive comparison
|
|
140
|
+
const matchingMembers = items.filter(
|
|
141
|
+
item => item.url && item.url.toLowerCase() === url.toLowerCase()
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
return matchingMembers.length > 0;
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error('Error checking URL existence:', error);
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
107
151
|
module.exports = {
|
|
108
152
|
getSiteConfigs,
|
|
109
153
|
retrieveAllItems,
|
|
@@ -111,4 +155,6 @@ module.exports = {
|
|
|
111
155
|
isStudent,
|
|
112
156
|
getAddressDisplayOptions,
|
|
113
157
|
getInterestAll,
|
|
158
|
+
generateGeoHash,
|
|
159
|
+
urlExists,
|
|
114
160
|
};
|