abmp-npm 10.0.70 → 10.0.71
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/index.js +0 -1
- package/backend/routers/utils.js +0 -1
- package/package.json +1 -2
- package/pages/index.js +0 -1
- package/pages/personalDetails.js +56 -17
- package/public/consts.js +0 -1
- package/backend/public-profile-methods.js +0 -54
- package/pages/publicProfile.js +0 -523
package/backend/index.js
CHANGED
package/backend/routers/utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abmp-npm",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.71",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"check-cycles": "madge --circular .",
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
"@wix/secrets": "^1.0.62",
|
|
43
43
|
"@wix/site-location": "^1.31.0",
|
|
44
44
|
"@wix/site-members": "^1.32.0",
|
|
45
|
-
"@wix/site-seo": "^1.22.0",
|
|
46
45
|
"@wix/site-storage": "^1.22.0",
|
|
47
46
|
"@wix/site-window": "^1.44.0",
|
|
48
47
|
"@wix/urls": "^1.0.57",
|
package/pages/index.js
CHANGED
package/pages/personalDetails.js
CHANGED
|
@@ -18,6 +18,33 @@ const {
|
|
|
18
18
|
const MAX_PHONES_COUNT = 10;
|
|
19
19
|
const MAX_ADDRESSES_COUNT = 10;
|
|
20
20
|
|
|
21
|
+
/** US 10-digit NANP: strip non-digits; drop leading 1 from 11-digit input. */
|
|
22
|
+
function digitsFromPhoneInput(value) {
|
|
23
|
+
if (!value || typeof value !== 'string') return '';
|
|
24
|
+
let d = value.replace(/\D/g, '');
|
|
25
|
+
if (d.length === 11 && d[0] === '1') d = d.slice(1);
|
|
26
|
+
return d.slice(0, 10);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Format as (###) ###-#### while typing. */
|
|
30
|
+
function formatUsPhoneInput(digits) {
|
|
31
|
+
if (!digits) return '';
|
|
32
|
+
const d = digits.slice(0, 10);
|
|
33
|
+
if (d.length <= 3) return `(${d}`;
|
|
34
|
+
if (d.length <= 6) return `(${d.slice(0, 3)}) ${d.slice(3)}`;
|
|
35
|
+
return `(${d.slice(0, 3)}) ${d.slice(3, 6)}-${d.slice(6)}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function formatPhoneNumberForInput(value) {
|
|
39
|
+
return formatUsPhoneInput(digitsFromPhoneInput(value || ''));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function phoneDigitsEqual(a, b) {
|
|
43
|
+
const da = digitsFromPhoneInput(String(a || ''));
|
|
44
|
+
const db = digitsFromPhoneInput(String(b || ''));
|
|
45
|
+
return da.length > 0 && db.length > 0 && da === db;
|
|
46
|
+
}
|
|
47
|
+
|
|
21
48
|
const ADDRESS_STATES = {
|
|
22
49
|
VIEW: 'addressViewState',
|
|
23
50
|
EDIT: 'addressEditState',
|
|
@@ -2024,12 +2051,16 @@ async function personalDetailsOnReady({
|
|
|
2024
2051
|
_$w('#phoneInput').onInput(event => {
|
|
2025
2052
|
const data = _$w('#phoneNumbersList').data;
|
|
2026
2053
|
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
2027
|
-
const
|
|
2054
|
+
const digits = digitsFromPhoneInput(event.target.value);
|
|
2055
|
+
const formatted = formatUsPhoneInput(digits);
|
|
2056
|
+
if (event.target.value !== formatted) {
|
|
2057
|
+
event.target.value = formatted;
|
|
2058
|
+
}
|
|
2028
2059
|
|
|
2029
|
-
updatePhoneNumber(clickedItemData._id,
|
|
2060
|
+
updatePhoneNumber(clickedItemData._id, formatted);
|
|
2030
2061
|
|
|
2031
|
-
if (clickedItemData.isNewPhone &&
|
|
2032
|
-
addNewPhoneToData(clickedItemData._id,
|
|
2062
|
+
if (clickedItemData.isNewPhone && digits.length > 0) {
|
|
2063
|
+
addNewPhoneToData(clickedItemData._id, formatted);
|
|
2033
2064
|
clickedItemData.isNewPhone = false;
|
|
2034
2065
|
}
|
|
2035
2066
|
|
|
@@ -2098,7 +2129,7 @@ async function personalDetailsOnReady({
|
|
|
2098
2129
|
}
|
|
2099
2130
|
|
|
2100
2131
|
function handlePhoneItem($item, itemData) {
|
|
2101
|
-
$item('#phoneInput').value = itemData.phoneNumber || '';
|
|
2132
|
+
$item('#phoneInput').value = formatPhoneNumberForInput(itemData.phoneNumber || '');
|
|
2102
2133
|
$item('#showPhoneCheckbox').checked = itemData.showPhone || false;
|
|
2103
2134
|
$item('#phoneNumberLabel').text = `Phone ${itemData.phoneIndex}`;
|
|
2104
2135
|
}
|
|
@@ -2112,7 +2143,7 @@ async function personalDetailsOnReady({
|
|
|
2112
2143
|
let matched = false;
|
|
2113
2144
|
return phoneData.map(p => {
|
|
2114
2145
|
const t = (p.phoneNumber || '').trim();
|
|
2115
|
-
const isMatch = Boolean(t && t
|
|
2146
|
+
const isMatch = Boolean(t && phoneDigitsEqual(t, cms));
|
|
2116
2147
|
if (isMatch && !matched) {
|
|
2117
2148
|
matched = true;
|
|
2118
2149
|
return { ...p, showPhone: true };
|
|
@@ -2140,7 +2171,7 @@ async function personalDetailsOnReady({
|
|
|
2140
2171
|
phoneData = phones.map((phone, index) => ({
|
|
2141
2172
|
_id: `phone_${index}`,
|
|
2142
2173
|
phoneNumber: phone,
|
|
2143
|
-
showPhone: phone
|
|
2174
|
+
showPhone: phoneDigitsEqual(phone, itemMemberObj.toShowPhone),
|
|
2144
2175
|
isNewPhone: false,
|
|
2145
2176
|
phoneIndex: index + 1,
|
|
2146
2177
|
}));
|
|
@@ -2195,7 +2226,7 @@ async function personalDetailsOnReady({
|
|
|
2195
2226
|
} else if (
|
|
2196
2227
|
itemMemberObj.toShowPhone &&
|
|
2197
2228
|
prevTrimmed &&
|
|
2198
|
-
itemMemberObj.toShowPhone
|
|
2229
|
+
phoneDigitsEqual(itemMemberObj.toShowPhone, prevTrimmed)
|
|
2199
2230
|
) {
|
|
2200
2231
|
itemMemberObj.toShowPhone = newTrimmed || null;
|
|
2201
2232
|
}
|
|
@@ -2230,14 +2261,17 @@ async function personalDetailsOnReady({
|
|
|
2230
2261
|
if (phoneToRemove) {
|
|
2231
2262
|
if (itemMemberObj.phones) {
|
|
2232
2263
|
itemMemberObj.phones = itemMemberObj.phones.filter(
|
|
2233
|
-
phone => phone
|
|
2264
|
+
phone => !phoneDigitsEqual(phone, phoneToRemove.phoneNumber)
|
|
2234
2265
|
);
|
|
2235
2266
|
}
|
|
2236
2267
|
|
|
2237
2268
|
// Clear toShowPhone if it was the removed phone or if it's no longer in the list
|
|
2238
2269
|
// (handles format mismatch e.g. "(406)655-4940" vs "(406) 655-4940")
|
|
2239
2270
|
const remainingPhones = Array.isArray(itemMemberObj.phones) ? itemMemberObj.phones : [];
|
|
2240
|
-
if (
|
|
2271
|
+
if (
|
|
2272
|
+
itemMemberObj.toShowPhone &&
|
|
2273
|
+
!remainingPhones.some(p => phoneDigitsEqual(p, itemMemberObj.toShowPhone))
|
|
2274
|
+
) {
|
|
2241
2275
|
itemMemberObj.toShowPhone = null;
|
|
2242
2276
|
}
|
|
2243
2277
|
|
|
@@ -2262,7 +2296,10 @@ async function personalDetailsOnReady({
|
|
|
2262
2296
|
return;
|
|
2263
2297
|
}
|
|
2264
2298
|
|
|
2265
|
-
if (
|
|
2299
|
+
if (
|
|
2300
|
+
itemMemberObj.toShowPhone === trimmed ||
|
|
2301
|
+
phoneDigitsEqual(itemMemberObj.toShowPhone, trimmed)
|
|
2302
|
+
) {
|
|
2266
2303
|
itemMemberObj.toShowPhone = null;
|
|
2267
2304
|
}
|
|
2268
2305
|
}
|
|
@@ -2273,7 +2310,7 @@ async function personalDetailsOnReady({
|
|
|
2273
2310
|
// Never expose toShowPhone when phones is empty, so save payload clears it in CMS
|
|
2274
2311
|
if (phones.length === 0) return null;
|
|
2275
2312
|
// If toShowPhone is not in the list (e.g. format mismatch), treat as none selected
|
|
2276
|
-
if (toShow && !phones.
|
|
2313
|
+
if (toShow && !phones.some(p => phoneDigitsEqual(p, toShow))) return null;
|
|
2277
2314
|
return toShow;
|
|
2278
2315
|
}
|
|
2279
2316
|
|
|
@@ -2302,9 +2339,6 @@ async function personalDetailsOnReady({
|
|
|
2302
2339
|
}
|
|
2303
2340
|
|
|
2304
2341
|
async function saveContactBooking() {
|
|
2305
|
-
// if showWixUrl value changes then update optWebsiteCheckbox value
|
|
2306
|
-
_$w('#optWebsiteCheckbox').checked = itemMemberObj.showWixUrl;
|
|
2307
|
-
|
|
2308
2342
|
const showExistingUrl = _$w('#showExsistingUrlCheckbox').checked;
|
|
2309
2343
|
const otherWebsiteValue = (_$w('#UrlInput').value || '').trim();
|
|
2310
2344
|
const isOtherWebsiteInvalid =
|
|
@@ -2345,8 +2379,13 @@ async function personalDetailsOnReady({
|
|
|
2345
2379
|
console.groupEnd();
|
|
2346
2380
|
|
|
2347
2381
|
const result = await saveData(formData);
|
|
2348
|
-
if (
|
|
2349
|
-
|
|
2382
|
+
if (result.success) {
|
|
2383
|
+
if (beforeData.showWebsite !== contactChanges.showWebsite) {
|
|
2384
|
+
handleOptWebsiteCheckboxEnable(showExistingUrl);
|
|
2385
|
+
}
|
|
2386
|
+
// Sync Personal Details opt-in from saved member.
|
|
2387
|
+
_$w('#optWebsiteCheckbox').checked = itemMemberObj.showWixUrl;
|
|
2388
|
+
toggleFreeWebsiteText(itemMemberObj.showWixUrl);
|
|
2350
2389
|
}
|
|
2351
2390
|
formHasUnsavedChanges[FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING.section] = false;
|
|
2352
2391
|
handleSaveDataFeedback(_$w('#contactMessage'), result.message);
|
package/public/consts.js
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const { COLLECTIONS } = require('../public/consts');
|
|
2
|
-
|
|
3
|
-
const { CONFIG_KEYS } = require('./consts');
|
|
4
|
-
const { MEMBER_ACTIONS } = require('./daily-pull/consts');
|
|
5
|
-
const { wixData } = require('./elevated-modules');
|
|
6
|
-
const { findMemberByWixDataId } = require('./members-data-methods');
|
|
7
|
-
const { transformMemberToProfileData } = require('./routers/utils');
|
|
8
|
-
const { getSiteConfigs } = require('./utils');
|
|
9
|
-
|
|
10
|
-
const getPublicMemberRecord = memberDataId =>
|
|
11
|
-
wixData
|
|
12
|
-
.query(COLLECTIONS.MEMBERS_DATA_PUBLIC)
|
|
13
|
-
.eq('memberData', memberDataId)
|
|
14
|
-
.limit(1)
|
|
15
|
-
.find()
|
|
16
|
-
.then(res => res.items?.[0] || null);
|
|
17
|
-
|
|
18
|
-
async function getPublicMemberProfileData({ memberDataId }) {
|
|
19
|
-
if (!memberDataId) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const publicMember = await getPublicMemberRecord(memberDataId);
|
|
24
|
-
if (!publicMember || publicMember.showWixUrl !== true) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const member = await findMemberByWixDataId(memberDataId);
|
|
29
|
-
if (!member || member.action === MEMBER_ACTIONS.DROP || member.showWixUrl !== true) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const siteConfigs = await getSiteConfigs();
|
|
34
|
-
const siteAssociation = siteConfigs[CONFIG_KEYS.SITE_ASSOCIATION];
|
|
35
|
-
const defaultProfileImage = siteConfigs[CONFIG_KEYS.DEFAULT_PROFILE_IMAGE];
|
|
36
|
-
|
|
37
|
-
const profileData = transformMemberToProfileData(member, siteAssociation);
|
|
38
|
-
return {
|
|
39
|
-
profileData: { ...profileData, defaultProfileImage },
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
module.exports = {
|
|
44
|
-
getPublicMemberProfileData,
|
|
45
|
-
async getPublicProfileSeoConfig() {
|
|
46
|
-
const siteConfigs = await getSiteConfigs();
|
|
47
|
-
return {
|
|
48
|
-
siteAssociation: siteConfigs[CONFIG_KEYS.SITE_ASSOCIATION],
|
|
49
|
-
defaultSEODescription: siteConfigs[CONFIG_KEYS.DEFAULT_PROFILE_SEO_DESCRIPTION],
|
|
50
|
-
siteLogoUrl: siteConfigs[CONFIG_KEYS.SITE_LOGO_URL],
|
|
51
|
-
defaultProfileImage: siteConfigs[CONFIG_KEYS.DEFAULT_PROFILE_IMAGE],
|
|
52
|
-
};
|
|
53
|
-
},
|
|
54
|
-
};
|
package/pages/publicProfile.js
DELETED
|
@@ -1,523 +0,0 @@
|
|
|
1
|
-
const { location: wixLocation } = require('@wix/site-location');
|
|
2
|
-
const { seo } = require('@wix/site-seo');
|
|
3
|
-
const { window: wixWindow } = require('@wix/site-window');
|
|
4
|
-
|
|
5
|
-
const { LIGHTBOX_NAMES } = require('../public/consts');
|
|
6
|
-
const {
|
|
7
|
-
generateId,
|
|
8
|
-
formatPracticeAreasForDisplay,
|
|
9
|
-
isWixHostedImage,
|
|
10
|
-
} = require('../public/Utils/sharedUtils');
|
|
11
|
-
|
|
12
|
-
const TESTIMONIALS_PER_PAGE_CONFIG = {
|
|
13
|
-
DESKTOP: 4,
|
|
14
|
-
TABLET: 2,
|
|
15
|
-
MOBILE: 1,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const BREAKPOINTS = {
|
|
19
|
-
DESKTOP: 1301,
|
|
20
|
-
TABLET: 750,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const resolveMemberDataId = memberData => {
|
|
24
|
-
if (!memberData) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
if (typeof memberData === 'string') {
|
|
28
|
-
return memberData;
|
|
29
|
-
}
|
|
30
|
-
return memberData?._id || memberData?._ref || null;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
async function publicProfileOnReady({
|
|
34
|
-
$w: _$w,
|
|
35
|
-
getPublicMemberProfileData,
|
|
36
|
-
getPublicProfileSeoConfig,
|
|
37
|
-
}) {
|
|
38
|
-
const dataset = _$w('#dynamicDataset');
|
|
39
|
-
let profileData = null;
|
|
40
|
-
|
|
41
|
-
let testimonialsPerPage = TESTIMONIALS_PER_PAGE_CONFIG.TABLET;
|
|
42
|
-
let currentTestimonialPage = 0;
|
|
43
|
-
|
|
44
|
-
if (typeof getPublicMemberProfileData !== 'function') {
|
|
45
|
-
console.error('[publicProfileOnReady] getPublicMemberProfileData is required');
|
|
46
|
-
wixLocation.to(`${wixLocation.baseUrl}/404`);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
await dataset.onReadyAsync();
|
|
51
|
-
const item = dataset.getCurrentItem();
|
|
52
|
-
|
|
53
|
-
if (!item || item.showWixUrl !== true) {
|
|
54
|
-
wixLocation.to(`${wixLocation.baseUrl}/404`);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const memberDataId = resolveMemberDataId(item.memberData);
|
|
59
|
-
if (!memberDataId) {
|
|
60
|
-
wixLocation.to(`${wixLocation.baseUrl}/404`);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const result = await getPublicMemberProfileData({ memberDataId });
|
|
65
|
-
profileData = result?.profileData || null;
|
|
66
|
-
|
|
67
|
-
if (!profileData) {
|
|
68
|
-
wixLocation.to(`${wixLocation.baseUrl}/404`);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (typeof getPublicProfileSeoConfig === 'function') {
|
|
73
|
-
try {
|
|
74
|
-
const seoConfig = await getPublicProfileSeoConfig();
|
|
75
|
-
applySeo(profileData, seoConfig);
|
|
76
|
-
} catch (error) {
|
|
77
|
-
console.error('[publicProfileOnReady] Failed to set SEO', error);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
initializePage();
|
|
82
|
-
|
|
83
|
-
function initializePage() {
|
|
84
|
-
bindProfileData();
|
|
85
|
-
setupAddressToggle();
|
|
86
|
-
setupResponsiveTestimonials();
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Profile data binding
|
|
90
|
-
function bindProfileData() {
|
|
91
|
-
bindAddressData();
|
|
92
|
-
bindMemberInfo();
|
|
93
|
-
bindContactInfo();
|
|
94
|
-
bindBusinessInfo();
|
|
95
|
-
bindGalleryData();
|
|
96
|
-
bindTestimonialsData();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function bindAddressData() {
|
|
100
|
-
if (profileData.mainAddress) {
|
|
101
|
-
setTextForElements(
|
|
102
|
-
['#LocationText', '#LocationText2', '#LocationText3'],
|
|
103
|
-
profileData.mainAddress
|
|
104
|
-
);
|
|
105
|
-
} else {
|
|
106
|
-
deleteElements(['#locationContainer', '#location1Container', '#locationContainer2']);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
setupAdditionalAddresses();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function setupAdditionalAddresses() {
|
|
113
|
-
_$w('#moreAdressesRepeater').data = profileData.moreAddressesToDisplay;
|
|
114
|
-
|
|
115
|
-
if (profileData.moreAddressesToDisplay.length > 0) {
|
|
116
|
-
_$w('#moreLocationButton').expand();
|
|
117
|
-
_$w('#addressTitle').collapse();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
_$w('#moreAdressesRepeater').onItemReady(($item, itemData) => {
|
|
121
|
-
console.log('Item Data:', itemData);
|
|
122
|
-
$item('#adressText').text = itemData.address || '';
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function setupAddressToggle() {
|
|
127
|
-
toggleContainer('#moreLocationButton', '#addressContainer');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function toggleContainer(buttonId, containerId) {
|
|
131
|
-
const $button = _$w(buttonId);
|
|
132
|
-
const $container = _$w(containerId);
|
|
133
|
-
|
|
134
|
-
$button.onClick(() => {
|
|
135
|
-
const isCollapsed = $container.collapsed;
|
|
136
|
-
$container[isCollapsed ? 'expand' : 'collapse']();
|
|
137
|
-
$button.label = isCollapsed ? 'Less Locations -' : 'More Locations +';
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function bindMemberInfo() {
|
|
142
|
-
bindMemberSince();
|
|
143
|
-
bindStudentBadge();
|
|
144
|
-
bindProfileImages();
|
|
145
|
-
bindFullName();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function bindMemberSince() {
|
|
149
|
-
if (profileData.memberSince) {
|
|
150
|
-
_$w('#sinceYearText').text = profileData.memberSince;
|
|
151
|
-
} else {
|
|
152
|
-
_$w('#memberSinceBox').delete();
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function bindStudentBadge() {
|
|
157
|
-
if (profileData.shouldHaveStudentBadge) {
|
|
158
|
-
_$w('#studentContainer, #studentContainerMobile').expand();
|
|
159
|
-
} else {
|
|
160
|
-
_$w('#studentContainer, #studentContainerMobile').delete();
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function bindProfileImages() {
|
|
165
|
-
if (profileData.logoImage) {
|
|
166
|
-
_$w('#logoImage').src = profileData.logoImage;
|
|
167
|
-
} else {
|
|
168
|
-
_$w('#logoImage').delete();
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (profileData.profileImage && isWixHostedImage(profileData.profileImage)) {
|
|
172
|
-
_$w('#profileImage').src = profileData.profileImage;
|
|
173
|
-
} else {
|
|
174
|
-
_$w('#profileImage').src = profileData.defaultProfileImage;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function bindFullName() {
|
|
179
|
-
if (profileData.fullName) {
|
|
180
|
-
setTextForElements(
|
|
181
|
-
['#fullNameText', '#fullNameText2', '#fullNameTextFoter'],
|
|
182
|
-
profileData.fullName
|
|
183
|
-
);
|
|
184
|
-
} else {
|
|
185
|
-
deleteElements(['#fullNameText', '#fullNameText2', '#fullNameTextFoter']);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Contact information binding
|
|
190
|
-
function bindContactInfo() {
|
|
191
|
-
bindContactForm();
|
|
192
|
-
bindBookingUrl();
|
|
193
|
-
bindPhoneNumber();
|
|
194
|
-
bindLicenseNumber();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function bindContactForm() {
|
|
198
|
-
if (profileData.showContactForm) {
|
|
199
|
-
_$w('#contactButton').onClick(() =>
|
|
200
|
-
wixWindow.openLightbox(LIGHTBOX_NAMES.CONTACT_US, profileData)
|
|
201
|
-
);
|
|
202
|
-
} else {
|
|
203
|
-
_$w('#contactButton').delete();
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
function bindBookingUrl() {
|
|
208
|
-
if (profileData.bookingUrl) {
|
|
209
|
-
_$w('#bookNowButton').link = profileData.bookingUrl;
|
|
210
|
-
} else {
|
|
211
|
-
_$w('#bookNowButton').delete();
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function bindPhoneNumber() {
|
|
216
|
-
if (profileData.phone) {
|
|
217
|
-
const formattedPhoneNumber = profileData.phone.replace(/[^\d+]/g, '');
|
|
218
|
-
const getPhoneHTML = $phoneSelector =>
|
|
219
|
-
$phoneSelector.html.replace(
|
|
220
|
-
$phoneSelector.text,
|
|
221
|
-
`<a href="${`tel:${formattedPhoneNumber}`}">${profileData.phone}</a>`
|
|
222
|
-
);
|
|
223
|
-
_$w('#phoneText').html = getPhoneHTML(_$w('#phoneText'));
|
|
224
|
-
_$w('#phoneText2').html = getPhoneHTML(_$w('#phoneText2'));
|
|
225
|
-
} else {
|
|
226
|
-
deleteElements(['#phoneContainer', '#phoneContainer2']);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function bindLicenseNumber() {
|
|
231
|
-
if (profileData.licenceNo) {
|
|
232
|
-
_$w('#licenceNoText').text = profileData.licenceNo;
|
|
233
|
-
} else {
|
|
234
|
-
_$w('#licensesContainer').delete();
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function bindBusinessInfo() {
|
|
239
|
-
bindAboutService();
|
|
240
|
-
bindBusinessName();
|
|
241
|
-
bindAreasOfPractice();
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function bindAboutService() {
|
|
245
|
-
if (profileData.aboutService) {
|
|
246
|
-
_$w('#aboutYouText').html = profileData.aboutService;
|
|
247
|
-
} else {
|
|
248
|
-
_$w('#aboutSection').delete();
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function bindBusinessName() {
|
|
253
|
-
if (profileData.businessName) {
|
|
254
|
-
_$w('#businessName').text = profileData.businessName;
|
|
255
|
-
_$w('#businessName').expand();
|
|
256
|
-
} else {
|
|
257
|
-
_$w('#businessName').delete();
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function bindAreasOfPractice() {
|
|
262
|
-
const areasText = formatPracticeAreasForDisplay(profileData.areasOfPractices);
|
|
263
|
-
|
|
264
|
-
if (areasText) {
|
|
265
|
-
_$w('#areaOfPracticesText').text = areasText;
|
|
266
|
-
} else {
|
|
267
|
-
_$w('#areaOfPracticesText').delete();
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (Array.isArray(profileData.areasOfPractices) && profileData.areasOfPractices.length > 0) {
|
|
271
|
-
populateRepeater(profileData.areasOfPractices, '#areaOfPracticesRepeater', '#practiceText');
|
|
272
|
-
} else {
|
|
273
|
-
_$w('#servicesSection').delete();
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function bindGalleryData() {
|
|
278
|
-
if (profileData.bannerImages && profileData.bannerImages.length > 0) {
|
|
279
|
-
_$w('#bannerImage').src = profileData.bannerImages[0];
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (!profileData.gallery?.length) {
|
|
283
|
-
_$w('#gallerySection').delete();
|
|
284
|
-
} else {
|
|
285
|
-
_$w('#gallery').items = profileData.gallery;
|
|
286
|
-
_$w('#gallerySection').restore();
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function bindTestimonialsData() {
|
|
291
|
-
if (!profileData.testimonials?.length) {
|
|
292
|
-
_$w('#testimonialsSection').delete();
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Responsive testimonials setup
|
|
297
|
-
async function setupResponsiveTestimonials() {
|
|
298
|
-
const { window } = await wixWindow.getBoundingRect();
|
|
299
|
-
testimonialsPerPage = getTestimonialsPerPage(window.width);
|
|
300
|
-
|
|
301
|
-
// Monitor window resize
|
|
302
|
-
setInterval(async () => {
|
|
303
|
-
const { window: win } = await wixWindow.getBoundingRect();
|
|
304
|
-
const newTestimonialsPerPage = getTestimonialsPerPage(win.width);
|
|
305
|
-
|
|
306
|
-
if (newTestimonialsPerPage !== testimonialsPerPage) {
|
|
307
|
-
testimonialsPerPage = newTestimonialsPerPage;
|
|
308
|
-
currentTestimonialPage = 0;
|
|
309
|
-
displayTestimonialsPage(profileData.testimonials);
|
|
310
|
-
}
|
|
311
|
-
}, 500);
|
|
312
|
-
|
|
313
|
-
setupTestimonialsIfAvailable();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
function setupTestimonialsIfAvailable() {
|
|
317
|
-
if (profileData.testimonials.length > 0) {
|
|
318
|
-
setupTestimonialsPagination(profileData.testimonials);
|
|
319
|
-
_$w('#testimonialsSection').expand();
|
|
320
|
-
} else {
|
|
321
|
-
_$w('#testimonialsSection').delete();
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
function getTestimonialsPerPage(width) {
|
|
326
|
-
if (width >= BREAKPOINTS.DESKTOP) return TESTIMONIALS_PER_PAGE_CONFIG.DESKTOP;
|
|
327
|
-
if (width >= BREAKPOINTS.TABLET) return TESTIMONIALS_PER_PAGE_CONFIG.TABLET;
|
|
328
|
-
return TESTIMONIALS_PER_PAGE_CONFIG.MOBILE;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function setTextForElements(elementIds, text) {
|
|
332
|
-
elementIds.forEach(id => {
|
|
333
|
-
_$w(id).text = text;
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function deleteElements(elementIds) {
|
|
338
|
-
elementIds.forEach(id => {
|
|
339
|
-
_$w(id).delete();
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
function populateRepeater(data, repeaterId, textElementId) {
|
|
344
|
-
const repeaterData = data.map(item => ({
|
|
345
|
-
_id: generateId(),
|
|
346
|
-
text: item.trim(),
|
|
347
|
-
}));
|
|
348
|
-
_$w(repeaterId).data = repeaterData;
|
|
349
|
-
_$w(repeaterId).onItemReady(($item, itemData) => {
|
|
350
|
-
$item(textElementId).text = itemData.text;
|
|
351
|
-
});
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Testimonials pagination
|
|
355
|
-
function setupTestimonialsPagination(allTestimonials) {
|
|
356
|
-
currentTestimonialPage = 0;
|
|
357
|
-
|
|
358
|
-
_$w('#prevTestimonialBtn').onClick(() => {
|
|
359
|
-
if (currentTestimonialPage > 0) {
|
|
360
|
-
currentTestimonialPage--;
|
|
361
|
-
displayTestimonialsPage(allTestimonials);
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
_$w('#nextTestimonialBtn').onClick(() => {
|
|
366
|
-
const maxPage = Math.floor((allTestimonials.length - 1) / testimonialsPerPage);
|
|
367
|
-
if (currentTestimonialPage < maxPage) {
|
|
368
|
-
currentTestimonialPage++;
|
|
369
|
-
displayTestimonialsPage(allTestimonials);
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
displayTestimonialsPage(allTestimonials);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
function displayTestimonialsPage(allTestimonials) {
|
|
377
|
-
const start = currentTestimonialPage * testimonialsPerPage;
|
|
378
|
-
const end = start + testimonialsPerPage;
|
|
379
|
-
const currentBatch = allTestimonials.slice(start, end);
|
|
380
|
-
|
|
381
|
-
populateRepeater(currentBatch, '#testimonialsrepeater', '#testimonialText');
|
|
382
|
-
updateTestimonialNavigation(end, allTestimonials.length);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function updateTestimonialNavigation(end, totalLength) {
|
|
386
|
-
_$w('#prevTestimonialBtn').hide();
|
|
387
|
-
_$w('#nextTestimonialBtn').hide();
|
|
388
|
-
|
|
389
|
-
if (currentTestimonialPage > 0) {
|
|
390
|
-
_$w('#prevTestimonialBtn').show();
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
if (end < totalLength) {
|
|
394
|
-
_$w('#nextTestimonialBtn').show();
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
function applySeo(data, config) {
|
|
399
|
-
if (!data || !config) {
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
const { siteAssociation, defaultSEODescription, siteLogoUrl, defaultProfileImage } = config;
|
|
403
|
-
|
|
404
|
-
const profileImage =
|
|
405
|
-
data.profileImage?.trim() && isWixHostedImage(data.profileImage)
|
|
406
|
-
? data.profileImage
|
|
407
|
-
: defaultProfileImage;
|
|
408
|
-
const ogImage = profileImage || data.logoImage || siteLogoUrl;
|
|
409
|
-
const seoTitle = generateSEOTitle({
|
|
410
|
-
fullName: data.fullName,
|
|
411
|
-
areasOfPractices: data.areasOfPractices,
|
|
412
|
-
siteAssociation,
|
|
413
|
-
});
|
|
414
|
-
let description = stripHtmlTags(data.aboutService) || defaultSEODescription || '';
|
|
415
|
-
if (description.length > 160) {
|
|
416
|
-
description = description.substring(0, 157) + '...';
|
|
417
|
-
}
|
|
418
|
-
const profileUrl = data.url
|
|
419
|
-
? `${wixLocation.baseUrl}/profile/${data.url}`
|
|
420
|
-
: wixLocation.baseUrl;
|
|
421
|
-
const shouldNoIndex = data.isPrivateMember || data.shouldHaveStudentBadge;
|
|
422
|
-
|
|
423
|
-
seo.setTitle(seoTitle);
|
|
424
|
-
seo.setDescription(description);
|
|
425
|
-
seo.setMetaTags(
|
|
426
|
-
[
|
|
427
|
-
{
|
|
428
|
-
name: 'description',
|
|
429
|
-
content: description,
|
|
430
|
-
},
|
|
431
|
-
{
|
|
432
|
-
name: 'keywords',
|
|
433
|
-
content:
|
|
434
|
-
`${data.fullName}, ${data.areasOfPractices ? data.areasOfPractices.slice(0, 3).join(', ') : ''}, ${siteAssociation}, ${data.city || ''}, ${data.state || ''}`
|
|
435
|
-
.replace(/,\s*,/g, ',')
|
|
436
|
-
.replace(/^,|,$/g, ''),
|
|
437
|
-
},
|
|
438
|
-
{
|
|
439
|
-
name: 'author',
|
|
440
|
-
content: data.fullName,
|
|
441
|
-
},
|
|
442
|
-
{
|
|
443
|
-
name: 'robots',
|
|
444
|
-
content: shouldNoIndex ? 'noindex, nofollow' : 'index, follow',
|
|
445
|
-
},
|
|
446
|
-
{
|
|
447
|
-
property: 'og:type',
|
|
448
|
-
content: 'profile',
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
property: 'og:title',
|
|
452
|
-
content: seoTitle,
|
|
453
|
-
},
|
|
454
|
-
{
|
|
455
|
-
property: 'og:description',
|
|
456
|
-
content: description,
|
|
457
|
-
},
|
|
458
|
-
{
|
|
459
|
-
property: 'og:image',
|
|
460
|
-
content: ogImage,
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
property: 'og:url',
|
|
464
|
-
content: profileUrl,
|
|
465
|
-
},
|
|
466
|
-
{
|
|
467
|
-
property: 'og:site_name',
|
|
468
|
-
content: `${siteAssociation} Members`,
|
|
469
|
-
},
|
|
470
|
-
{
|
|
471
|
-
name: 'twitter:card',
|
|
472
|
-
content: 'summary_large_image',
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
name: 'twitter:title',
|
|
476
|
-
content: seoTitle,
|
|
477
|
-
},
|
|
478
|
-
{
|
|
479
|
-
name: 'twitter:description',
|
|
480
|
-
content: description,
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
name: 'twitter:image',
|
|
484
|
-
content: ogImage,
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
name: 'geo.region',
|
|
488
|
-
content: data.state || '',
|
|
489
|
-
},
|
|
490
|
-
{
|
|
491
|
-
name: 'geo.placename',
|
|
492
|
-
content: data.city || '',
|
|
493
|
-
},
|
|
494
|
-
].filter(tag => tag.content && tag.content.trim() !== '')
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
function generateSEOTitle({ fullName, areasOfPractices, siteAssociation }) {
|
|
499
|
-
return `${fullName}${
|
|
500
|
-
areasOfPractices && areasOfPractices.length > 0
|
|
501
|
-
? ` | ${areasOfPractices.slice(0, 3).join(', ')}`
|
|
502
|
-
: ''
|
|
503
|
-
} | ${siteAssociation} Member`;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
function stripHtmlTags(html) {
|
|
507
|
-
if (!html) return '';
|
|
508
|
-
return html
|
|
509
|
-
.replace(/<[^>]*>/g, '')
|
|
510
|
-
.replace(/ /g, ' ')
|
|
511
|
-
.replace(/&/g, '&')
|
|
512
|
-
.replace(/</g, '<')
|
|
513
|
-
.replace(/>/g, '>')
|
|
514
|
-
.replace(/"/g, '"')
|
|
515
|
-
.replace(/'/g, "'")
|
|
516
|
-
.replace(/\s+/g, ' ')
|
|
517
|
-
.trim();
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
module.exports = {
|
|
522
|
-
publicProfileOnReady,
|
|
523
|
-
};
|