abmp-npm 2.0.77 → 2.0.79

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 (101) hide show
  1. package/package.json +8 -1
  2. package/pages/Profile.js +6 -1
  3. package/public/Utils/personalDetailsUtils.js +17 -6
  4. package/.claude/skills/wix-data-query/SKILL.md +0 -167
  5. package/.claude/skills/wix-data-query/references/backup-archive.md +0 -136
  6. package/.claude/skills/wix-data-query/references/members-data-latest.md +0 -125
  7. package/.claude/skills/wix-data-query/references/recipes.md +0 -264
  8. package/.claude/worktrees/fix-save-button-disable/.husky/pre-commit +0 -19
  9. package/.claude/worktrees/fix-save-button-disable/.prettierignore +0 -7
  10. package/.claude/worktrees/fix-save-button-disable/.prettierrc.json +0 -16
  11. package/.claude/worktrees/fix-save-button-disable/README.md +0 -1
  12. package/.claude/worktrees/fix-save-button-disable/backend/README-member-contact-flows.md +0 -136
  13. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  14. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  15. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/login-email-sync.test.js +0 -49
  16. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  17. package/.claude/worktrees/fix-save-button-disable/backend/__tests__/url-uniqueness.test.js +0 -194
  18. package/.claude/worktrees/fix-save-button-disable/backend/automations-methods.js +0 -13
  19. package/.claude/worktrees/fix-save-button-disable/backend/cms-data-methods.js +0 -251
  20. package/.claude/worktrees/fix-save-button-disable/backend/consts.js +0 -58
  21. package/.claude/worktrees/fix-save-button-disable/backend/contacts-methods.js +0 -67
  22. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/bulk-process-methods.js +0 -222
  23. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/consts.js +0 -39
  24. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/index.js +0 -5
  25. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/process-member-methods.js +0 -213
  26. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/schedule-methods.js +0 -41
  27. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/sync-to-cms-methods.js +0 -161
  28. package/.claude/worktrees/fix-save-button-disable/backend/daily-pull/utils.js +0 -151
  29. package/.claude/worktrees/fix-save-button-disable/backend/data-hooks.js +0 -29
  30. package/.claude/worktrees/fix-save-button-disable/backend/dev-only-methods.js +0 -58
  31. package/.claude/worktrees/fix-save-button-disable/backend/elevated-modules.js +0 -18
  32. package/.claude/worktrees/fix-save-button-disable/backend/forms-methods.js +0 -52
  33. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/httpFunctions.js +0 -86
  34. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/index.js +0 -3
  35. package/.claude/worktrees/fix-save-button-disable/backend/http-functions/interests.js +0 -35
  36. package/.claude/worktrees/fix-save-button-disable/backend/index.js +0 -19
  37. package/.claude/worktrees/fix-save-button-disable/backend/jobs.js +0 -158
  38. package/.claude/worktrees/fix-save-button-disable/backend/login/generate-member-session-token.js +0 -27
  39. package/.claude/worktrees/fix-save-button-disable/backend/login/index.js +0 -8
  40. package/.claude/worktrees/fix-save-button-disable/backend/login/qa-login-methods.js +0 -54
  41. package/.claude/worktrees/fix-save-button-disable/backend/login/sso-methods.js +0 -159
  42. package/.claude/worktrees/fix-save-button-disable/backend/member-contact-orchestration.js +0 -111
  43. package/.claude/worktrees/fix-save-button-disable/backend/members-area-methods.js +0 -88
  44. package/.claude/worktrees/fix-save-button-disable/backend/members-data-methods.js +0 -789
  45. package/.claude/worktrees/fix-save-button-disable/backend/pac-api-methods.js +0 -54
  46. package/.claude/worktrees/fix-save-button-disable/backend/routers/index.js +0 -3
  47. package/.claude/worktrees/fix-save-button-disable/backend/routers/methods.js +0 -191
  48. package/.claude/worktrees/fix-save-button-disable/backend/routers/utils.js +0 -128
  49. package/.claude/worktrees/fix-save-button-disable/backend/search-filters-methods.js +0 -124
  50. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-primary-methods.js +0 -256
  51. package/.claude/worktrees/fix-save-button-disable/backend/tasks/address-visibility-methods.js +0 -160
  52. package/.claude/worktrees/fix-save-button-disable/backend/tasks/consts.js +0 -34
  53. package/.claude/worktrees/fix-save-button-disable/backend/tasks/daily-pull-check-methods.js +0 -78
  54. package/.claude/worktrees/fix-save-button-disable/backend/tasks/email-normalize-methods.js +0 -134
  55. package/.claude/worktrees/fix-save-button-disable/backend/tasks/index.js +0 -10
  56. package/.claude/worktrees/fix-save-button-disable/backend/tasks/migration-methods.js +0 -46
  57. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-configs.js +0 -251
  58. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-helpers-methods.js +0 -433
  59. package/.claude/worktrees/fix-save-button-disable/backend/tasks/tasks-process-methods.js +0 -606
  60. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-migration-methods.js +0 -378
  61. package/.claude/worktrees/fix-save-button-disable/backend/tasks/url-space-fix-methods.js +0 -174
  62. package/.claude/worktrees/fix-save-button-disable/backend/utils.js +0 -277
  63. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  64. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-ids.js +0 -159
  65. package/.claude/worktrees/fix-save-button-disable/dev-only-scripts/find-duplicate-urls.js +0 -201
  66. package/.claude/worktrees/fix-save-button-disable/eslint.config.js +0 -120
  67. package/.claude/worktrees/fix-save-button-disable/index.js +0 -5
  68. package/.claude/worktrees/fix-save-button-disable/package-lock.json +0 -12160
  69. package/.claude/worktrees/fix-save-button-disable/package.json +0 -60
  70. package/.claude/worktrees/fix-save-button-disable/pages/ContactUs.js +0 -129
  71. package/.claude/worktrees/fix-save-button-disable/pages/Home.js +0 -779
  72. package/.claude/worktrees/fix-save-button-disable/pages/LearnMore.js +0 -27
  73. package/.claude/worktrees/fix-save-button-disable/pages/LoadingPage.js +0 -29
  74. package/.claude/worktrees/fix-save-button-disable/pages/Profile.js +0 -354
  75. package/.claude/worktrees/fix-save-button-disable/pages/QAPage.js +0 -39
  76. package/.claude/worktrees/fix-save-button-disable/pages/SaveAlerts.js +0 -13
  77. package/.claude/worktrees/fix-save-button-disable/pages/SelectBannerImages.js +0 -46
  78. package/.claude/worktrees/fix-save-button-disable/pages/deleteConfirm.js +0 -19
  79. package/.claude/worktrees/fix-save-button-disable/pages/index.js +0 -12
  80. package/.claude/worktrees/fix-save-button-disable/pages/personalDetails.js +0 -2486
  81. package/.claude/worktrees/fix-save-button-disable/public/Utils/homePage.js +0 -798
  82. package/.claude/worktrees/fix-save-button-disable/public/Utils/personalDetailsUtils.js +0 -25
  83. package/.claude/worktrees/fix-save-button-disable/public/Utils/sharedUtils.js +0 -235
  84. package/.claude/worktrees/fix-save-button-disable/public/consts.js +0 -113
  85. package/.claude/worktrees/fix-save-button-disable/public/index.js +0 -5
  86. package/.claude/worktrees/fix-save-button-disable/public/messages.js +0 -16
  87. package/.claude/worktrees/fix-save-button-disable/public/sso-auth-methods.js +0 -43
  88. package/.husky/pre-commit +0 -19
  89. package/.prettierignore +0 -7
  90. package/.prettierrc.json +0 -16
  91. package/backend/__tests__/daily-pull-execution-check.test.js +0 -124
  92. package/backend/__tests__/ensure-unique-urls-in-batch.test.js +0 -129
  93. package/backend/__tests__/login-email-sync.test.js +0 -49
  94. package/backend/__tests__/map-link.test.js +0 -115
  95. package/backend/__tests__/transient-retry-and-bulk-lookup.test.js +0 -129
  96. package/backend/__tests__/url-uniqueness.test.js +0 -194
  97. package/backend/__tests__/url-validation.test.js +0 -69
  98. package/dev-only-scripts/extract-duplicate-url-groups.js +0 -201
  99. package/dev-only-scripts/find-duplicate-ids.js +0 -159
  100. package/dev-only-scripts/find-duplicate-urls.js +0 -201
  101. package/eslint.config.js +0 -120
@@ -1,54 +0,0 @@
1
- const axios = require('axios');
2
-
3
- const { PAC_API_URL, TEST_PAC_API_URL, BACKUP_API_URL } = require('./consts');
4
- const { getSecret } = require('./utils');
5
-
6
- const getPacApiBaseUrl = ({ backupDate, isTestEnvironment }) =>
7
- backupDate ? BACKUP_API_URL : isTestEnvironment ? TEST_PAC_API_URL : PAC_API_URL;
8
-
9
- const getHeaders = async () => {
10
- const AUTH_TOKEN = await getSecret('members-data-api-key');
11
- const headers = {
12
- Authorization: `Bearer ${AUTH_TOKEN}`,
13
- };
14
- return headers;
15
- };
16
- /**
17
- *
18
- * @param {*} params
19
- * @param {number} params.page - The page number to fetch
20
- * @param {string} params.action - The action to fetch
21
- * @param {string} [params.backupDate] - Optional. The backup date to fetch in format YYYY-MM-DD, use only to fetch from backup endpoint not from PAC endpoint.
22
- * @returns {Promise<Object>} - The response from the API
23
- */
24
- const fetchPACMembers = async ({ page, action, backupDate, isTestEnvironment }) => {
25
- const baseUrl = getPacApiBaseUrl({
26
- backupDate,
27
- isTestEnvironment,
28
- });
29
- const queryParams = { page, actionFilter: action };
30
- if (backupDate) {
31
- queryParams.date = backupDate;
32
- }
33
- const url = `${baseUrl}/Members?${new URLSearchParams(queryParams).toString()}`;
34
- console.log(`Fetching PAC members from: ${url}`);
35
- const headers = await getHeaders();
36
- const response = await axios.get(url, {
37
- headers,
38
- validateStatus: () => true,
39
- });
40
- const responseType = response.headers['content-type'] || '';
41
- if (!responseType.includes('application/json')) {
42
- const errorMessage = `[fetchPACMembers] got invalid responseType: ${responseType} for page ${page} and actionFilter ${action}`;
43
- console.error(errorMessage);
44
- throw new Error(errorMessage);
45
- }
46
- if (response.status >= 200 && response.status < 300) {
47
- return response.data;
48
- }
49
- const errorMessage = `[fetchPACMembers] failed with status ${response.status} for page ${page} and actionFilter ${action}`;
50
- console.error(errorMessage);
51
- throw new Error(errorMessage);
52
- };
53
-
54
- module.exports = { fetchPACMembers, getHeaders }; //TODO: remove getHeaders from exported methods once npm movement finishes
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- ...require('./methods'),
3
- };
@@ -1,191 +0,0 @@
1
- const { PAGES_PATHS } = require('../../public/consts');
2
- const { isWixHostedImage } = require('../../public/Utils/sharedUtils');
3
- //const { fetchAllItemsInParallel } = require('../cms-data-methods'); unused at host site
4
- const { CONFIG_KEYS } = require('../consts');
5
- const { getSiteConfigs } = require('../utils');
6
-
7
- const { generateSEOTitle, stripHtmlTags, getMemberProfileData } = require('./utils');
8
-
9
- const createRoutersHandlers = wixRouterMethods => {
10
- const {
11
- redirect,
12
- ok,
13
- notFound,
14
- sendStatus,
15
- WixRouterSitemapEntry: _WixRouterSitemapEntry,
16
- } = wixRouterMethods; // These dependencies needs to be injected as they do not have an SDK equivalent for now
17
-
18
- async function profileRouter(request) {
19
- const slug = request.path[0];
20
- if (!slug) {
21
- return redirect(request.baseUrl);
22
- }
23
- try {
24
- const siteConfigs = await getSiteConfigs();
25
- const siteAssociation = siteConfigs[CONFIG_KEYS.SITE_ASSOCIATION];
26
- const defaultSEODescription = siteConfigs[CONFIG_KEYS.DEFAULT_PROFILE_SEO_DESCRIPTION];
27
- const siteLogoUrl = siteConfigs[CONFIG_KEYS.SITE_LOGO_URL];
28
- const defaultProfileImage = siteConfigs[CONFIG_KEYS.DEFAULT_PROFILE_IMAGE];
29
- const profileData = await getMemberProfileData(slug, siteAssociation);
30
- if (profileData && profileData.showWixUrl) {
31
- const profileImage =
32
- profileData.profileImage?.trim() && isWixHostedImage(profileData.profileImage)
33
- ? profileData.profileImage
34
- : defaultProfileImage;
35
- const ogImage = profileImage || profileData.logoImage || siteLogoUrl;
36
- const seoTitle = generateSEOTitle({
37
- fullName: profileData.fullName,
38
- areasOfPractices: profileData.areasOfPractices,
39
- siteAssociation,
40
- });
41
- // Use stripped HTML from aboutService rich text content
42
- let description = stripHtmlTags(profileData.aboutService) || defaultSEODescription;
43
-
44
- // Limit description to 160 characters for optimal SEO
45
- if (description.length > 160) {
46
- description = description.substring(0, 157) + '...';
47
- }
48
- const profileUrl = `${request.baseUrl}/${PAGES_PATHS.PROFILE}/${profileData.url}`;
49
- const isPrivateMember = profileData.isPrivateMember;
50
- const isStudent = profileData.shouldHaveStudentBadge;
51
- const shouldNoIndex = isPrivateMember || isStudent;
52
- const seoData = {
53
- title: seoTitle,
54
- description: description,
55
- noIndex: shouldNoIndex,
56
- metaTags: [
57
- {
58
- name: 'description',
59
- content: description,
60
- },
61
- {
62
- name: 'keywords',
63
- content:
64
- `${profileData.fullName}, ${profileData.areasOfPractices ? profileData.areasOfPractices.slice(0, 3).join(', ') : ''}, ${siteAssociation}, ${profileData.city || ''}, ${profileData.state || ''}`
65
- .replace(/,\s*,/g, ',')
66
- .replace(/^,|,$/g, ''),
67
- },
68
- {
69
- name: 'author',
70
- content: profileData.fullName,
71
- },
72
- {
73
- name: 'robots',
74
- content: shouldNoIndex ? 'noindex, nofollow' : 'index, follow',
75
- },
76
- // Open Graph tags
77
- {
78
- property: 'og:type',
79
- content: 'profile',
80
- },
81
- {
82
- property: 'og:title',
83
- content: seoTitle,
84
- },
85
- {
86
- property: 'og:description',
87
- content: description,
88
- },
89
- {
90
- property: 'og:image',
91
- content: ogImage,
92
- },
93
- {
94
- property: 'og:url',
95
- content: profileUrl,
96
- },
97
- {
98
- property: 'og:site_name',
99
- content: `${siteAssociation} Members`,
100
- },
101
- // Twitter Card tags
102
- {
103
- name: 'twitter:card',
104
- content: 'summary_large_image',
105
- },
106
- {
107
- name: 'twitter:title',
108
- content: seoTitle,
109
- },
110
- {
111
- name: 'twitter:description',
112
- content: description,
113
- },
114
- {
115
- name: 'twitter:image',
116
- content: ogImage,
117
- },
118
- // Additional SEO tags
119
- {
120
- name: 'geo.region',
121
- content: profileData.state || '',
122
- },
123
- {
124
- name: 'geo.placename',
125
- content: profileData.city || '',
126
- },
127
- ].filter(tag => tag.content && tag.content.trim() !== ''), // Remove empty tags
128
- };
129
- return ok('profile', { ...profileData, defaultProfileImage }, seoData);
130
- }
131
- console.log(
132
- `[profileRouter] Profile not found returning 404 for: ${JSON.stringify({
133
- slug,
134
- profileData,
135
- showWixUrl: profileData?.showWixUrl,
136
- })}`
137
- );
138
- return notFound();
139
- } catch (error) {
140
- console.error(`Error in profileRouter for slug: ${slug} : ${error.message}`);
141
- return sendStatus('500', 'Internal Server Error');
142
- }
143
- }
144
- function profileSiteMap(_sitemapRequest) {
145
- return [];
146
- // Commented out - currently disabled in host site
147
- // try {
148
- // const membersQuery = wixData
149
- // .query(COLLECTIONS.MEMBERS_DATA)
150
- // .eq('showWixUrl', true)
151
- // .isNotEmpty('url')
152
- // .ne('action', 'drop')
153
- // .fields('url', 'fullName');
154
-
155
- // const allMembers = await fetchAllItemsInParallel(membersQuery);
156
-
157
- // const batchSize = 1000;
158
- // const sitemapEntries = [];
159
- // const totalItems = allMembers.items.length;
160
-
161
- // for (let i = 0; i < totalItems; i += batchSize) {
162
- // const batch = allMembers.items.slice(i, i + batchSize);
163
- // const batchEntries = batch.map(member => {
164
- // const entry = new WixRouterSitemapEntry(member.fullName);
165
- // entry.pageName = 'profile';
166
- // entry.url = `${PAGES_PATHS.PROFILE}/${member.url}`;
167
- // entry.title = member.fullName;
168
- // entry.changeFrequency = 'monthly';
169
- // entry.priority = 1.0;
170
- // return entry;
171
- // });
172
- // sitemapEntries.push(...batchEntries);
173
- // }
174
-
175
- // return sitemapEntries;
176
- // } catch (error) {
177
- // console.error('Error generating profile sitemap:', error);
178
- // return [];
179
- // }
180
- }
181
- //Add other routers here
182
- return {
183
- profileRouter,
184
- profileSiteMap,
185
- //Add other routers here
186
- };
187
- };
188
-
189
- module.exports = {
190
- createRoutersHandlers,
191
- };
@@ -1,128 +0,0 @@
1
- const { getMainAddress } = require('../../public/Utils/sharedUtils');
2
- const { getMemberBySlug } = require('../members-data-methods');
3
- const {
4
- getMoreAddressesToDisplay,
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 moreAddressesToDisplay = getMoreAddressesToDisplay(
52
- member.addresses,
53
- member.addressDisplayOption
54
- );
55
-
56
- const memberships = member.memberships || [];
57
- const siteAssociationMembership = memberships.find(m => m.association === siteAssociation);
58
-
59
- const areasOfPractices =
60
- member.areasOfPractices
61
- ?.filter(item => typeof item === 'string' && item.trim().length > 0)
62
- .map(item => item.trim())
63
- .sort((a, b) =>
64
- a.localeCompare(b, undefined, {
65
- sensitivity: 'base',
66
- numeric: true,
67
- })
68
- ) || [];
69
-
70
- const phones = Array.isArray(member.phones) ? member.phones : [];
71
- const toShowPhone = member.toShowPhone || '';
72
- const phone = toShowPhone && phones.includes(toShowPhone) ? toShowPhone : '';
73
-
74
- return {
75
- mainAddress,
76
- testimonials: member.testimonial || [],
77
- licenceNo,
78
- moreAddressesToDisplay,
79
- memberSince:
80
- (member.showABMP &&
81
- siteAssociationMembership &&
82
- formatDateToMonthYear(siteAssociationMembership?.membersince)) ||
83
- '',
84
- shouldHaveStudentBadge: shouldHaveStudentBadge(member, siteAssociation),
85
- logoImage: member.logoImage,
86
- fullName: member.fullName,
87
- profileImage: member.profileImage,
88
- showContactForm: member.showContactForm,
89
- bookingUrl: member.bookingUrl,
90
- aboutService: member.aboutService,
91
- businessName: (member.showBusinessName && member.businessName) || '',
92
- phone,
93
- areasOfPractices,
94
- gallery: member.gallery,
95
- bannerImages: member.bannerImages,
96
- showWixUrl: member.showWixUrl,
97
- _id: member._id,
98
- url: member.url,
99
- isPrivateMember: isPAC_STAFF(member),
100
- };
101
- }
102
-
103
- const getMemberProfileData = async (slug, siteAssociation) => {
104
- try {
105
- const member = await getMemberBySlug({
106
- slug,
107
- excludeDropped: true,
108
- excludeSearchedMember: false,
109
- });
110
-
111
- if (!member) {
112
- console.log(`[getMemberProfileData] Member not found for slug: ${slug}`);
113
- return null;
114
- }
115
-
116
- return transformMemberToProfileData(member, siteAssociation);
117
- } catch (error) {
118
- const errorMessage = `Error in getMemberProfileData for slug: ${slug} : ${error.message}`;
119
- console.error(errorMessage);
120
- throw new Error(errorMessage);
121
- }
122
- };
123
-
124
- module.exports = {
125
- generateSEOTitle,
126
- stripHtmlTags,
127
- getMemberProfileData,
128
- };
@@ -1,124 +0,0 @@
1
- const { COLLECTIONS } = require('../public/consts');
2
-
3
- const { buildMembersSearchQuery } = require('./cms-data-methods');
4
- const { wixData } = require('./elevated-modules');
5
- const { retrieveAllItems } = require('./utils');
6
-
7
- const getCompiledFiltersOptions = () =>
8
- wixData.get(COLLECTIONS.COMPILED_STATE_CITY_MAP, 'SINGLE_ITEM_ID');
9
-
10
- const getNonCompiledFiltersOptions = async () => {
11
- const [completeStateList, areasOfPracticesList, stateCityMapList] = await Promise.all([
12
- getCompleteStateList(),
13
- getAreasOfPracticeList(),
14
- getStateCityMap(),
15
- ]);
16
- return { completeStateList, areasOfPracticesList, stateCityMapList };
17
- };
18
- const filterProfiles = async data => {
19
- const membersSearchQuery = buildMembersSearchQuery({ ...data, includeStudents: false });
20
- const query = await membersSearchQuery.get();
21
- return membersSearchQuery.run(query);
22
- };
23
-
24
- async function getAreasOfPracticeList() {
25
- const interestsData = await retrieveAllItems(COLLECTIONS.INTERESTS);
26
- return interestsData.map(({ title }) => ({ label: title, value: title }));
27
- }
28
-
29
- async function getStateCityMap() {
30
- const getAllCitiesMap = async () => {
31
- const totalCount = await wixData.query(COLLECTIONS.STATE_CITY_MAP).count();
32
- const baseQuery = wixData.query(COLLECTIONS.STATE_CITY_MAP).limit(1000);
33
- const batchedQueries = Array.from({ length: Math.ceil(totalCount / 1000) }, (_, i) =>
34
- baseQuery.skip(i * 1000)
35
- );
36
- const allCities = await Promise.all(
37
- batchedQueries.map(query => query.find({ omitTotalCount: true }).then(res => res.items))
38
- );
39
- return allCities.flat();
40
- };
41
- const allCities = await getAllCitiesMap();
42
- const stateCityMap = new Map();
43
- allCities.forEach(cityObj => {
44
- const state = cityObj.stateText;
45
- const city = cityObj.title;
46
- const cityArray = stateCityMap.has(state) ? [...stateCityMap.get(state), city] : [city];
47
- stateCityMap.set(state, cityArray);
48
- });
49
- return Object.fromEntries(stateCityMap);
50
- }
51
- //Besan comments on moved code: Below code assumes that Velo can cache value, however this isn't valid so it needs adjustment
52
- // Cache for state list
53
- let stateListCache = null;
54
- let lastCacheTime = 0;
55
- const CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
56
-
57
- async function getCompleteStateList() {
58
- // Check if we have a valid cache
59
- const now = Date.now();
60
- if (stateListCache && now - lastCacheTime < CACHE_DURATION) {
61
- return stateListCache;
62
- }
63
-
64
- // 1. fire both queries at once:
65
- const [stateRecords, memberStates] = await Promise.all([
66
- retrieveAllItems(COLLECTIONS.STATE),
67
- getMembersStateList(), //this method a
68
- ]);
69
-
70
- const fullNameByCode = new Map(stateRecords.map(st => [st.title, st.name]));
71
-
72
- const states = memberStates.map(({ value: code }) => ({
73
- value: code,
74
- label: fullNameByCode.get(code) || code,
75
- }));
76
-
77
- // Update cache
78
- stateListCache = states;
79
- lastCacheTime = now;
80
-
81
- return states;
82
- }
83
- //Besan Comments on moved code: THIS WILL IGNORE SOME STATES VALUES while we should return all states AFAIU
84
- async function getMembersStateList() {
85
- try {
86
- // Use a more efficient query to get only the addresses field
87
- const results = await wixData
88
- .query(COLLECTIONS.MEMBERS_DATA)
89
- .fields('addresses')
90
- .limit(1000)
91
- .find();
92
-
93
- // Extract all state codes from addresses
94
- const allStates = new Set();
95
- results.items.forEach(member => {
96
- if (Array.isArray(member.addresses)) {
97
- member.addresses.forEach(addr => {
98
- if (addr.state) allStates.add(addr.state);
99
- });
100
- }
101
- });
102
-
103
- // Convert to array and sort
104
- const uniqueStates = Array.from(allStates).sort();
105
-
106
- // Map to label/value format
107
- return uniqueStates.map(stateCode => ({
108
- label: stateCode,
109
- value: stateCode,
110
- }));
111
- } catch (error) {
112
- console.error('Error in getMembersStateList:', error);
113
- return [];
114
- }
115
- }
116
-
117
- module.exports = {
118
- getCompiledFiltersOptions,
119
- getNonCompiledFiltersOptions,
120
- filterProfiles,
121
- getCompleteStateList,
122
- getAreasOfPracticeList,
123
- getStateCityMap,
124
- };