abmp-npm 1.8.43 → 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.
Files changed (50) hide show
  1. package/CONTACT_EMAIL_UPDATE_DEBUG.md +313 -0
  2. package/DEBUG_QUICKSTART.md +133 -0
  3. package/backend/cms-data-methods.js +8 -0
  4. package/backend/consts.js +22 -7
  5. package/backend/contacts-methods-DEBUG.js +237 -0
  6. package/backend/contacts-methods-TEST.js +271 -0
  7. package/backend/contacts-methods.js +6 -1
  8. package/backend/daily-pull/consts.js +0 -3
  9. package/backend/daily-pull/process-member-methods.js +1 -1
  10. package/backend/daily-pull/sync-to-cms-methods.js +10 -6
  11. package/backend/daily-pull/utils.js +3 -3
  12. package/backend/data-hooks.js +29 -0
  13. package/backend/elevated-modules.js +2 -0
  14. package/backend/http-functions/httpFunctions.js +86 -0
  15. package/backend/http-functions/index.js +3 -0
  16. package/backend/http-functions/interests.js +37 -0
  17. package/backend/index.js +6 -1
  18. package/backend/jobs.js +15 -3
  19. package/backend/login/index.js +7 -0
  20. package/backend/login/login-methods-factory.js +24 -0
  21. package/backend/login/qa-login-methods.js +72 -0
  22. package/backend/login/sso-methods.js +158 -0
  23. package/backend/members-data-methods.js +271 -94
  24. package/backend/pac-api-methods.js +3 -4
  25. package/backend/routers/index.js +3 -0
  26. package/backend/routers/methods.js +177 -0
  27. package/backend/routers/utils.js +118 -0
  28. package/backend/search-filters-methods.js +3 -0
  29. package/backend/tasks/consts.js +19 -0
  30. package/backend/tasks/index.js +6 -0
  31. package/backend/tasks/migration-methods.js +26 -0
  32. package/backend/tasks/tasks-configs.js +124 -0
  33. package/backend/tasks/tasks-helpers-methods.js +419 -0
  34. package/backend/tasks/tasks-process-methods.js +545 -0
  35. package/backend/test-methods.js +118 -0
  36. package/backend/utils.js +85 -41
  37. package/package.json +13 -2
  38. package/pages/LoadingPage.js +20 -0
  39. package/pages/Profile.js +2 -2
  40. package/pages/QAPage.js +39 -0
  41. package/pages/SaveAlerts.js +13 -0
  42. package/pages/SelectBannerImages.js +46 -0
  43. package/pages/deleteConfirm.js +19 -0
  44. package/pages/index.js +5 -0
  45. package/pages/personalDetails.js +12 -8
  46. package/public/consts.js +6 -23
  47. package/public/sso-auth-methods.js +43 -0
  48. package/backend/routers-methods.js +0 -186
  49. package/backend/routers-utils.js +0 -158
  50. 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(/&nbsp;/g, ' ') // Replace non-breaking spaces
24
+ .replace(/&amp;/g, '&') // Replace encoded ampersands
25
+ .replace(/&lt;/g, '<') // Replace encoded less than
26
+ .replace(/&gt;/g, '>') // Replace encoded greater than
27
+ .replace(/&quot;/g, '"') // Replace encoded quotes
28
+ .replace(/&#39;/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
+ };
@@ -118,4 +118,7 @@ module.exports = {
118
118
  getCompiledFiltersOptions,
119
119
  getNonCompiledFiltersOptions,
120
120
  filterProfiles,
121
+ getCompleteStateList,
122
+ getAreasOfPracticeList,
123
+ getStateCityMap,
121
124
  };
@@ -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,6 @@
1
+ module.exports = {
2
+ ...require('./tasks-configs'),
3
+ ...require('./consts'),
4
+ ...require('./tasks-process-methods'),
5
+ ...require('./migration-methods'),
6
+ };
@@ -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 };