@designcrowd/library.brand-page 5.16.43 → 5.16.44-ast-keywords-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/lib/src/{CreatedOnBrandCrowd-de-de-C5cH1T-1.js → CreatedOnBrandCrowd-de-de-DoCFs9H9.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-CYMnCJLK.js → CreatedOnBrandCrowd-en-us-DW4zHk_6.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-lj9In06n.js → CreatedOnBrandCrowd-es-es-CbWWkz6Y.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-d2eXSGxp.js → CreatedOnBrandCrowd-fr-ca-B1kHXNpR.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-d2eXSGxp.js → CreatedOnBrandCrowd-fr-fr-B1kHXNpR.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-B0KA6Yz2.js → CreatedOnBrandCrowd-pt-br-B6hFGeGZ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-B0KA6Yz2.js → CreatedOnBrandCrowd-pt-pt-B6hFGeGZ.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-BVVrQTkJ.js → CreatedOnDcom-de-de-DEQLF64O.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-DFt3dW1K.js → CreatedOnDcom-en-us-DOAV3_A-.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-DwdbeJO4.js → CreatedOnDcom-es-es-BwW9RJIf.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-jlQTAkBO.js → CreatedOnDcom-fr-ca-BhlLIGY2.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-OFLmEho0.js → CreatedOnDcom-fr-fr-Ddk5GqYD.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-BHqtceac.js → CreatedOnDcom-pt-br-BeD0T8KP.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-DIrlJ6nF.js → CreatedOnDcom-pt-pt-D6HZgbKm.js} +1 -1
- package/lib/src/brand-page/__fixtures__/brand-page-sample-data.js +2 -0
- package/lib/src/brand-page/clients/brand-page.client.d.ts +2 -2
- package/lib/src/brand-page/clients/brand-page.client.js +4 -2
- package/lib/src/brand-page/components/contact-form/ContactForm.mixin.d.ts +10 -1
- package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +18 -2
- package/lib/src/brand-page/components/image-gallery/ImageGallery.stories.js +2 -1
- package/lib/src/brand-page/components/images-section/ImagesSection.stories.js +2 -1
- package/lib/src/brand-page/components/mailing-list/MailingList.mixin.d.ts +8 -0
- package/lib/src/brand-page/components/mailing-list/MailingList.mixin.js +22 -7
- package/lib/src/brand-page/components/payment/__fixtures__/request-payment.d.ts +1 -0
- package/lib/src/brand-page/components/payment/__fixtures__/support-me.d.ts +1 -0
- package/lib/src/brand-page/components/profile/Profile.stories.js +2 -1
- package/lib/src/brand-page/composables/recaptcha.composable.d.ts +23 -0
- package/lib/src/brand-page/composables/recaptcha.composable.js +109 -0
- package/lib/src/brand-page/constants/misc.constants.d.ts +3 -0
- package/lib/src/brand-page/constants/misc.constants.js +4 -0
- package/lib/src/brand-page/models/brand-page-context.model.d.ts +2 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/components/preview/Preview.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/quick-link-bar/QuickLinkBar.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/components/seo-settings/UseExistingDomainModal.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +1 -0
- package/lib/src/brand-page-maker/components/upgrade-to-premium-button/UpgradeToPremiumButton.mixin.d.ts +2 -0
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.d.ts +3 -0
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +2 -0
- package/lib/src/bundled-translations-BGBFf8J6.js +169 -0
- package/lib/src/bundled-translations.de-DE-CMMRRwga.js +169 -0
- package/lib/src/bundled-translations.es-ES-XRLPG1g-.js +169 -0
- package/lib/src/{bundled-translations.fr-CA-D4lvna7W.js → bundled-translations.fr-CA-JVxHjJw5.js} +5 -5
- package/lib/src/bundled-translations.fr-FR-B9v33v0w.js +169 -0
- package/lib/src/bundled-translations.pt-BR-B_hexxsq.js +169 -0
- package/lib/src/bundled-translations.pt-PT-B9aY7rS8.js +169 -0
- package/lib/src/bundles/bundled-translations.de-DE.json +1 -1
- package/lib/src/bundles/bundled-translations.es-ES.json +1 -1
- package/lib/src/bundles/bundled-translations.fr-CA.json +1 -1
- package/lib/src/bundles/bundled-translations.fr-FR.json +1 -1
- package/lib/src/bundles/bundled-translations.json +1 -1
- package/lib/src/bundles/bundled-translations.pt-BR.json +1 -1
- package/lib/src/bundles/bundled-translations.pt-PT.json +1 -1
- package/lib/src/clients/fabric-render-client.d.ts +1 -1
- package/lib/src/clients/fabric-render-client.js +6 -2
- package/lib/src/css/library.brand-page-brandCrowd.min.css +16 -16
- package/lib/src/css/library.brand-page-brandPage.min.css +16 -16
- package/lib/src/css/library.brand-page-designCom.min.css +16 -16
- package/lib/src/css/library.brand-page-preview.min.css +16 -16
- package/lib/src/index.d.ts +3 -1
- package/lib/src/index.mjs +127 -123
- package/lib/src/{lib-CnJZ6ibD.js → lib-7X9yBRZB.js} +14512 -14405
- package/lib/src/lib.js +2 -1
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +1 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +0 -1
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +0 -3
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +1 -0
- package/lib/src/shared/content-settings/components/payment-config-field/PaymentConfigField.mixin.d.ts +2 -0
- package/lib/src/shared/content-settings/components/radio-field/RadioField.mixin.js +1 -0
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.d.ts +292 -0
- package/lib/src/shared/logo-settings/components/EditLogoSettings.mixin.js +16 -1
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +2 -0
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -0
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +2 -0
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +2 -0
- package/lib/src/shared/side-bar/components/SideBar.mixin.d.ts +2 -0
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -0
- package/package.json +3 -3
- package/src/brand-page/__fixtures__/brand-page-sample-data.ts +2 -0
- package/src/brand-page/clients/brand-page.client.ts +5 -0
- package/src/brand-page/components/about-section/AboutSection.vue.test.ts +1 -0
- package/src/brand-page/components/contact-form/ContactForm.mixin.ts +23 -0
- package/src/brand-page/components/contact-form/ContactForm.vue +5 -0
- package/src/brand-page/components/image/Image.test.ts +1 -0
- package/src/brand-page/components/image-gallery/ImageGallery.stories.ts +2 -1
- package/src/brand-page/components/image-gallery/ImageGallery.test.ts +1 -0
- package/src/brand-page/components/images-section/ImagesSection.stories.ts +2 -1
- package/src/brand-page/components/mailing-list/MailingList.mixin.ts +32 -12
- package/src/brand-page/components/profile/Profile.stories.ts +2 -1
- package/src/brand-page/components/social-links/SocialLinks.vue.test.ts +1 -0
- package/src/brand-page/composables/recaptcha.composable.ts +159 -0
- package/src/brand-page/constants/misc.constants.ts +5 -0
- package/src/brand-page/models/brand-page-context.model.ts +2 -0
- package/src/brand-page-maker/components/preview/Preview.mixin.ts +1 -0
- package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +1 -0
- package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +3 -0
- package/src/bundles/bundled-translations.de-DE.json +1 -1
- package/src/bundles/bundled-translations.es-ES.json +1 -1
- package/src/bundles/bundled-translations.fr-CA.json +1 -1
- package/src/bundles/bundled-translations.fr-FR.json +1 -1
- package/src/bundles/bundled-translations.json +1 -1
- package/src/bundles/bundled-translations.pt-BR.json +1 -1
- package/src/bundles/bundled-translations.pt-PT.json +1 -1
- package/src/clients/fabric-render-client.ts +8 -1
- package/src/lib.ts +5 -0
- package/src/shared/common/i18n/common.de-DE.json +66 -56
- package/src/shared/common/i18n/common.es-ES.json +66 -56
- package/src/shared/common/i18n/common.fr-CA.json +66 -56
- package/src/shared/common/i18n/common.fr-FR.json +66 -56
- package/src/shared/common/i18n/common.json +1 -1
- package/src/shared/common/i18n/common.pt-BR.json +66 -56
- package/src/shared/common/i18n/common.pt-PT.json +66 -56
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +1 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +0 -3
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +1 -0
- package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +1 -1
- package/src/shared/content-settings/components/radio-field/RadioField.mixin.ts +1 -0
- package/src/shared/logo-settings/components/EditLogoSettings.mixin.ts +22 -1
- package/src/shared/logo-settings/components/EditLogoSettings.vue +1 -0
- package/src/shared/logo-settings/components/LogoTemplateSearch.vue +10 -13
- package/lib/src/bundled-translations-m0LLDrVj.js +0 -169
- package/lib/src/bundled-translations.de-DE-1O8nqesB.js +0 -169
- package/lib/src/bundled-translations.es-ES-DpzOLKxV.js +0 -169
- package/lib/src/bundled-translations.fr-FR-rn7Qlrcy.js +0 -169
- package/lib/src/bundled-translations.pt-BR-Cuinfm5y.js +0 -169
- package/lib/src/bundled-translations.pt-PT-BWcxkaQn.js +0 -169
|
@@ -97,6 +97,7 @@ export const context = {
|
|
|
97
97
|
mediaSizes: MEDIA_SIZES.sizeThumb,
|
|
98
98
|
},
|
|
99
99
|
isCapturingPreview: false,
|
|
100
|
+
recaptchaSiteKey: undefined,
|
|
100
101
|
};
|
|
101
102
|
export const BScontext = {
|
|
102
103
|
isTemplate: false,
|
|
@@ -119,6 +120,7 @@ export const BScontext = {
|
|
|
119
120
|
mediaSizes: MEDIA_SIZES.sizeThumb,
|
|
120
121
|
},
|
|
121
122
|
isCapturingPreview: false,
|
|
123
|
+
recaptchaSiteKey: undefined,
|
|
122
124
|
};
|
|
123
125
|
export const logoTheme = {
|
|
124
126
|
logoTextColor: {
|
|
@@ -16,8 +16,8 @@ export interface CartForShopRequest {
|
|
|
16
16
|
unitPrice: number;
|
|
17
17
|
}
|
|
18
18
|
declare const _default: {
|
|
19
|
-
addMailSubscriber: (brandPageToken: string, email: string, name?: string | undefined) => Promise<FormResult>;
|
|
20
|
-
submitContactForm: (brandPageToken: string, contentBlockId: string, values: ContactFormField[]) => Promise<FormResult>;
|
|
19
|
+
addMailSubscriber: (brandPageToken: string, email: string, name?: string | undefined, recaptchaToken?: string | undefined) => Promise<FormResult>;
|
|
20
|
+
submitContactForm: (brandPageToken: string, contentBlockId: string, values: ContactFormField[], recaptchaToken?: string | undefined) => Promise<FormResult>;
|
|
21
21
|
getPaymentConfigStatusByPaymentConfigId: (paymentConfigId: string) => Promise<string>;
|
|
22
22
|
getStoreProductsByBrandPageToken: (brandPageToken: string) => Promise<string>;
|
|
23
23
|
createBrandPageCart: (request: {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import * as constants from '../constants';
|
|
3
3
|
import * as csrfUtil from '../utils/csrf.util';
|
|
4
|
-
const addMailSubscriber = async (brandPageToken, email, name) => {
|
|
4
|
+
const addMailSubscriber = async (brandPageToken, email, name, recaptchaToken) => {
|
|
5
5
|
try {
|
|
6
6
|
const csrfToken = csrfUtil.getCsrfTokenFromMetaHeader();
|
|
7
7
|
await axios.post(`/api/mailing-lists/${brandPageToken}`, {
|
|
8
8
|
email,
|
|
9
9
|
name,
|
|
10
|
+
recaptchaToken,
|
|
10
11
|
}, {
|
|
11
12
|
headers: {
|
|
12
13
|
'Content-Type': 'application/json',
|
|
@@ -28,12 +29,13 @@ const addMailSubscriber = async (brandPageToken, email, name) => {
|
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
31
|
};
|
|
31
|
-
const submitContactForm = async (brandPageToken, contentBlockId, values) => {
|
|
32
|
+
const submitContactForm = async (brandPageToken, contentBlockId, values, recaptchaToken) => {
|
|
32
33
|
try {
|
|
33
34
|
const csrfToken = csrfUtil.getCsrfTokenFromMetaHeader();
|
|
34
35
|
const formBody = {
|
|
35
36
|
contentBlockId,
|
|
36
37
|
fields: values,
|
|
38
|
+
recaptchaToken,
|
|
37
39
|
};
|
|
38
40
|
await axios.post(`/api/contact/${brandPageToken}`, formBody, {
|
|
39
41
|
headers: {
|
|
@@ -28,7 +28,16 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
28
28
|
required: false;
|
|
29
29
|
default: undefined;
|
|
30
30
|
};
|
|
31
|
-
}>, {
|
|
31
|
+
}>, {
|
|
32
|
+
recaptcha: {
|
|
33
|
+
isReady: import("vue").ComputedRef<boolean>;
|
|
34
|
+
initialise: (config: import("../../composables/recaptcha.composable").ReCaptchaConfig) => Promise<void>;
|
|
35
|
+
executeAsync: (action: string) => Promise<string | undefined>;
|
|
36
|
+
error: import("vue").ComputedRef<string | undefined>;
|
|
37
|
+
isLoading: import("vue").ComputedRef<boolean>;
|
|
38
|
+
siteKey: import("vue").ComputedRef<string>;
|
|
39
|
+
};
|
|
40
|
+
}, {
|
|
32
41
|
values: FieldValue[];
|
|
33
42
|
hasSubmitted: boolean;
|
|
34
43
|
isSubmitting: boolean;
|
|
@@ -3,8 +3,9 @@ import { FORM_FIELD_TYPES } from '../../models';
|
|
|
3
3
|
import { getEmailValidationError, getMessageValidationError, getNameValidationError, getPhoneValidationError, } from '../../utils';
|
|
4
4
|
import brandPageClient from '../../clients/brand-page.client';
|
|
5
5
|
import { isEmail } from '../../../utils/validator.util';
|
|
6
|
-
import { ALIGN_CARD_CENTER, ALIGN_CARD_CENTER_IMAGE, ALIGN_CENTERED, ALIGN_LEFT_FULL_IMAGE, ALIGN_RIGHT_FULL_IMAGE, DISPLAY_STYLE_COLLAPSED, TEXT_ONLY, } from '../../constants';
|
|
6
|
+
import { ALIGN_CARD_CENTER, ALIGN_CARD_CENTER_IMAGE, ALIGN_CENTERED, ALIGN_LEFT_FULL_IMAGE, ALIGN_RIGHT_FULL_IMAGE, DISPLAY_STYLE_COLLAPSED, RECAPTCHA_ACTION_CONTACT_FORM, TEXT_ONLY, } from '../../constants';
|
|
7
7
|
import { getRenderText } from '../../utils';
|
|
8
|
+
import { useReCaptcha } from '../../composables/recaptcha.composable';
|
|
8
9
|
export default defineComponent({
|
|
9
10
|
props: {
|
|
10
11
|
context: {
|
|
@@ -29,6 +30,12 @@ export default defineComponent({
|
|
|
29
30
|
default: undefined,
|
|
30
31
|
},
|
|
31
32
|
},
|
|
33
|
+
setup() {
|
|
34
|
+
const recaptcha = useReCaptcha();
|
|
35
|
+
return {
|
|
36
|
+
recaptcha,
|
|
37
|
+
};
|
|
38
|
+
},
|
|
32
39
|
data: () => ({
|
|
33
40
|
values: [],
|
|
34
41
|
hasSubmitted: false,
|
|
@@ -136,6 +143,11 @@ export default defineComponent({
|
|
|
136
143
|
field: f,
|
|
137
144
|
}));
|
|
138
145
|
},
|
|
146
|
+
mounted() {
|
|
147
|
+
if (this.context?.recaptchaSiteKey && !this.isPreview && this.recaptcha) {
|
|
148
|
+
this.recaptcha.initialise({ siteKey: this.context.recaptchaSiteKey });
|
|
149
|
+
}
|
|
150
|
+
},
|
|
139
151
|
methods: {
|
|
140
152
|
async submitContactForm() {
|
|
141
153
|
this.validateFormValues();
|
|
@@ -152,12 +164,16 @@ export default defineComponent({
|
|
|
152
164
|
let result;
|
|
153
165
|
this.isSubmitting = true;
|
|
154
166
|
try {
|
|
167
|
+
let recaptchaToken;
|
|
168
|
+
if (this.context?.recaptchaSiteKey && this.recaptcha?.isReady?.value) {
|
|
169
|
+
recaptchaToken = await this.recaptcha.executeAsync(RECAPTCHA_ACTION_CONTACT_FORM);
|
|
170
|
+
}
|
|
155
171
|
result = await brandPageClient.submitContactForm(this.context.brandPageToken, this.viewModel.id, this.values.map((v) => ({
|
|
156
172
|
id: v.field.id,
|
|
157
173
|
name: v.field.name,
|
|
158
174
|
type: v.field.type,
|
|
159
175
|
value: v.value,
|
|
160
|
-
})));
|
|
176
|
+
})), recaptchaToken);
|
|
161
177
|
}
|
|
162
178
|
finally {
|
|
163
179
|
this.isSubmitting = false;
|
|
@@ -21,6 +21,14 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
21
21
|
};
|
|
22
22
|
}>, {
|
|
23
23
|
mailingListTr: (key: any, valuesToInterpolate?: {}) => any;
|
|
24
|
+
recaptcha: {
|
|
25
|
+
isReady: import("vue").ComputedRef<boolean>;
|
|
26
|
+
initialise: (config: import("../../composables/recaptcha.composable").ReCaptchaConfig) => Promise<void>;
|
|
27
|
+
executeAsync: (action: string) => Promise<string | undefined>;
|
|
28
|
+
error: import("vue").ComputedRef<string | undefined>;
|
|
29
|
+
isLoading: import("vue").ComputedRef<boolean>;
|
|
30
|
+
siteKey: import("vue").ComputedRef<string>;
|
|
31
|
+
};
|
|
24
32
|
}, {
|
|
25
33
|
email: string;
|
|
26
34
|
emailError: string | undefined;
|
|
@@ -2,6 +2,8 @@ import { defineComponent } from 'vue';
|
|
|
2
2
|
import brandPageClient from '../../clients/brand-page.client';
|
|
3
3
|
import { getEmailValidationError } from '../../utils';
|
|
4
4
|
import { contentSettingsTr, mailingListTr, } from '../../../composables/useTranslate';
|
|
5
|
+
import { useReCaptcha } from '../../composables/recaptcha.composable';
|
|
6
|
+
import { RECAPTCHA_ACTION_MAILING_LIST } from '../../constants';
|
|
5
7
|
const MAX_NAME_LENGTH = 200;
|
|
6
8
|
export default defineComponent({
|
|
7
9
|
props: {
|
|
@@ -24,8 +26,10 @@ export default defineComponent({
|
|
|
24
26
|
},
|
|
25
27
|
},
|
|
26
28
|
setup() {
|
|
29
|
+
const recaptcha = useReCaptcha();
|
|
27
30
|
return {
|
|
28
31
|
mailingListTr,
|
|
32
|
+
recaptcha,
|
|
29
33
|
};
|
|
30
34
|
},
|
|
31
35
|
data() {
|
|
@@ -42,6 +46,9 @@ export default defineComponent({
|
|
|
42
46
|
},
|
|
43
47
|
mounted() {
|
|
44
48
|
this.show = true;
|
|
49
|
+
if (this.context?.recaptchaSiteKey && !this.isPreview && this.recaptcha) {
|
|
50
|
+
this.recaptcha.initialise({ siteKey: this.context.recaptchaSiteKey });
|
|
51
|
+
}
|
|
45
52
|
},
|
|
46
53
|
computed: {
|
|
47
54
|
hasNameError() {
|
|
@@ -107,14 +114,22 @@ export default defineComponent({
|
|
|
107
114
|
return;
|
|
108
115
|
}
|
|
109
116
|
this.isSubmitting = true;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
try {
|
|
118
|
+
let recaptchaToken;
|
|
119
|
+
if (this.context?.recaptchaSiteKey && this.recaptcha?.isReady?.value) {
|
|
120
|
+
recaptchaToken = await this.recaptcha.executeAsync(RECAPTCHA_ACTION_MAILING_LIST);
|
|
121
|
+
}
|
|
122
|
+
const result = await brandPageClient.addMailSubscriber(this.brandPageToken, this.email, this.name === '' ? undefined : this.name, recaptchaToken);
|
|
123
|
+
if (!result.success) {
|
|
124
|
+
this.submitError = result.errMessage;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
this.submitError = undefined;
|
|
128
|
+
this.hasSubscribed = result.success;
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
this.isSubmitting = false;
|
|
115
132
|
}
|
|
116
|
-
this.submitError = undefined;
|
|
117
|
-
this.hasSubscribed = result.success;
|
|
118
133
|
},
|
|
119
134
|
validateName() {
|
|
120
135
|
if (this.name.trim() === '') {
|
|
@@ -12,6 +12,7 @@ export declare const context: {
|
|
|
12
12
|
pages?: import("../../../view-models").PageViewModel[] | undefined;
|
|
13
13
|
currentPageSlug?: string | undefined;
|
|
14
14
|
runtimeEnvironment: string;
|
|
15
|
+
recaptchaSiteKey: string | undefined;
|
|
15
16
|
pageTitle: string;
|
|
16
17
|
customDomain: string | undefined;
|
|
17
18
|
brandPageType: "default" | "brandSite" | "brandContact";
|
|
@@ -12,6 +12,7 @@ export declare const context: {
|
|
|
12
12
|
pages?: import("../../../view-models").PageViewModel[] | undefined;
|
|
13
13
|
currentPageSlug?: string | undefined;
|
|
14
14
|
runtimeEnvironment: string;
|
|
15
|
+
recaptchaSiteKey: string | undefined;
|
|
15
16
|
pageTitle: string;
|
|
16
17
|
customDomain: string | undefined;
|
|
17
18
|
brandPageType: "default" | "brandSite" | "brandContact";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
grecaptcha: {
|
|
4
|
+
enterprise: {
|
|
5
|
+
ready: (callback: () => void) => void;
|
|
6
|
+
execute: (siteKey: string, options: {
|
|
7
|
+
action: string;
|
|
8
|
+
}) => Promise<string>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export interface ReCaptchaConfig {
|
|
14
|
+
siteKey: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const useReCaptcha: () => {
|
|
17
|
+
isReady: import("vue").ComputedRef<boolean>;
|
|
18
|
+
initialise: (config: ReCaptchaConfig) => Promise<void>;
|
|
19
|
+
executeAsync: (action: string) => Promise<string | undefined>;
|
|
20
|
+
error: import("vue").ComputedRef<string | undefined>;
|
|
21
|
+
isLoading: import("vue").ComputedRef<boolean>;
|
|
22
|
+
siteKey: import("vue").ComputedRef<string>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { reactive, computed } from 'vue';
|
|
2
|
+
const store = reactive({
|
|
3
|
+
isLoaded: false,
|
|
4
|
+
isLoading: false,
|
|
5
|
+
siteKey: '',
|
|
6
|
+
error: undefined,
|
|
7
|
+
});
|
|
8
|
+
const SCRIPT_ID = 'recaptcha-enterprise-script';
|
|
9
|
+
const isBrowser = () => {
|
|
10
|
+
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
11
|
+
};
|
|
12
|
+
const loadScript = (siteKey) => {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
if (!isBrowser()) {
|
|
15
|
+
reject(new Error('reCAPTCHA can only be loaded in browser environment'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
// Check if script already exists
|
|
19
|
+
const existingScript = document.getElementById(SCRIPT_ID);
|
|
20
|
+
if (existingScript) {
|
|
21
|
+
resolve();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const script = document.createElement('script');
|
|
25
|
+
script.id = SCRIPT_ID;
|
|
26
|
+
script.src = `https://www.google.com/recaptcha/enterprise.js?render=${siteKey}`;
|
|
27
|
+
script.async = true;
|
|
28
|
+
script.defer = true;
|
|
29
|
+
script.onload = () => {
|
|
30
|
+
resolve();
|
|
31
|
+
};
|
|
32
|
+
script.onerror = () => {
|
|
33
|
+
reject(new Error('Failed to load reCAPTCHA script'));
|
|
34
|
+
};
|
|
35
|
+
document.head.appendChild(script);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export const useReCaptcha = () => {
|
|
39
|
+
const isReady = computed(() => store.isLoaded && !store.isLoading);
|
|
40
|
+
/**
|
|
41
|
+
* Initialize reCAPTCHA with the site key.
|
|
42
|
+
* Should be called once when the component mounts.
|
|
43
|
+
*/
|
|
44
|
+
const initialise = async (config) => {
|
|
45
|
+
if (!isBrowser()) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (store.isLoaded || store.isLoading) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!config.siteKey) {
|
|
52
|
+
store.error = 'reCAPTCHA site key is required';
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
store.siteKey = config.siteKey;
|
|
56
|
+
store.isLoading = true;
|
|
57
|
+
store.error = undefined;
|
|
58
|
+
try {
|
|
59
|
+
await loadScript(config.siteKey);
|
|
60
|
+
store.isLoaded = true;
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
store.error =
|
|
64
|
+
err instanceof Error ? err.message : 'Failed to load reCAPTCHA';
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
store.isLoading = false;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Execute reCAPTCHA and get a token for the specified action.
|
|
72
|
+
* @param action - The action name for reCAPTCHA (e.g., 'CONTACT_FORM_SUBMIT')
|
|
73
|
+
* @returns Promise<string | undefined> - The reCAPTCHA token or undefined if failed
|
|
74
|
+
*/
|
|
75
|
+
const executeAsync = async (action) => {
|
|
76
|
+
if (!isBrowser()) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
if (!store.isLoaded || !store.siteKey) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
return await new Promise((resolve, reject) => {
|
|
84
|
+
window.grecaptcha.enterprise.ready(async () => {
|
|
85
|
+
try {
|
|
86
|
+
const token = await window.grecaptcha.enterprise.execute(store.siteKey, { action });
|
|
87
|
+
resolve(token);
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
reject(err);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
store.error =
|
|
97
|
+
err instanceof Error ? err.message : 'Failed to execute reCAPTCHA';
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
isReady,
|
|
103
|
+
initialise,
|
|
104
|
+
executeAsync,
|
|
105
|
+
error: computed(() => store.error),
|
|
106
|
+
isLoading: computed(() => store.isLoading),
|
|
107
|
+
siteKey: computed(() => store.siteKey),
|
|
108
|
+
};
|
|
109
|
+
};
|
|
@@ -51,6 +51,9 @@ export declare const STATUS_CODE_CONFLICT = 409;
|
|
|
51
51
|
export declare const MESSAGE_ADD_MAIL_SUBSCRIBER_CONFLICT: () => any;
|
|
52
52
|
export declare const MESSAGE_ADD_MAIL_SUBSCRIBER_FAILED: () => any;
|
|
53
53
|
export declare const MESSAGE_CONTACT_MESSAGE_FAILED: () => any;
|
|
54
|
+
export declare const RECAPTCHA_ACTION_MAILING_LIST = "MAILING_LIST_SUBSCRIBE";
|
|
55
|
+
export declare const RECAPTCHA_ACTION_CONTACT_FORM = "CONTACT_FORM_SUBMIT";
|
|
56
|
+
export declare const RECAPTCHA_MIN_SCORE = 0.5;
|
|
54
57
|
export declare const stripeDefaultStyle: {
|
|
55
58
|
readonly base: {
|
|
56
59
|
readonly color: "#7d8284";
|
|
@@ -61,6 +61,10 @@ export const STATUS_CODE_CONFLICT = 409;
|
|
|
61
61
|
export const MESSAGE_ADD_MAIL_SUBSCRIBER_CONFLICT = () => errorTr('alreadySubscribedError');
|
|
62
62
|
export const MESSAGE_ADD_MAIL_SUBSCRIBER_FAILED = () => errorTr('mailingListError');
|
|
63
63
|
export const MESSAGE_CONTACT_MESSAGE_FAILED = () => errorTr('contactMessageError');
|
|
64
|
+
// reCAPTCHA constants
|
|
65
|
+
export const RECAPTCHA_ACTION_MAILING_LIST = 'MAILING_LIST_SUBSCRIBE';
|
|
66
|
+
export const RECAPTCHA_ACTION_CONTACT_FORM = 'CONTACT_FORM_SUBMIT';
|
|
67
|
+
export const RECAPTCHA_MIN_SCORE = 0.5;
|
|
64
68
|
export const stripeDefaultStyle = {
|
|
65
69
|
base: {
|
|
66
70
|
color: '#7d8284',
|
|
@@ -59,6 +59,8 @@ export interface BrandPageContext {
|
|
|
59
59
|
currentPageSlug?: string;
|
|
60
60
|
runtimeEnvironment: string;
|
|
61
61
|
stripePublishableKey: string | undefined;
|
|
62
|
+
/** reCAPTCHA Enterprise site key for spam protection */
|
|
63
|
+
recaptchaSiteKey: string | undefined;
|
|
62
64
|
pageTitle: string;
|
|
63
65
|
customDomain: string | undefined;
|
|
64
66
|
brandPageType: BrandPageType;
|
|
@@ -273,6 +273,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
273
273
|
isSubsequentPublish: boolean;
|
|
274
274
|
isContextualUpgradeModalVisible: boolean;
|
|
275
275
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
276
|
+
templateSearchTerm: string | undefined;
|
|
276
277
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
277
278
|
isUserDraft: (state: {
|
|
278
279
|
availableTaxes: any[];
|
|
@@ -334,6 +335,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
334
335
|
isSubsequentPublish: boolean;
|
|
335
336
|
isContextualUpgradeModalVisible: boolean;
|
|
336
337
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
338
|
+
templateSearchTerm: string | undefined;
|
|
337
339
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
338
340
|
}, {
|
|
339
341
|
initialise(payload: import("../../stores/brandpage-container").InitialisePayload): void;
|
package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts
CHANGED
|
@@ -705,6 +705,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
705
705
|
isSubsequentPublish: boolean;
|
|
706
706
|
isContextualUpgradeModalVisible: boolean;
|
|
707
707
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
708
|
+
templateSearchTerm: string | undefined;
|
|
708
709
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
709
710
|
isUserDraft: (state: {
|
|
710
711
|
availableTaxes: any[];
|
|
@@ -766,6 +767,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
766
767
|
isSubsequentPublish: boolean;
|
|
767
768
|
isContextualUpgradeModalVisible: boolean;
|
|
768
769
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
770
|
+
templateSearchTerm: string | undefined;
|
|
769
771
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
770
772
|
}, {
|
|
771
773
|
initialise(payload: import("../../stores/brandpage-container").InitialisePayload): void;
|
|
@@ -71,6 +71,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
71
71
|
isSubsequentPublish: boolean;
|
|
72
72
|
isContextualUpgradeModalVisible: boolean;
|
|
73
73
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
74
|
+
templateSearchTerm: string | undefined;
|
|
74
75
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
75
76
|
isUserDraft: (state: {
|
|
76
77
|
availableTaxes: any[];
|
|
@@ -132,6 +133,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
132
133
|
isSubsequentPublish: boolean;
|
|
133
134
|
isContextualUpgradeModalVisible: boolean;
|
|
134
135
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
136
|
+
templateSearchTerm: string | undefined;
|
|
135
137
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
136
138
|
}, {
|
|
137
139
|
initialise(payload: import("../../stores/brandpage-container").InitialisePayload): void;
|
|
@@ -87,6 +87,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
87
87
|
isSubsequentPublish: boolean;
|
|
88
88
|
isContextualUpgradeModalVisible: boolean;
|
|
89
89
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
90
|
+
templateSearchTerm: string | undefined;
|
|
90
91
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
91
92
|
isUserDraft: (state: {
|
|
92
93
|
availableTaxes: any[];
|
|
@@ -148,6 +149,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
148
149
|
isSubsequentPublish: boolean;
|
|
149
150
|
isContextualUpgradeModalVisible: boolean;
|
|
150
151
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
152
|
+
templateSearchTerm: string | undefined;
|
|
151
153
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
152
154
|
}, {
|
|
153
155
|
initialise(payload: import("../../stores/brandpage-container").InitialisePayload): void;
|
|
@@ -92,6 +92,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
92
92
|
isSubsequentPublish: boolean;
|
|
93
93
|
isContextualUpgradeModalVisible: boolean;
|
|
94
94
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
95
|
+
templateSearchTerm: string | undefined;
|
|
95
96
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
96
97
|
isUserDraft: (state: {
|
|
97
98
|
availableTaxes: any[];
|
|
@@ -153,6 +154,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
153
154
|
isSubsequentPublish: boolean;
|
|
154
155
|
isContextualUpgradeModalVisible: boolean;
|
|
155
156
|
contextualUpgradeType: string | number | symbol | undefined;
|
|
157
|
+
templateSearchTerm: string | undefined;
|
|
156
158
|
} & import("pinia").PiniaCustomStateProperties<import("../../stores").BrandPageContainerState>) => boolean;
|
|
157
159
|
}, {
|
|
158
160
|
initialise(payload: import("../../stores/brandpage-container").InitialisePayload): void;
|