abmp-npm 1.6.0 → 1.6.1
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/package.json +2 -1
- package/pages/PersonalDetailsForm.js +127 -100
- package/public/Utils/formValidation.js +33 -0
- package/public/consts.js +21 -0
- package/public/index.js +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abmp-npm",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@wix/essentials": "^0.1.28",
|
|
33
33
|
"@wix/members": "^1.0.330",
|
|
34
34
|
"@wix/site-location": "^1.31.0",
|
|
35
|
+
"@wix/site-storage": "^1.22.0",
|
|
35
36
|
"@wix/site-window": "^1.44.0",
|
|
36
37
|
"ngeohash": "^0.6.3",
|
|
37
38
|
"phone": "^3.1.67",
|
|
@@ -2,6 +2,14 @@ const { location: wixLocation } = require('@wix/site-location');
|
|
|
2
2
|
const { storage: wixStorage } = require('@wix/site-storage');
|
|
3
3
|
const { window: wixWindow } = require('@wix/site-window');
|
|
4
4
|
|
|
5
|
+
const {
|
|
6
|
+
ADDRESS_STATUS_TYPES,
|
|
7
|
+
DEFAULT_BUSINESS_NAME_TEXT,
|
|
8
|
+
FREE_WEBSITE_TEXT_STATES,
|
|
9
|
+
LIGHTBOX_NAMES,
|
|
10
|
+
ABMP_MEMBERS_HOME_URL,
|
|
11
|
+
} = require('../public/consts');
|
|
12
|
+
const { handleOnCustomValidation, isNotValidUrl } = require('../public/Utils/formValidation');
|
|
5
13
|
const { generateId } = require('../public/Utils/sharedUtils');
|
|
6
14
|
|
|
7
15
|
const MAX_PHONES_COUNT = 10;
|
|
@@ -54,18 +62,11 @@ async function personalDetailsFormOnReady({
|
|
|
54
62
|
saveRegistrationData,
|
|
55
63
|
validateMemberToken,
|
|
56
64
|
checkUrlUniqueness,
|
|
57
|
-
ADDRESS_STATUS_TYPES,
|
|
58
|
-
DEFAULT_BUSINESS_NAME_TEXT,
|
|
59
|
-
FREE_WEBSITE_TEXT_STATES,
|
|
60
|
-
LIGHTBOX_NAMES,
|
|
61
|
-
ABMP_MEMBERS_HOME_URL,
|
|
62
|
-
handleOnCustomValidation,
|
|
63
|
-
isNotValidUrl,
|
|
64
65
|
}) {
|
|
65
66
|
let itemMemberObj = {};
|
|
66
67
|
let originalMemberData = {};
|
|
67
68
|
let selectedServices = [];
|
|
68
|
-
|
|
69
|
+
const uploadedImages = {
|
|
69
70
|
profileImage: '',
|
|
70
71
|
logoImage: '',
|
|
71
72
|
bannerImage: '',
|
|
@@ -73,7 +74,7 @@ async function personalDetailsFormOnReady({
|
|
|
73
74
|
|
|
74
75
|
const FALLBACK_ADDRESS_STATUS = ADDRESS_STATUS_TYPES.STATE_CITY_ZIP;
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
const formHasUnsavedChanges = {
|
|
77
78
|
[FORM_SECTION_HANDLER_MAP.PERSONAL.section]: false,
|
|
78
79
|
[FORM_SECTION_HANDLER_MAP.BUSINESS_SERVICES.section]: false,
|
|
79
80
|
[FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING.section]: false,
|
|
@@ -81,7 +82,7 @@ async function personalDetailsFormOnReady({
|
|
|
81
82
|
[FORM_SECTION_HANDLER_MAP.WEBSITE_OPT_OUT.section]: false,
|
|
82
83
|
};
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
const slugValidationTimeout = {};
|
|
85
86
|
let isSlugValid = true;
|
|
86
87
|
let currentSlugValidationId = 0;
|
|
87
88
|
let memberData, isValid, isStudent;
|
|
@@ -147,7 +148,7 @@ async function personalDetailsFormOnReady({
|
|
|
147
148
|
originalMemberData = JSON.parse(JSON.stringify(memberData));
|
|
148
149
|
// Initialize selectedServices based on memberData
|
|
149
150
|
selectedServices = Array.isArray(itemMemberObj.areasOfPractices)
|
|
150
|
-
? itemMemberObj.areasOfPractices.map(
|
|
151
|
+
? itemMemberObj.areasOfPractices.map(label => ({ _id: generateId(), label: String(label) }))
|
|
151
152
|
: [];
|
|
152
153
|
|
|
153
154
|
$w('#mainMultiStateBox').changeState(MAIN_STATE_BOX_STATES.FORM_STATE);
|
|
@@ -230,7 +231,7 @@ async function personalDetailsFormOnReady({
|
|
|
230
231
|
}
|
|
231
232
|
function initGallery() {
|
|
232
233
|
$w('#galleryRepeater').onItemReady(handleGalleryItem);
|
|
233
|
-
$w('#uploadGalleryImageButton').onChange(async
|
|
234
|
+
$w('#uploadGalleryImageButton').onChange(async event => {
|
|
234
235
|
const $item = $w.at(event.context);
|
|
235
236
|
const uploadButton = $item('#uploadGalleryImageButton');
|
|
236
237
|
if (uploadButton.value.length === 0) return;
|
|
@@ -241,7 +242,7 @@ async function personalDetailsFormOnReady({
|
|
|
241
242
|
itemMemberObj.gallery = [];
|
|
242
243
|
}
|
|
243
244
|
|
|
244
|
-
uploadedFiles.forEach(
|
|
245
|
+
uploadedFiles.forEach(file => {
|
|
245
246
|
itemMemberObj.gallery.unshift({ src: file.fileUrl });
|
|
246
247
|
});
|
|
247
248
|
|
|
@@ -255,12 +256,12 @@ async function personalDetailsFormOnReady({
|
|
|
255
256
|
console.error('Upload failed:', error);
|
|
256
257
|
}
|
|
257
258
|
});
|
|
258
|
-
$w('#deleteImageButton').onClick(async
|
|
259
|
+
$w('#deleteImageButton').onClick(async event => {
|
|
259
260
|
const itemId = event.context.itemId;
|
|
260
|
-
const itemData = $w('#galleryRepeater').data.find(
|
|
261
|
+
const itemData = $w('#galleryRepeater').data.find(item => item._id === itemId);
|
|
261
262
|
const result = await wixWindow.openLightbox(LIGHTBOX_NAMES.DELETE_CONFIRM);
|
|
262
263
|
if (result && result.toDelete) {
|
|
263
|
-
itemMemberObj.gallery = itemMemberObj.gallery.filter(
|
|
264
|
+
itemMemberObj.gallery = itemMemberObj.gallery.filter(img => img.src !== itemData.image.src);
|
|
264
265
|
await saveGalleryToCMS();
|
|
265
266
|
setGallery(); // Re-render
|
|
266
267
|
}
|
|
@@ -275,8 +276,6 @@ async function personalDetailsFormOnReady({
|
|
|
275
276
|
|
|
276
277
|
$w('#slugInput').value = itemMemberObj.url || '';
|
|
277
278
|
|
|
278
|
-
isSlugValid = true;
|
|
279
|
-
|
|
280
279
|
$w(SLUG_FLAGS.VALID).collapse();
|
|
281
280
|
$w(SLUG_FLAGS.INVALID).collapse();
|
|
282
281
|
|
|
@@ -284,7 +283,7 @@ async function personalDetailsFormOnReady({
|
|
|
284
283
|
$w('#profileLink').link = fullProfilePageLink;
|
|
285
284
|
$w('#profileLink').target = '_blank';
|
|
286
285
|
$w('#licenceNoText').text = (itemMemberObj.licenses || [])
|
|
287
|
-
.map(
|
|
286
|
+
.map(val => val.license)
|
|
288
287
|
.filter(Boolean)
|
|
289
288
|
.join(', ');
|
|
290
289
|
const handleIsStudent = () => {
|
|
@@ -306,7 +305,7 @@ async function personalDetailsFormOnReady({
|
|
|
306
305
|
'#optConfirmationBox',
|
|
307
306
|
'#yesOptButton',
|
|
308
307
|
'#cancelOptButton',
|
|
309
|
-
|
|
308
|
+
confirmed => handleOptConfirmation(confirmed, '#optCheckbox', '#optConfirmationBox', 'optOut')
|
|
310
309
|
);
|
|
311
310
|
|
|
312
311
|
setupOptOutCheckbox(
|
|
@@ -314,15 +313,27 @@ async function personalDetailsFormOnReady({
|
|
|
314
313
|
'#optWebsiteConfirmationBox',
|
|
315
314
|
'#yesOptWebsiteButton',
|
|
316
315
|
'#cancelOptwebsiteButton',
|
|
317
|
-
|
|
316
|
+
confirmed =>
|
|
317
|
+
handleOptConfirmation(
|
|
318
|
+
confirmed,
|
|
319
|
+
'#optWebsiteCheckbox',
|
|
320
|
+
'#optWebsiteConfirmationBox',
|
|
321
|
+
'showWixUrl'
|
|
322
|
+
)
|
|
318
323
|
);
|
|
319
324
|
}
|
|
320
325
|
|
|
321
|
-
function setupOptOutCheckbox(
|
|
326
|
+
function setupOptOutCheckbox(
|
|
327
|
+
checkboxId,
|
|
328
|
+
confirmationBoxId,
|
|
329
|
+
confirmBtnId,
|
|
330
|
+
cancelBtnId,
|
|
331
|
+
confirmCallback
|
|
332
|
+
) {
|
|
322
333
|
const checkbox = $w(checkboxId);
|
|
323
334
|
const box = $w(confirmationBoxId);
|
|
324
335
|
|
|
325
|
-
checkbox.onChange(
|
|
336
|
+
checkbox.onChange(e => {
|
|
326
337
|
if (!e.target.checked) {
|
|
327
338
|
box.expand();
|
|
328
339
|
checkbox.disable();
|
|
@@ -433,18 +444,18 @@ async function personalDetailsFormOnReady({
|
|
|
433
444
|
{ $elem: elements.$UrlInput, changeEvent: CHANGE_EVENTS.ON_INPUT },
|
|
434
445
|
],
|
|
435
446
|
};
|
|
436
|
-
Object.keys(formChangeEventBindings).forEach(
|
|
447
|
+
Object.keys(formChangeEventBindings).forEach(section => {
|
|
437
448
|
formChangeEventBindings[section].forEach(({ $elem, changeEvent }) => {
|
|
438
449
|
$elem[changeEvent](() => {
|
|
439
450
|
const handlerMap = Object.values(FORM_SECTION_HANDLER_MAP).find(
|
|
440
|
-
|
|
451
|
+
handlerMap => handlerMap.section === section
|
|
441
452
|
);
|
|
442
453
|
checkFormChanges(handlerMap);
|
|
443
454
|
});
|
|
444
455
|
});
|
|
445
456
|
});
|
|
446
457
|
|
|
447
|
-
$w('#slugInput').onInput(
|
|
458
|
+
$w('#slugInput').onInput(event => {
|
|
448
459
|
$w('#savePersonalButton').disable();
|
|
449
460
|
const slug = event.target.value;
|
|
450
461
|
|
|
@@ -500,7 +511,8 @@ async function personalDetailsFormOnReady({
|
|
|
500
511
|
isSlugValid = true;
|
|
501
512
|
if (formDataType === FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING.section) {
|
|
502
513
|
isEmailValid = $w('#contactFormEmailInput').valid;
|
|
503
|
-
isUrlValid =
|
|
514
|
+
isUrlValid =
|
|
515
|
+
!isNotValidUrl($w('#UrlInput').value) && !isNotValidUrl($w('#schedulingLinkInput').value);
|
|
504
516
|
}
|
|
505
517
|
if (formDataType === FORM_SECTION_HANDLER_MAP.PERSONAL.section) {
|
|
506
518
|
isNameValid = $w('#firstNameInput').valid && $w('#lastNameInput').valid;
|
|
@@ -587,7 +599,7 @@ async function personalDetailsFormOnReady({
|
|
|
587
599
|
// Get memberships array
|
|
588
600
|
const memberships = Array.isArray(itemMemberObj.memberships) ? itemMemberObj.memberships : [];
|
|
589
601
|
// Find ABMP object
|
|
590
|
-
const abmp = memberships.find(
|
|
602
|
+
const abmp = memberships.find(m => m.association === 'ABMP');
|
|
591
603
|
// Set yearJoinedText
|
|
592
604
|
if (abmp && abmp.membersince) {
|
|
593
605
|
$w('#yearJoinedText').text = abmp.membersince;
|
|
@@ -607,7 +619,7 @@ async function personalDetailsFormOnReady({
|
|
|
607
619
|
}
|
|
608
620
|
|
|
609
621
|
if (Array.isArray(itemMemberObj.areasOfPractices)) {
|
|
610
|
-
selectedServices = itemMemberObj.areasOfPractices.map(
|
|
622
|
+
selectedServices = itemMemberObj.areasOfPractices.map(label => ({
|
|
611
623
|
_id: generateId(),
|
|
612
624
|
label: String(label),
|
|
613
625
|
}));
|
|
@@ -628,7 +640,7 @@ async function personalDetailsFormOnReady({
|
|
|
628
640
|
if ($w(uploadButton).value?.length > 0) {
|
|
629
641
|
try {
|
|
630
642
|
const uploadedFiles = await $w(uploadButton).uploadFiles();
|
|
631
|
-
uploadedFiles.forEach(
|
|
643
|
+
uploadedFiles.forEach(file => {
|
|
632
644
|
uploadedImages[imageKey] = file.fileUrl;
|
|
633
645
|
updateUI(file);
|
|
634
646
|
});
|
|
@@ -669,19 +681,19 @@ async function personalDetailsFormOnReady({
|
|
|
669
681
|
}
|
|
670
682
|
|
|
671
683
|
function setupImageUploadAndDeleteHandlers() {
|
|
672
|
-
uploadImage('#uploadProfileButton', 'profileImage',
|
|
684
|
+
uploadImage('#uploadProfileButton', 'profileImage', file => {
|
|
673
685
|
$w('#profileImage').src = file.fileUrl;
|
|
674
686
|
$w('#profileImageName').text = formatFileName(file.fileName);
|
|
675
687
|
$w('#profileImageContainer').expand();
|
|
676
688
|
});
|
|
677
689
|
|
|
678
|
-
uploadImage('#uploadLogoButton', 'logoImage',
|
|
690
|
+
uploadImage('#uploadLogoButton', 'logoImage', file => {
|
|
679
691
|
$w('#logoImage').src = file.fileUrl;
|
|
680
692
|
$w('#logoImageName').text = file.fileName;
|
|
681
693
|
$w('#logoImageContainer').expand();
|
|
682
694
|
});
|
|
683
695
|
|
|
684
|
-
uploadImage('#uploadBannerButton', 'bannerImage',
|
|
696
|
+
uploadImage('#uploadBannerButton', 'bannerImage', file => {
|
|
685
697
|
$w('#bannerImage').src = file.fileUrl;
|
|
686
698
|
$w('#bannerImageName').text = file.fileName;
|
|
687
699
|
$w('#bannerImageContainer').expand();
|
|
@@ -777,7 +789,7 @@ async function personalDetailsFormOnReady({
|
|
|
777
789
|
arrayRef.splice(
|
|
778
790
|
0,
|
|
779
791
|
arrayRef.length,
|
|
780
|
-
...arrayRef.filter(
|
|
792
|
+
...arrayRef.filter(item =>
|
|
781
793
|
typeof item === 'string' ? item !== textToRemove : item[matchField] !== textToRemove
|
|
782
794
|
)
|
|
783
795
|
);
|
|
@@ -790,7 +802,7 @@ async function personalDetailsFormOnReady({
|
|
|
790
802
|
async function setInterestData() {
|
|
791
803
|
const interestsData = await getInterestAll();
|
|
792
804
|
|
|
793
|
-
$w('#removeServiceButton').onClick(
|
|
805
|
+
$w('#removeServiceButton').onClick(event => {
|
|
794
806
|
handleItemDelete(event, '#serviceNameText', selectedServices, 'label', renderServices);
|
|
795
807
|
});
|
|
796
808
|
|
|
@@ -801,7 +813,7 @@ async function personalDetailsFormOnReady({
|
|
|
801
813
|
}));
|
|
802
814
|
|
|
803
815
|
$w('#repeaterInterest').data = formattedData;
|
|
804
|
-
$w('#repeaterInterest').onItemReady(($item, itemData,
|
|
816
|
+
$w('#repeaterInterest').onItemReady(($item, itemData, _index) => {
|
|
805
817
|
$item('#interestText').text = itemData.value;
|
|
806
818
|
});
|
|
807
819
|
}
|
|
@@ -827,7 +839,7 @@ async function personalDetailsFormOnReady({
|
|
|
827
839
|
// }, 150);
|
|
828
840
|
// });
|
|
829
841
|
|
|
830
|
-
intrestInput.onKeyPress(
|
|
842
|
+
intrestInput.onKeyPress(event => {
|
|
831
843
|
debounce_fun();
|
|
832
844
|
|
|
833
845
|
if (event.key === 'Enter') {
|
|
@@ -835,7 +847,9 @@ async function personalDetailsFormOnReady({
|
|
|
835
847
|
|
|
836
848
|
if (
|
|
837
849
|
typedValue &&
|
|
838
|
-
!selectedServices.some(
|
|
850
|
+
!selectedServices.some(
|
|
851
|
+
service => service.label.toLowerCase() === typedValue.toLowerCase()
|
|
852
|
+
)
|
|
839
853
|
) {
|
|
840
854
|
selectedServices.unshift({
|
|
841
855
|
_id: generateId(),
|
|
@@ -853,7 +867,7 @@ async function personalDetailsFormOnReady({
|
|
|
853
867
|
$item('#interestText').text = itemData.value;
|
|
854
868
|
|
|
855
869
|
$item('#intrestItem').onClick(() => {
|
|
856
|
-
if (!selectedServices.some(
|
|
870
|
+
if (!selectedServices.some(service => service.label === itemData.value)) {
|
|
857
871
|
selectedServices.unshift({
|
|
858
872
|
_id: generateId(),
|
|
859
873
|
label: itemData.value,
|
|
@@ -887,7 +901,9 @@ async function personalDetailsFormOnReady({
|
|
|
887
901
|
const memberId = wixStorage.local.getItem('memberId');
|
|
888
902
|
const timestamp = new Date().toISOString();
|
|
889
903
|
|
|
890
|
-
console.group(
|
|
904
|
+
console.group(
|
|
905
|
+
`User Data Change Log - ${saveType.toUpperCase()} - ${success ? 'SUCCESS' : 'FAILED'}`
|
|
906
|
+
);
|
|
891
907
|
console.log('Change Details:', {
|
|
892
908
|
memberId,
|
|
893
909
|
timestamp,
|
|
@@ -900,7 +916,7 @@ async function personalDetailsFormOnReady({
|
|
|
900
916
|
|
|
901
917
|
// Calculate and log specific changes
|
|
902
918
|
const changes = {};
|
|
903
|
-
Object.keys(afterData).forEach(
|
|
919
|
+
Object.keys(afterData).forEach(key => {
|
|
904
920
|
if (JSON.stringify(beforeData[key]) !== JSON.stringify(afterData[key])) {
|
|
905
921
|
changes[key] = {
|
|
906
922
|
before: beforeData[key],
|
|
@@ -942,7 +958,8 @@ async function personalDetailsFormOnReady({
|
|
|
942
958
|
|
|
943
959
|
return {
|
|
944
960
|
success: false,
|
|
945
|
-
message:
|
|
961
|
+
message:
|
|
962
|
+
"It looks like something went wrong — the information wasn't saved. Please try again later.",
|
|
946
963
|
};
|
|
947
964
|
}
|
|
948
965
|
}
|
|
@@ -1024,8 +1041,8 @@ async function personalDetailsFormOnReady({
|
|
|
1024
1041
|
function getBusinessAndServicesData() {
|
|
1025
1042
|
const getCurrentTestimonials = () =>
|
|
1026
1043
|
$w('#testimonialRepeater')
|
|
1027
|
-
.data.filter(
|
|
1028
|
-
.map(
|
|
1044
|
+
.data.filter(item => item.isAdd === false)
|
|
1045
|
+
.map(item => item.text)
|
|
1029
1046
|
.filter(Boolean) || itemMemberObj.testimonial;
|
|
1030
1047
|
|
|
1031
1048
|
return {
|
|
@@ -1035,7 +1052,7 @@ async function personalDetailsFormOnReady({
|
|
|
1035
1052
|
profileImage: uploadedImages.profileImage,
|
|
1036
1053
|
logoImage: uploadedImages.logoImage,
|
|
1037
1054
|
bannerImages: uploadedImages.bannerImage ? [uploadedImages.bannerImage] : [],
|
|
1038
|
-
areasOfPractices: selectedServices.map(
|
|
1055
|
+
areasOfPractices: selectedServices.map(service => service.label),
|
|
1039
1056
|
aboutService: $w('#aboutInput').value,
|
|
1040
1057
|
testimonial: getCurrentTestimonials(),
|
|
1041
1058
|
};
|
|
@@ -1063,7 +1080,11 @@ async function personalDetailsFormOnReady({
|
|
|
1063
1080
|
if (result.success) {
|
|
1064
1081
|
if (personalChanges.url && personalChanges.url !== originalUrl) {
|
|
1065
1082
|
const newProfileLink = `${wixLocation.baseUrl}/profile/${personalChanges.url}`;
|
|
1066
|
-
console.log('🔗 Updating profile link:', {
|
|
1083
|
+
console.log('🔗 Updating profile link:', {
|
|
1084
|
+
originalUrl,
|
|
1085
|
+
newUrl: personalChanges.url,
|
|
1086
|
+
newProfileLink,
|
|
1087
|
+
});
|
|
1067
1088
|
$w('#profileLink').text = newProfileLink;
|
|
1068
1089
|
$w('#profileLink').link = newProfileLink;
|
|
1069
1090
|
|
|
@@ -1109,8 +1130,14 @@ async function personalDetailsFormOnReady({
|
|
|
1109
1130
|
const addTestimonialButton = $w('#addTestimonialButton');
|
|
1110
1131
|
|
|
1111
1132
|
addTestimonialButton.onClick(handleAddTestimonial);
|
|
1112
|
-
$w('#deleteTestimonialButton').onClick(
|
|
1113
|
-
handleItemDelete(
|
|
1133
|
+
$w('#deleteTestimonialButton').onClick(event => {
|
|
1134
|
+
handleItemDelete(
|
|
1135
|
+
event,
|
|
1136
|
+
'#testimonialText',
|
|
1137
|
+
itemMemberObj.testimonial,
|
|
1138
|
+
null,
|
|
1139
|
+
renderTestimonials
|
|
1140
|
+
);
|
|
1114
1141
|
});
|
|
1115
1142
|
|
|
1116
1143
|
renderTestimonials();
|
|
@@ -1135,7 +1162,7 @@ async function personalDetailsFormOnReady({
|
|
|
1135
1162
|
const addItem = { _id: 'add-item', text: '', isAdd: true };
|
|
1136
1163
|
const testimonialData = [
|
|
1137
1164
|
addItem,
|
|
1138
|
-
...testimonials.map(
|
|
1165
|
+
...testimonials.map(text => ({ _id: generateId(), text, isAdd: false })),
|
|
1139
1166
|
];
|
|
1140
1167
|
|
|
1141
1168
|
setupRepeater('#testimonialRepeater', testimonialData);
|
|
@@ -1202,7 +1229,7 @@ async function personalDetailsFormOnReady({
|
|
|
1202
1229
|
});
|
|
1203
1230
|
|
|
1204
1231
|
// toggle handlers
|
|
1205
|
-
$w('#showUrlWixCheckbox').onChange(
|
|
1232
|
+
$w('#showUrlWixCheckbox').onChange(e => {
|
|
1206
1233
|
if (e.target.checked) {
|
|
1207
1234
|
$w('#showExsistingUrlCheckbox').checked = false;
|
|
1208
1235
|
$w('#UrlInput').disable();
|
|
@@ -1210,7 +1237,7 @@ async function personalDetailsFormOnReady({
|
|
|
1210
1237
|
}
|
|
1211
1238
|
checkFormChanges(FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING);
|
|
1212
1239
|
});
|
|
1213
|
-
$w('#showExsistingUrlCheckbox').onChange(
|
|
1240
|
+
$w('#showExsistingUrlCheckbox').onChange(e => {
|
|
1214
1241
|
if (e.target.checked) {
|
|
1215
1242
|
$w('#showUrlWixCheckbox').checked = false;
|
|
1216
1243
|
$w('#UrlInput').enable();
|
|
@@ -1239,7 +1266,9 @@ async function personalDetailsFormOnReady({
|
|
|
1239
1266
|
const formatted = formatFullAddress(address);
|
|
1240
1267
|
|
|
1241
1268
|
const hasValidCoordinates = Boolean(address.latitude && address.longitude);
|
|
1242
|
-
const location = hasValidCoordinates
|
|
1269
|
+
const location = hasValidCoordinates
|
|
1270
|
+
? { latitude: address.latitude, longitude: address.longitude }
|
|
1271
|
+
: null;
|
|
1243
1272
|
|
|
1244
1273
|
return {
|
|
1245
1274
|
formatted,
|
|
@@ -1283,14 +1312,16 @@ async function personalDetailsFormOnReady({
|
|
|
1283
1312
|
state: addressInputValue.subdivision || '',
|
|
1284
1313
|
postalcode: addressInputValue.postalCode || '',
|
|
1285
1314
|
country: addressInputValue.country || 'US',
|
|
1286
|
-
latitude: addressInputValue.location?.latitude ||
|
|
1287
|
-
longitude: addressInputValue.location?.longitude ||
|
|
1315
|
+
latitude: addressInputValue.location?.latitude || existingAddress?.latitude || 0,
|
|
1316
|
+
longitude: addressInputValue.location?.longitude || existingAddress?.longitude || 0,
|
|
1288
1317
|
addressStatus: existingAddress?.addressStatus || FALLBACK_ADDRESS_STATUS,
|
|
1289
1318
|
};
|
|
1290
1319
|
}
|
|
1291
1320
|
|
|
1292
1321
|
function setupAddressRepeater() {
|
|
1293
|
-
$w('#addressesList').onItemReady(($item, itemData,
|
|
1322
|
+
$w('#addressesList').onItemReady(($item, itemData, _index) =>
|
|
1323
|
+
handleAddressItem($item, itemData, _index)
|
|
1324
|
+
);
|
|
1294
1325
|
renderAddressesList();
|
|
1295
1326
|
|
|
1296
1327
|
$w('#newAddressButton').onClick(addNewAddress);
|
|
@@ -1299,9 +1330,9 @@ async function personalDetailsFormOnReady({
|
|
|
1299
1330
|
}
|
|
1300
1331
|
|
|
1301
1332
|
function setupAddressRepeaterEventListeners() {
|
|
1302
|
-
$w('#mainAddressCheckbox').onChange(
|
|
1333
|
+
$w('#mainAddressCheckbox').onChange(event => {
|
|
1303
1334
|
const data = $w('#addressesList').data;
|
|
1304
|
-
const clickedItemData = data.find(
|
|
1335
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1305
1336
|
const $item = $w.at(event.context);
|
|
1306
1337
|
|
|
1307
1338
|
$w('#mainAddressCheckbox').checked = false;
|
|
@@ -1316,9 +1347,9 @@ async function personalDetailsFormOnReady({
|
|
|
1316
1347
|
checkFormChanges(FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING);
|
|
1317
1348
|
});
|
|
1318
1349
|
|
|
1319
|
-
$w('#addressStatusOptions').onChange(
|
|
1350
|
+
$w('#addressStatusOptions').onChange(event => {
|
|
1320
1351
|
const data = $w('#addressesList').data;
|
|
1321
|
-
const clickedItemData = data.find(
|
|
1352
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1322
1353
|
const newStatus = event.target.value;
|
|
1323
1354
|
const $item = $w.at(event.context);
|
|
1324
1355
|
const isMain = $item('#mainAddressCheckbox').checked;
|
|
@@ -1332,32 +1363,32 @@ async function personalDetailsFormOnReady({
|
|
|
1332
1363
|
checkFormChanges(FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING);
|
|
1333
1364
|
});
|
|
1334
1365
|
|
|
1335
|
-
$w('#addressItemEditBtn').onClick(
|
|
1366
|
+
$w('#addressItemEditBtn').onClick(event => {
|
|
1336
1367
|
const data = $w('#addressesList').data;
|
|
1337
|
-
const clickedItemData = data.find(
|
|
1368
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1338
1369
|
const $item = $w.at(event.context);
|
|
1339
1370
|
$item('#addressItemStates').changeState(ADDRESS_STATES.EDIT);
|
|
1340
1371
|
const addressInputValue = convertToAddressInputFormat(clickedItemData.address);
|
|
1341
1372
|
$item('#addressEditInput').value = addressInputValue;
|
|
1342
1373
|
});
|
|
1343
1374
|
|
|
1344
|
-
$w('#addressItemRemoveBtn').onClick(async
|
|
1375
|
+
$w('#addressItemRemoveBtn').onClick(async event => {
|
|
1345
1376
|
const data = $w('#addressesList').data;
|
|
1346
|
-
const clickedItemData = data.find(
|
|
1377
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1347
1378
|
const result = await wixWindow.openLightbox(LIGHTBOX_NAMES.DELETE_CONFIRM);
|
|
1348
1379
|
if (result && result.toDelete) {
|
|
1349
1380
|
removeAddress(clickedItemData._id);
|
|
1350
1381
|
}
|
|
1351
1382
|
});
|
|
1352
1383
|
|
|
1353
|
-
$w('#addressEditInput').onChange(
|
|
1384
|
+
$w('#addressEditInput').onChange(event => {
|
|
1354
1385
|
const $item = $w.at(event.context);
|
|
1355
1386
|
validateAddressCompleteness($item);
|
|
1356
1387
|
});
|
|
1357
1388
|
|
|
1358
|
-
$w('#addressEditCancelBtn').onClick(
|
|
1389
|
+
$w('#addressEditCancelBtn').onClick(event => {
|
|
1359
1390
|
const data = $w('#addressesList').data;
|
|
1360
|
-
const clickedItemData = data.find(
|
|
1391
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1361
1392
|
const $item = $w.at(event.context);
|
|
1362
1393
|
if (clickedItemData.isNewAddress) {
|
|
1363
1394
|
removeNewAddressFromRepeater(clickedItemData._id);
|
|
@@ -1367,9 +1398,9 @@ async function personalDetailsFormOnReady({
|
|
|
1367
1398
|
}
|
|
1368
1399
|
});
|
|
1369
1400
|
|
|
1370
|
-
$w('#addressEditSaveBtn').onClick(
|
|
1401
|
+
$w('#addressEditSaveBtn').onClick(event => {
|
|
1371
1402
|
const data = $w('#addressesList').data;
|
|
1372
|
-
const clickedItemData = data.find(
|
|
1403
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1373
1404
|
const $item = $w.at(event.context);
|
|
1374
1405
|
saveAddressFromSingleInput($item, clickedItemData);
|
|
1375
1406
|
});
|
|
@@ -1433,7 +1464,7 @@ async function personalDetailsFormOnReady({
|
|
|
1433
1464
|
$item('#addressStatusOptions').value = addressStatus;
|
|
1434
1465
|
}
|
|
1435
1466
|
|
|
1436
|
-
function setupAddressEditState($item, itemData,
|
|
1467
|
+
function setupAddressEditState($item, itemData, _index) {
|
|
1437
1468
|
$item('#addressEditInput').enable();
|
|
1438
1469
|
|
|
1439
1470
|
const addressInputValue = convertToAddressInputFormat(itemData.address);
|
|
@@ -1526,7 +1557,7 @@ async function personalDetailsFormOnReady({
|
|
|
1526
1557
|
|
|
1527
1558
|
function removeNewAddressFromRepeater(addressId) {
|
|
1528
1559
|
const currentData = $w('#addressesList').data || [];
|
|
1529
|
-
const updatedData = currentData.filter(
|
|
1560
|
+
const updatedData = currentData.filter(item => item._id !== addressId);
|
|
1530
1561
|
$w('#addressesList').data = updatedData;
|
|
1531
1562
|
}
|
|
1532
1563
|
|
|
@@ -1568,7 +1599,7 @@ async function personalDetailsFormOnReady({
|
|
|
1568
1599
|
: [];
|
|
1569
1600
|
|
|
1570
1601
|
addressData = addresses.map((address, index) => {
|
|
1571
|
-
const displayOption = displayOptions.find(
|
|
1602
|
+
const displayOption = displayOptions.find(opt => opt.key === address.key);
|
|
1572
1603
|
return {
|
|
1573
1604
|
_id: address.key || `address_${index}`,
|
|
1574
1605
|
address,
|
|
@@ -1601,11 +1632,11 @@ async function personalDetailsFormOnReady({
|
|
|
1601
1632
|
itemMemberObj.addressDisplayOption = [];
|
|
1602
1633
|
}
|
|
1603
1634
|
|
|
1604
|
-
itemMemberObj.addressDisplayOption.forEach(
|
|
1635
|
+
itemMemberObj.addressDisplayOption.forEach(option => {
|
|
1605
1636
|
option.isMain = false;
|
|
1606
1637
|
});
|
|
1607
1638
|
|
|
1608
|
-
const selectedOption = itemMemberObj.addressDisplayOption.find(
|
|
1639
|
+
const selectedOption = itemMemberObj.addressDisplayOption.find(opt => opt.key === selectedId);
|
|
1609
1640
|
|
|
1610
1641
|
selectedOption.isMain = true;
|
|
1611
1642
|
}
|
|
@@ -1613,7 +1644,7 @@ async function personalDetailsFormOnReady({
|
|
|
1613
1644
|
function updateAddressStatus(addressId, newStatus) {
|
|
1614
1645
|
const addresses = Array.isArray(itemMemberObj.addresses) ? itemMemberObj.addresses : [];
|
|
1615
1646
|
const addressIndex = addresses.findIndex(
|
|
1616
|
-
|
|
1647
|
+
addr => (addr.key || `address_${addresses.indexOf(addr)}`) === addressId
|
|
1617
1648
|
);
|
|
1618
1649
|
|
|
1619
1650
|
if (addressIndex !== -1) {
|
|
@@ -1624,7 +1655,7 @@ async function personalDetailsFormOnReady({
|
|
|
1624
1655
|
function updateAddress(addressId, newAddressValue) {
|
|
1625
1656
|
const addresses = Array.isArray(itemMemberObj.addresses) ? itemMemberObj.addresses : [];
|
|
1626
1657
|
const addressIndex = addresses.findIndex(
|
|
1627
|
-
|
|
1658
|
+
addr => (addr.key || `address_${addresses.indexOf(addr)}`) === addressId
|
|
1628
1659
|
);
|
|
1629
1660
|
|
|
1630
1661
|
if (addressIndex !== -1) {
|
|
@@ -1640,12 +1671,14 @@ async function personalDetailsFormOnReady({
|
|
|
1640
1671
|
function removeAddress(addressId) {
|
|
1641
1672
|
if (itemMemberObj.addresses) {
|
|
1642
1673
|
itemMemberObj.addresses = itemMemberObj.addresses.filter(
|
|
1643
|
-
|
|
1674
|
+
addr => (addr.key || `address_${itemMemberObj.addresses.indexOf(addr)}`) !== addressId
|
|
1644
1675
|
);
|
|
1645
1676
|
}
|
|
1646
1677
|
|
|
1647
1678
|
if (itemMemberObj.addressDisplayOption) {
|
|
1648
|
-
itemMemberObj.addressDisplayOption = itemMemberObj.addressDisplayOption.filter(
|
|
1679
|
+
itemMemberObj.addressDisplayOption = itemMemberObj.addressDisplayOption.filter(
|
|
1680
|
+
opt => opt.key !== addressId
|
|
1681
|
+
);
|
|
1649
1682
|
}
|
|
1650
1683
|
|
|
1651
1684
|
renderAddressesList();
|
|
@@ -1680,9 +1713,9 @@ async function personalDetailsFormOnReady({
|
|
|
1680
1713
|
}
|
|
1681
1714
|
|
|
1682
1715
|
function setupPhoneRepeaterEventListeners() {
|
|
1683
|
-
$w('#phoneInput').onInput(
|
|
1716
|
+
$w('#phoneInput').onInput(event => {
|
|
1684
1717
|
const data = $w('#phoneNumbersList').data;
|
|
1685
|
-
const clickedItemData = data.find(
|
|
1718
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1686
1719
|
const phoneValue = event.target.value;
|
|
1687
1720
|
|
|
1688
1721
|
updatePhoneNumber(clickedItemData._id, phoneValue);
|
|
@@ -1695,9 +1728,9 @@ async function personalDetailsFormOnReady({
|
|
|
1695
1728
|
checkFormChanges(FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING);
|
|
1696
1729
|
});
|
|
1697
1730
|
|
|
1698
|
-
$w('#showPhoneCheckbox').onChange(
|
|
1731
|
+
$w('#showPhoneCheckbox').onChange(event => {
|
|
1699
1732
|
const data = $w('#phoneNumbersList').data;
|
|
1700
|
-
const clickedItemData = data.find(
|
|
1733
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1701
1734
|
const $item = $w.at(event.context);
|
|
1702
1735
|
|
|
1703
1736
|
$w('#showPhoneCheckbox').checked = false;
|
|
@@ -1707,9 +1740,9 @@ async function personalDetailsFormOnReady({
|
|
|
1707
1740
|
checkFormChanges(FORM_SECTION_HANDLER_MAP.CONTACT_BOOKING);
|
|
1708
1741
|
});
|
|
1709
1742
|
|
|
1710
|
-
$w('#removePhoneBtn').onClick(async
|
|
1743
|
+
$w('#removePhoneBtn').onClick(async event => {
|
|
1711
1744
|
const data = $w('#phoneNumbersList').data;
|
|
1712
|
-
const clickedItemData = data.find(
|
|
1745
|
+
const clickedItemData = data.find(item => item._id === event.context.itemId);
|
|
1713
1746
|
const result = await wixWindow.openLightbox(LIGHTBOX_NAMES.DELETE_CONFIRM);
|
|
1714
1747
|
if (result && result.toDelete) {
|
|
1715
1748
|
removePhone(clickedItemData._id);
|
|
@@ -1776,7 +1809,7 @@ async function personalDetailsFormOnReady({
|
|
|
1776
1809
|
|
|
1777
1810
|
function updatePhoneNumber(phoneId, newPhoneNumber) {
|
|
1778
1811
|
const currentData = $w('#phoneNumbersList').data || [];
|
|
1779
|
-
const itemIndex = currentData.findIndex(
|
|
1812
|
+
const itemIndex = currentData.findIndex(item => item._id === phoneId);
|
|
1780
1813
|
|
|
1781
1814
|
if (itemIndex !== -1) {
|
|
1782
1815
|
currentData[itemIndex].phoneNumber = newPhoneNumber;
|
|
@@ -1789,8 +1822,8 @@ async function personalDetailsFormOnReady({
|
|
|
1789
1822
|
function syncPhonesFromRepeater() {
|
|
1790
1823
|
const phoneData = $w('#phoneNumbersList').data || [];
|
|
1791
1824
|
itemMemberObj.phones = phoneData
|
|
1792
|
-
.filter(
|
|
1793
|
-
.map(
|
|
1825
|
+
.filter(item => !item.isNewPhone && item.phoneNumber.trim())
|
|
1826
|
+
.map(item => item.phoneNumber);
|
|
1794
1827
|
}
|
|
1795
1828
|
|
|
1796
1829
|
function addNewPhoneToData(phoneId, phoneNumber) {
|
|
@@ -1805,21 +1838,21 @@ async function personalDetailsFormOnReady({
|
|
|
1805
1838
|
|
|
1806
1839
|
function removePhone(phoneId) {
|
|
1807
1840
|
const currentData = $w('#phoneNumbersList').data || [];
|
|
1808
|
-
const phoneToRemove = currentData.find(
|
|
1841
|
+
const phoneToRemove = currentData.find(item => item._id === phoneId);
|
|
1809
1842
|
|
|
1810
1843
|
if (phoneToRemove) {
|
|
1811
1844
|
if (itemMemberObj.toShowPhone === phoneToRemove.phoneNumber) {
|
|
1812
1845
|
itemMemberObj.toShowPhone = null;
|
|
1813
1846
|
}
|
|
1814
1847
|
|
|
1815
|
-
const updatedData = currentData.filter(
|
|
1848
|
+
const updatedData = currentData.filter(item => item._id !== phoneId);
|
|
1816
1849
|
renderPhonesList(updatedData);
|
|
1817
1850
|
}
|
|
1818
1851
|
}
|
|
1819
1852
|
|
|
1820
1853
|
function updateShowPhoneSelection(phoneId, isVisible) {
|
|
1821
1854
|
const currentData = $w('#phoneNumbersList').data || [];
|
|
1822
|
-
const selectedItem = currentData.find(
|
|
1855
|
+
const selectedItem = currentData.find(item => item._id === phoneId);
|
|
1823
1856
|
|
|
1824
1857
|
if (selectedItem && selectedItem.phoneNumber) {
|
|
1825
1858
|
if (isVisible) {
|
|
@@ -1906,7 +1939,7 @@ async function personalDetailsFormOnReady({
|
|
|
1906
1939
|
function buildGalleryData(gallery) {
|
|
1907
1940
|
return [
|
|
1908
1941
|
{ _id: 'add-item', isAdd: true },
|
|
1909
|
-
...gallery.map(
|
|
1942
|
+
...gallery.map(image => ({
|
|
1910
1943
|
_id: generateId(),
|
|
1911
1944
|
image,
|
|
1912
1945
|
isAdd: false,
|
|
@@ -1955,16 +1988,10 @@ async function personalDetailsFormOnReady({
|
|
|
1955
1988
|
const container = $w('#containerRepeaterInterest');
|
|
1956
1989
|
const repeater = $w('#repeaterInterest');
|
|
1957
1990
|
|
|
1958
|
-
// if (!searchValue) {
|
|
1959
|
-
// container.collapse();
|
|
1960
|
-
// repeater.data = [];
|
|
1961
|
-
// return [];
|
|
1962
|
-
// }
|
|
1963
|
-
|
|
1964
1991
|
const allInterests = await getInterestAll();
|
|
1965
1992
|
const filtered = allInterests
|
|
1966
|
-
.filter(
|
|
1967
|
-
.map(
|
|
1993
|
+
.filter(val => val.toLowerCase().includes(searchValue))
|
|
1994
|
+
.map(val => ({ _id: generateId(), value: val }));
|
|
1968
1995
|
|
|
1969
1996
|
if (filtered.length > 0) {
|
|
1970
1997
|
repeater.data = filtered;
|
|
@@ -1977,7 +2004,8 @@ async function personalDetailsFormOnReady({
|
|
|
1977
2004
|
return filtered;
|
|
1978
2005
|
}
|
|
1979
2006
|
|
|
1980
|
-
|
|
2007
|
+
// Declare debounce_fun - uses filterInterests above
|
|
2008
|
+
const debounce_fun = _.debounce(async () => {
|
|
1981
2009
|
const searchValue = $w('#intrestInput').value.trim().toLowerCase();
|
|
1982
2010
|
await filterInterests(searchValue);
|
|
1983
2011
|
}, 250);
|
|
@@ -1986,4 +2014,3 @@ async function personalDetailsFormOnReady({
|
|
|
1986
2014
|
module.exports = {
|
|
1987
2015
|
personalDetailsFormOnReady,
|
|
1988
2016
|
};
|
|
1989
|
-
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handle custom validation for URL inputs
|
|
3
|
+
* @param {Object} element - The input element to validate
|
|
4
|
+
*/
|
|
5
|
+
function handleOnCustomValidation(element) {
|
|
6
|
+
element.onCustomValidation((value, reject) => {
|
|
7
|
+
if (isNotValidUrl(value)) {
|
|
8
|
+
reject('Please enter a valid URL');
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check if URL is not valid using regex
|
|
15
|
+
* @param {string} url - The URL to validate
|
|
16
|
+
* @returns {boolean} - True if URL is invalid, false if valid
|
|
17
|
+
*/
|
|
18
|
+
function isNotValidUrl(url) {
|
|
19
|
+
// Empty URLs are considered valid (optional field)
|
|
20
|
+
if (!url) return false;
|
|
21
|
+
|
|
22
|
+
// URL must start with protocol OR www - handles all TLDs including multi-level and query params
|
|
23
|
+
const urlRegex =
|
|
24
|
+
/^(https?:\/\/|www\.)([\da-z\.-]+)\.([a-z\.]{2,})([\/\w \.-]*)*(\?[&\w=.-]*)?(\#[&\w=.-]*)?\/?$/;
|
|
25
|
+
|
|
26
|
+
return !urlRegex.test(url);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = {
|
|
30
|
+
handleOnCustomValidation,
|
|
31
|
+
isNotValidUrl,
|
|
32
|
+
};
|
|
33
|
+
|
package/public/consts.js
CHANGED
|
@@ -74,6 +74,23 @@ const MEMBERS_FIELDS = {
|
|
|
74
74
|
showWebsite: 'showWebsite',
|
|
75
75
|
addressDisplayOption: 'addressDisplayOption',
|
|
76
76
|
};
|
|
77
|
+
|
|
78
|
+
const LIGHTBOX_NAMES = {
|
|
79
|
+
SAVE_ALERT: 'Save Alert',
|
|
80
|
+
LOGIN_ERROR_ALERT: 'loginError',
|
|
81
|
+
DELETE_CONFIRM: 'deleteConfirm',
|
|
82
|
+
SELECT_BANNER_IMAGES: 'Select Banner Images',
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const ABMP_MEMBERS_HOME_URL = 'https://www.abmp.com/members';
|
|
86
|
+
|
|
87
|
+
const FREE_WEBSITE_TEXT_STATES = {
|
|
88
|
+
ENABLED: 'This is the default and will auto-populate with the information entered on this page.',
|
|
89
|
+
DISABLED: 'To deactivate, please opt in via Personal Details.',
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const DEFAULT_BUSINESS_NAME_TEXT = 'Business name not provided';
|
|
93
|
+
|
|
77
94
|
module.exports = {
|
|
78
95
|
REGEX,
|
|
79
96
|
COLLECTIONS,
|
|
@@ -82,4 +99,8 @@ module.exports = {
|
|
|
82
99
|
DROPDOWN_OPTIONS,
|
|
83
100
|
DEBOUNCE_DELAY,
|
|
84
101
|
MEMBERS_FIELDS,
|
|
102
|
+
LIGHTBOX_NAMES,
|
|
103
|
+
ABMP_MEMBERS_HOME_URL,
|
|
104
|
+
FREE_WEBSITE_TEXT_STATES,
|
|
105
|
+
DEFAULT_BUSINESS_NAME_TEXT,
|
|
85
106
|
};
|