abmp-npm 1.8.44 → 1.8.45
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/CONTACT_EMAIL_UPDATE_DEBUG.md +313 -0
- package/DEBUG_QUICKSTART.md +133 -0
- package/backend/cms-data-methods.js +8 -0
- package/backend/consts.js +22 -7
- package/backend/contacts-methods-DEBUG.js +237 -0
- package/backend/contacts-methods-TEST.js +271 -0
- package/backend/contacts-methods.js +6 -1
- package/backend/daily-pull/consts.js +0 -3
- package/backend/daily-pull/process-member-methods.js +1 -1
- package/backend/daily-pull/sync-to-cms-methods.js +10 -6
- package/backend/daily-pull/utils.js +3 -3
- package/backend/data-hooks.js +29 -0
- package/backend/elevated-modules.js +2 -0
- package/backend/http-functions/httpFunctions.js +86 -0
- package/backend/http-functions/index.js +3 -0
- package/backend/http-functions/interests.js +37 -0
- package/backend/index.js +6 -1
- package/backend/jobs.js +15 -3
- package/backend/login/index.js +7 -0
- package/backend/login/login-methods-factory.js +24 -0
- package/backend/login/qa-login-methods.js +72 -0
- package/backend/login/sso-methods.js +158 -0
- package/backend/members-data-methods.js +271 -94
- package/backend/pac-api-methods.js +3 -4
- package/backend/routers/index.js +3 -0
- package/backend/routers/methods.js +177 -0
- package/backend/routers/utils.js +118 -0
- package/backend/search-filters-methods.js +3 -0
- package/backend/tasks/consts.js +19 -0
- package/backend/tasks/index.js +6 -0
- package/backend/tasks/migration-methods.js +26 -0
- package/backend/tasks/tasks-configs.js +124 -0
- package/backend/tasks/tasks-helpers-methods.js +419 -0
- package/backend/tasks/tasks-process-methods.js +545 -0
- package/backend/test-methods.js +118 -0
- package/backend/utils.js +85 -41
- package/package.json +13 -2
- package/pages/LoadingPage.js +20 -0
- package/pages/Profile.js +2 -2
- package/pages/QAPage.js +39 -0
- package/pages/SaveAlerts.js +13 -0
- package/pages/SelectBannerImages.js +46 -0
- package/pages/deleteConfirm.js +19 -0
- package/pages/index.js +5 -0
- package/pages/personalDetails.js +12 -8
- package/public/consts.js +6 -23
- package/public/sso-auth-methods.js +43 -0
- package/backend/routers-methods.js +0 -182
- package/backend/routers-utils.js +0 -158
- package/backend/tasks.js +0 -37
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const { getMainAddress } = require('../../public/Utils/sharedUtils');
|
|
2
|
+
const { getMemberBySlug } = require('../members-data-methods');
|
|
3
|
+
const {
|
|
4
|
+
getAddressesByStatus,
|
|
5
|
+
formatDateToMonthYear,
|
|
6
|
+
hasStudentMembership,
|
|
7
|
+
isPAC_STAFF,
|
|
8
|
+
} = require('../utils');
|
|
9
|
+
|
|
10
|
+
function generateSEOTitle({ fullName, areasOfPractices, siteAssociation }) {
|
|
11
|
+
return `${fullName}${
|
|
12
|
+
areasOfPractices && areasOfPractices.length > 0
|
|
13
|
+
? ` | ${areasOfPractices.slice(0, 3).join(', ')}`
|
|
14
|
+
: ''
|
|
15
|
+
} | ${siteAssociation} Member`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function stripHtmlTags(html) {
|
|
19
|
+
if (!html) return '';
|
|
20
|
+
// Remove HTML tags and decode HTML entities
|
|
21
|
+
return html
|
|
22
|
+
.replace(/<[^>]*>/g, '') // Remove HTML tags
|
|
23
|
+
.replace(/ /g, ' ') // Replace non-breaking spaces
|
|
24
|
+
.replace(/&/g, '&') // Replace encoded ampersands
|
|
25
|
+
.replace(/</g, '<') // Replace encoded less than
|
|
26
|
+
.replace(/>/g, '>') // Replace encoded greater than
|
|
27
|
+
.replace(/"/g, '"') // Replace encoded quotes
|
|
28
|
+
.replace(/'/g, "'") // Replace encoded apostrophes
|
|
29
|
+
.replace(/\s+/g, ' ') // Replace multiple whitespace with single space
|
|
30
|
+
.trim(); // Remove leading/trailing whitespace
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function shouldHaveStudentBadge(member, siteAssociation) {
|
|
34
|
+
return hasStudentMembership({
|
|
35
|
+
member,
|
|
36
|
+
checkAssociation: true,
|
|
37
|
+
siteAssociation,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function transformMemberToProfileData(member, siteAssociation) {
|
|
42
|
+
if (!member) {
|
|
43
|
+
throw new Error('member is required');
|
|
44
|
+
}
|
|
45
|
+
const addresses = member.addresses || [];
|
|
46
|
+
const mainAddress = getMainAddress(member.addressDisplayOption, addresses);
|
|
47
|
+
const licenceNo = member.licenses
|
|
48
|
+
?.map(val => val.license)
|
|
49
|
+
.filter(Boolean)
|
|
50
|
+
.join(', ');
|
|
51
|
+
const processedAddresses = getAddressesByStatus(member.addresses, member.addressDisplayOption);
|
|
52
|
+
|
|
53
|
+
const memberships = member.memberships || [];
|
|
54
|
+
const siteAssociationMembership = memberships.find(m => m.association === siteAssociation);
|
|
55
|
+
|
|
56
|
+
const areasOfPractices =
|
|
57
|
+
member.areasOfPractices
|
|
58
|
+
?.filter(item => typeof item === 'string' && item.trim().length > 0)
|
|
59
|
+
.map(item => item.trim())
|
|
60
|
+
.sort((a, b) =>
|
|
61
|
+
a.localeCompare(b, undefined, {
|
|
62
|
+
sensitivity: 'base',
|
|
63
|
+
numeric: true,
|
|
64
|
+
})
|
|
65
|
+
) || [];
|
|
66
|
+
return {
|
|
67
|
+
mainAddress,
|
|
68
|
+
testimonials: member.testimonial || [],
|
|
69
|
+
licenceNo,
|
|
70
|
+
processedAddresses,
|
|
71
|
+
memberSince:
|
|
72
|
+
(member.showABMP &&
|
|
73
|
+
siteAssociationMembership &&
|
|
74
|
+
formatDateToMonthYear(siteAssociationMembership?.membersince)) ||
|
|
75
|
+
'',
|
|
76
|
+
shouldHaveStudentBadge: shouldHaveStudentBadge(member, siteAssociation),
|
|
77
|
+
logoImage: member.logoImage,
|
|
78
|
+
fullName: member.fullName,
|
|
79
|
+
profileImage: member.profileImage,
|
|
80
|
+
showContactForm: member.showContactForm,
|
|
81
|
+
bookingUrl: member.bookingUrl,
|
|
82
|
+
aboutService: member.aboutService,
|
|
83
|
+
businessName: (member.showBusinessName && member.businessName) || '',
|
|
84
|
+
phone: member.toShowPhone || '',
|
|
85
|
+
areasOfPractices,
|
|
86
|
+
gallery: member.gallery,
|
|
87
|
+
bannerImages: member.bannerImages,
|
|
88
|
+
showWixUrl: member.showWixUrl,
|
|
89
|
+
_id: member._id,
|
|
90
|
+
url: member.url,
|
|
91
|
+
isPrivateMember: isPAC_STAFF(member),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const getMemberProfileData = async (slug, siteAssociation) => {
|
|
96
|
+
try {
|
|
97
|
+
const member = await getMemberBySlug({
|
|
98
|
+
slug,
|
|
99
|
+
excludeDropped: true,
|
|
100
|
+
excludeSearchedMember: false,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (!member) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return transformMemberToProfileData(member, siteAssociation);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error(error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
module.exports = {
|
|
115
|
+
generateSEOTitle,
|
|
116
|
+
stripHtmlTags,
|
|
117
|
+
getMemberProfileData,
|
|
118
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const TASKS_NAMES = {
|
|
2
|
+
ScheduleDailyMembersDataSync: 'ScheduleDailyMembersDataSync',
|
|
3
|
+
ScheduleMembersDataPerAction: 'ScheduleMembersDataPerAction',
|
|
4
|
+
SyncMembers: 'SyncMembers',
|
|
5
|
+
scheduleTaskForEmptyAboutYouMembers: 'scheduleTaskForEmptyAboutYouMembers',
|
|
6
|
+
convertHtmlToRichContent: 'convertHtmlToRichContent',
|
|
7
|
+
CompileFiltersOptions: 'CompileFiltersOptions',
|
|
8
|
+
scheduleTaskForExternalProfileImages: 'scheduleTaskForExternalProfileImages',
|
|
9
|
+
convertExternalProfilesToWixImages: 'convertExternalProfilesToWixImages',
|
|
10
|
+
updateSiteMapS3: 'updateSiteMapS3',
|
|
11
|
+
scheduleEmailSync: 'scheduleEmailSync',
|
|
12
|
+
syncMemberLoginEmails: 'syncMemberLoginEmails',
|
|
13
|
+
scheduleContactFormEmailMigration: 'scheduleContactFormEmailMigration',
|
|
14
|
+
migrateContactFormEmails: 'migrateContactFormEmails',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
TASKS_NAMES,
|
|
19
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const { taskManager } = require('psdev-task-manager');
|
|
2
|
+
|
|
3
|
+
const { TASKS_NAMES } = require('./consts');
|
|
4
|
+
|
|
5
|
+
//this will be run only once by the developers during the migration
|
|
6
|
+
function scheduleConvertHtmlToRichContent() {
|
|
7
|
+
return taskManager().schedule({
|
|
8
|
+
name: TASKS_NAMES.scheduleTaskForEmptyAboutYouMembers,
|
|
9
|
+
data: {},
|
|
10
|
+
type: 'scheduled',
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// This function is used to migrate external profile images to Wix-hosted images
|
|
15
|
+
function scheduleExternalProfileImageMigration() {
|
|
16
|
+
return taskManager().schedule({
|
|
17
|
+
name: TASKS_NAMES.scheduleTaskForExternalProfileImages,
|
|
18
|
+
data: {},
|
|
19
|
+
type: 'scheduled',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
scheduleConvertHtmlToRichContent,
|
|
25
|
+
scheduleExternalProfileImageMigration,
|
|
26
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const { MEMBER_ACTIONS } = require('../daily-pull/consts.js');
|
|
2
|
+
const {
|
|
3
|
+
synchronizeSinglePage,
|
|
4
|
+
syncMembersDataPerAction,
|
|
5
|
+
} = require('../daily-pull/sync-to-cms-methods');
|
|
6
|
+
|
|
7
|
+
const { TASKS_NAMES } = require('./consts');
|
|
8
|
+
const {
|
|
9
|
+
scheduleTaskForEmptyAboutYouMembers,
|
|
10
|
+
convertAboutYouHtmlToRichContent,
|
|
11
|
+
compileFiltersOptions,
|
|
12
|
+
scheduleTaskForExternalProfileImages,
|
|
13
|
+
convertExternalProfilesToWixImages,
|
|
14
|
+
updateSiteMapS3,
|
|
15
|
+
scheduleContactFormEmailMigration,
|
|
16
|
+
migrateContactFormEmails,
|
|
17
|
+
scheduleEmailSync,
|
|
18
|
+
syncMemberLoginEmails,
|
|
19
|
+
} = require('./tasks-process-methods');
|
|
20
|
+
|
|
21
|
+
const getDailyMembersDataSyncChildTasks = () => {
|
|
22
|
+
// we don't want to sync none action as it means this members data hasn't changed and we don't need to sync it
|
|
23
|
+
const MEMBER_ACTIONS_EXCEPT_NONE = Object.values(MEMBER_ACTIONS).filter(
|
|
24
|
+
action => action !== MEMBER_ACTIONS.NONE
|
|
25
|
+
);
|
|
26
|
+
return MEMBER_ACTIONS_EXCEPT_NONE.map(action => ({
|
|
27
|
+
name: TASKS_NAMES.ScheduleMembersDataPerAction,
|
|
28
|
+
data: { action },
|
|
29
|
+
}));
|
|
30
|
+
};
|
|
31
|
+
const TASKS = {
|
|
32
|
+
[TASKS_NAMES.ScheduleDailyMembersDataSync]: {
|
|
33
|
+
name: TASKS_NAMES.ScheduleDailyMembersDataSync,
|
|
34
|
+
scheduleChildrenSequentially: false,
|
|
35
|
+
estimatedDurationSec: 60,
|
|
36
|
+
childTasks: getDailyMembersDataSyncChildTasks(),
|
|
37
|
+
},
|
|
38
|
+
[TASKS_NAMES.ScheduleMembersDataPerAction]: {
|
|
39
|
+
name: TASKS_NAMES.ScheduleMembersDataPerAction,
|
|
40
|
+
getIdentifier: task => task.data.action,
|
|
41
|
+
process: syncMembersDataPerAction,
|
|
42
|
+
shouldSkipCheck: () => false,
|
|
43
|
+
estimatedDurationSec: 6,
|
|
44
|
+
},
|
|
45
|
+
[TASKS_NAMES.SyncMembers]: {
|
|
46
|
+
name: TASKS_NAMES.SyncMembers,
|
|
47
|
+
getIdentifier: task => task,
|
|
48
|
+
process: synchronizeSinglePage,
|
|
49
|
+
shouldSkipCheck: () => false,
|
|
50
|
+
estimatedDurationSec: 6,
|
|
51
|
+
},
|
|
52
|
+
[TASKS_NAMES.scheduleTaskForEmptyAboutYouMembers]: {
|
|
53
|
+
name: TASKS_NAMES.scheduleTaskForEmptyAboutYouMembers,
|
|
54
|
+
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
55
|
+
process: scheduleTaskForEmptyAboutYouMembers,
|
|
56
|
+
shouldSkipCheck: () => false,
|
|
57
|
+
estimatedDurationSec: 40,
|
|
58
|
+
},
|
|
59
|
+
[TASKS_NAMES.convertHtmlToRichContent]: {
|
|
60
|
+
name: TASKS_NAMES.convertHtmlToRichContent,
|
|
61
|
+
getIdentifier: task => task.data.memberIds,
|
|
62
|
+
process: convertAboutYouHtmlToRichContent,
|
|
63
|
+
shouldSkipCheck: () => false,
|
|
64
|
+
estimatedDurationSec: 45,
|
|
65
|
+
},
|
|
66
|
+
[TASKS_NAMES.CompileFiltersOptions]: {
|
|
67
|
+
name: TASKS_NAMES.CompileFiltersOptions,
|
|
68
|
+
getIdentifier: task => task.data.field,
|
|
69
|
+
process: compileFiltersOptions,
|
|
70
|
+
shouldSkipCheck: () => false,
|
|
71
|
+
estimatedDurationSec: 6,
|
|
72
|
+
},
|
|
73
|
+
[TASKS_NAMES.scheduleTaskForExternalProfileImages]: {
|
|
74
|
+
name: TASKS_NAMES.scheduleTaskForExternalProfileImages,
|
|
75
|
+
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
76
|
+
process: scheduleTaskForExternalProfileImages,
|
|
77
|
+
shouldSkipCheck: () => false,
|
|
78
|
+
estimatedDurationSec: 60,
|
|
79
|
+
},
|
|
80
|
+
[TASKS_NAMES.convertExternalProfilesToWixImages]: {
|
|
81
|
+
name: TASKS_NAMES.convertExternalProfilesToWixImages,
|
|
82
|
+
getIdentifier: task => task.data.memberIds,
|
|
83
|
+
process: convertExternalProfilesToWixImages,
|
|
84
|
+
shouldSkipCheck: () => false,
|
|
85
|
+
estimatedDurationSec: 55,
|
|
86
|
+
},
|
|
87
|
+
[TASKS_NAMES.updateSiteMapS3]: {
|
|
88
|
+
name: TASKS_NAMES.updateSiteMapS3,
|
|
89
|
+
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
90
|
+
process: updateSiteMapS3,
|
|
91
|
+
shouldSkipCheck: () => false,
|
|
92
|
+
estimatedDurationSec: 70,
|
|
93
|
+
},
|
|
94
|
+
[TASKS_NAMES.scheduleContactFormEmailMigration]: {
|
|
95
|
+
name: TASKS_NAMES.scheduleContactFormEmailMigration,
|
|
96
|
+
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
97
|
+
process: scheduleContactFormEmailMigration,
|
|
98
|
+
shouldSkipCheck: () => false,
|
|
99
|
+
estimatedDurationSec: 30,
|
|
100
|
+
},
|
|
101
|
+
[TASKS_NAMES.migrateContactFormEmails]: {
|
|
102
|
+
name: TASKS_NAMES.migrateContactFormEmails,
|
|
103
|
+
getIdentifier: task => task.data,
|
|
104
|
+
process: migrateContactFormEmails,
|
|
105
|
+
shouldSkipCheck: () => false,
|
|
106
|
+
estimatedDurationSec: 40,
|
|
107
|
+
},
|
|
108
|
+
[TASKS_NAMES.scheduleEmailSync]: {
|
|
109
|
+
name: TASKS_NAMES.scheduleEmailSync,
|
|
110
|
+
getIdentifier: () => 'SHOULD_NEVER_SKIP',
|
|
111
|
+
process: scheduleEmailSync,
|
|
112
|
+
shouldSkipCheck: () => false,
|
|
113
|
+
estimatedDurationSec: 30,
|
|
114
|
+
},
|
|
115
|
+
[TASKS_NAMES.syncMemberLoginEmails]: {
|
|
116
|
+
name: TASKS_NAMES.syncMemberLoginEmails,
|
|
117
|
+
getIdentifier: task => task.data,
|
|
118
|
+
process: syncMemberLoginEmails,
|
|
119
|
+
shouldSkipCheck: () => false,
|
|
120
|
+
estimatedDurationSec: 45,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
module.exports = { TASKS };
|