@designcrowd/library.brand-page 5.16.17-pre-temp-2 → 5.16.18-ast-save-bc
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-CFZJ9B0_.js → CreatedOnBrandCrowd-de-de-DyUz0u__.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-Co2tanrg.js → CreatedOnBrandCrowd-en-us-CjKMC3AM.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-DWcr6V-z.js → CreatedOnBrandCrowd-es-es-BVDz6Ixy.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-De72i4oQ.js → CreatedOnBrandCrowd-fr-ca-BcxKWT6E.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-De72i4oQ.js → CreatedOnBrandCrowd-fr-fr-BcxKWT6E.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-CcznKAcC.js → CreatedOnBrandCrowd-pt-br-Co7QQ80l.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-CcznKAcC.js → CreatedOnBrandCrowd-pt-pt-Co7QQ80l.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-xh1FG9UT.js → CreatedOnDcom-de-de-CEDmsGBR.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-DwRJ-NGl.js → CreatedOnDcom-en-us-BoGpFhlg.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-qa4GXYmC.js → CreatedOnDcom-es-es-HABf8vVH.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-Ck443ItA.js → CreatedOnDcom-fr-ca-BHsSmAb4.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-DysZVU4Z.js → CreatedOnDcom-fr-fr-DwQ4Flp7.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-6zBZ72NO.js → CreatedOnDcom-pt-br-1SnSRC6J.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-Dtvbafy6.js → CreatedOnDcom-pt-pt-D91oqYtM.js} +1 -1
- package/lib/src/brand-page/components/page/Page.mixin.d.ts +1 -0
- package/lib/src/brand-page/components/page/Page.mixin.js +16 -0
- package/lib/src/brand-page/components/page-footer/PageFooter.mixin.d.ts +12 -1
- package/lib/src/brand-page/components/page-footer/PageFooter.mixin.js +5 -0
- package/lib/src/brand-page/components/payment/__fixtures__/request-payment.d.ts +2 -0
- package/lib/src/brand-page/components/payment/__fixtures__/support-me.d.ts +2 -0
- package/lib/src/brand-page/models/brand-page-context.model.d.ts +3 -0
- package/lib/src/brand-page/utils/vcard.util.d.ts +13 -0
- package/lib/src/brand-page/utils/vcard.util.js +176 -0
- package/lib/src/brand-page-maker/assessors/banner-section-description-visibility.assessor.js +1 -1
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +1 -0
- package/lib/src/brand-page-maker/components/preview/Preview.mixin.js +1 -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 +9 -0
- package/lib/src/brand-page-maker/composables/useEventTracker.d.ts +2 -0
- package/lib/src/brand-page-maker/composables/useEventTracker.js +2 -0
- package/lib/src/bundled-translations-Dp4KzW9M.js +165 -0
- package/lib/src/bundled-translations.de-DE-CMNy5LEQ.js +165 -0
- package/lib/src/bundled-translations.es-ES-B20ONBTs.js +165 -0
- package/lib/src/bundled-translations.fr-CA-DwBf1MZ8.js +165 -0
- package/lib/src/bundled-translations.fr-FR-3GhDgrC4.js +165 -0
- package/lib/src/bundled-translations.pt-BR-DuzEDMF5.js +165 -0
- package/lib/src/bundled-translations.pt-PT-CtT4FOlX.js +165 -0
- package/lib/src/bundles/bundled-translations.de-DE.json +7 -1
- package/lib/src/bundles/bundled-translations.es-ES.json +7 -1
- package/lib/src/bundles/bundled-translations.fr-CA.json +7 -1
- package/lib/src/bundles/bundled-translations.fr-FR.json +7 -1
- package/lib/src/bundles/bundled-translations.json +7 -1
- package/lib/src/bundles/bundled-translations.pt-BR.json +7 -1
- package/lib/src/bundles/bundled-translations.pt-PT.json +7 -1
- package/lib/src/clients/fabric-render-client.d.ts +0 -1
- package/lib/src/composables/useTranslate.d.ts +2 -1
- package/lib/src/composables/useTranslate.js +2 -1
- package/lib/src/css/library.brand-page-brandCrowd.min.css +185 -64
- package/lib/src/css/library.brand-page-brandPage.min.css +187 -64
- package/lib/src/css/library.brand-page-designCom.min.css +185 -64
- package/lib/src/css/library.brand-page-preview.min.css +185 -64
- package/lib/src/index.d.ts +1 -1
- package/lib/src/index.mjs +65 -66
- package/lib/src/{lib-DTMYf8OY.js → lib-CqQoDVDz.js} +21912 -21591
- package/lib/src/lib.js +1 -1
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +2 -0
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +2 -0
- package/lib/src/shared/logo-settings/store/editable-logo-store.js +0 -1
- package/package.json +1 -1
- package/src/brand-page/components/banner-section/BannerSection.vue +5 -1
- package/src/brand-page/components/brand-page-footer/i18n/brand-page-footer.de-DE.json +5 -5
- package/src/brand-page/components/brand-page-footer/i18n/brand-page-footer.es-ES.json +5 -5
- package/src/brand-page/components/brand-page-footer/i18n/brand-page-footer.fr-CA.json +5 -5
- package/src/brand-page/components/brand-page-footer/i18n/brand-page-footer.fr-FR.json +5 -5
- package/src/brand-page/components/brand-page-footer/i18n/brand-page-footer.pt-BR.json +5 -5
- package/src/brand-page/components/brand-page-footer/i18n/brand-page-footer.pt-PT.json +5 -5
- package/src/brand-page/components/button/Button.vue +64 -54
- package/src/brand-page/components/page/Page.mixin.ts +20 -0
- package/src/brand-page/components/page/Page.vue +10 -1
- package/src/brand-page/components/page-footer/PageFooter.mixin.ts +9 -1
- package/src/brand-page/components/save-contact/SaveContactWidget.vue +212 -0
- package/src/brand-page/components/save-contact/i18n/save-contact.de-DE.json +8 -0
- package/src/brand-page/components/save-contact/i18n/save-contact.es-ES.json +8 -0
- package/src/brand-page/components/save-contact/i18n/save-contact.fr-CA.json +8 -0
- package/src/brand-page/components/save-contact/i18n/save-contact.fr-FR.json +8 -0
- package/src/brand-page/components/save-contact/i18n/save-contact.json +8 -0
- package/src/brand-page/components/save-contact/i18n/save-contact.pt-BR.json +8 -0
- package/src/brand-page/components/save-contact/i18n/save-contact.pt-PT.json +8 -0
- package/src/brand-page/components/save-contact/popup-card/PopupCard.vue +156 -0
- package/src/brand-page/components/shop/ProductDetailModal.vue +1 -1
- package/src/brand-page/models/brand-page-context.model.ts +3 -0
- package/src/brand-page/utils/vcard.util.ts +252 -0
- package/src/brand-page-maker/assessors/banner-section-description-visibility.assessor.ts +1 -1
- package/src/brand-page-maker/components/color-palette/BpColorPalette.vue +3 -1
- package/src/brand-page-maker/components/preview/Preview.mixin.ts +1 -0
- package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +12 -0
- package/src/brand-page-maker/composables/useEventTracker.ts +2 -0
- package/src/bundles/bundled-translations.de-DE.json +7 -1
- package/src/bundles/bundled-translations.es-ES.json +7 -1
- package/src/bundles/bundled-translations.fr-CA.json +7 -1
- package/src/bundles/bundled-translations.fr-FR.json +7 -1
- package/src/bundles/bundled-translations.json +7 -1
- package/src/bundles/bundled-translations.pt-BR.json +7 -1
- package/src/bundles/bundled-translations.pt-PT.json +7 -1
- package/src/clients/fabric-render-client.ts +0 -1
- package/src/composables/useTranslate.ts +3 -0
- package/src/lib.ts +0 -1
- package/src/shared/content-settings/components/content-settings/i18n/content-settings.de-DE.json +1 -1
- package/src/shared/content-settings/components/content-settings/i18n/content-settings.es-ES.json +1 -1
- package/src/shared/content-settings/components/content-settings/i18n/content-settings.fr-CA.json +1 -1
- package/src/shared/content-settings/components/content-settings/i18n/content-settings.fr-FR.json +1 -1
- package/src/shared/content-settings/components/content-settings/i18n/content-settings.json +1 -1
- package/src/shared/content-settings/components/content-settings/i18n/content-settings.pt-BR.json +1 -1
- package/src/shared/content-settings/components/content-settings/i18n/content-settings.pt-PT.json +1 -1
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +2 -0
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +2 -0
- package/src/shared/logo-settings/store/editable-logo-store.ts +0 -1
- package/src/shared/shape-library/i18n/shape-library.de-DE.json +3 -3
- package/src/shared/shape-library/i18n/shape-library.es-ES.json +3 -3
- package/src/shared/shape-library/i18n/shape-library.fr-CA.json +3 -3
- package/src/shared/shape-library/i18n/shape-library.fr-FR.json +3 -3
- package/src/shared/shape-library/i18n/shape-library.pt-BR.json +3 -3
- package/src/shared/shape-library/i18n/shape-library.pt-PT.json +3 -3
- package/lib/src/bundled-translations-BYa_U-US.js +0 -163
- package/lib/src/bundled-translations.de-DE-DypSwCKV.js +0 -163
- package/lib/src/bundled-translations.es-ES-IiXZIQwt.js +0 -163
- package/lib/src/bundled-translations.fr-CA-B4yILHO8.js +0 -163
- package/lib/src/bundled-translations.fr-FR-C6C6FR8Q.js +0 -163
- package/lib/src/bundled-translations.pt-BR-C6Ym9BZY.js +0 -163
- package/lib/src/bundled-translations.pt-PT-CYohhAyJ.js +0 -163
|
@@ -73,6 +73,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
73
73
|
bpShowTopNavigationMobile(): boolean;
|
|
74
74
|
bpShowTopNavigationDesktop(): boolean;
|
|
75
75
|
slug(): string;
|
|
76
|
+
shouldShowSaveContactWidget(): boolean;
|
|
76
77
|
}, {
|
|
77
78
|
openSideMenu(): void;
|
|
78
79
|
onLogoClick(tabName: string): void;
|
|
@@ -2,6 +2,7 @@ import { defineComponent } from 'vue';
|
|
|
2
2
|
import { DEFAULT_FONT_FAMILY_KEY, FALLBACK_FONT_FAMILIES, FONT_FAMILY_CONFIGS, } from '../../constants';
|
|
3
3
|
import { getSlugFromContext } from '../../utils';
|
|
4
4
|
import { BRAND_PAGE_TYPES } from '../../models';
|
|
5
|
+
import { hasProfileContent as checkHasProfileContent } from '../../utils/vcard.util';
|
|
5
6
|
export default defineComponent({
|
|
6
7
|
props: {
|
|
7
8
|
context: {
|
|
@@ -263,6 +264,21 @@ export default defineComponent({
|
|
|
263
264
|
slug() {
|
|
264
265
|
return getSlugFromContext(this.context);
|
|
265
266
|
},
|
|
267
|
+
shouldShowSaveContactWidget() {
|
|
268
|
+
try {
|
|
269
|
+
if (this.context.isPreview ||
|
|
270
|
+
this.context.options?.showOnGeneratedPreviews === false ||
|
|
271
|
+
!this.context.isBrandContact) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
const brandPageData = { pages: this.context?.pages || [] };
|
|
275
|
+
return checkHasProfileContent(brandPageData);
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
console.error('Error checking profile content:', error);
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
},
|
|
266
282
|
},
|
|
267
283
|
watch: {
|
|
268
284
|
rootElementStyles() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PageFooterViewModel } from '../../view-models';
|
|
1
|
+
import type { PageFooterViewModel, BrandPageViewModel } from '../../view-models';
|
|
2
2
|
import type { PropType } from 'vue';
|
|
3
3
|
import type { BrandPageContext } from '../../models';
|
|
4
4
|
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
@@ -19,6 +19,11 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
19
19
|
required: false;
|
|
20
20
|
default: boolean;
|
|
21
21
|
};
|
|
22
|
+
brandPageViewModel: {
|
|
23
|
+
type: PropType<BrandPageViewModel>;
|
|
24
|
+
required: false;
|
|
25
|
+
default: undefined;
|
|
26
|
+
};
|
|
22
27
|
}>, {}, {}, {
|
|
23
28
|
containerStyle(): BrandPageCssStyle;
|
|
24
29
|
socialLinksIconStyle(): BrandPageCssStyle;
|
|
@@ -46,10 +51,16 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
46
51
|
required: false;
|
|
47
52
|
default: boolean;
|
|
48
53
|
};
|
|
54
|
+
brandPageViewModel: {
|
|
55
|
+
type: PropType<BrandPageViewModel>;
|
|
56
|
+
required: false;
|
|
57
|
+
default: undefined;
|
|
58
|
+
};
|
|
49
59
|
}>> & Readonly<{
|
|
50
60
|
"onOn-logo-click"?: ((...args: any[]) => any) | undefined;
|
|
51
61
|
"onFooter-container-click"?: ((...args: any[]) => any) | undefined;
|
|
52
62
|
}>, {
|
|
63
|
+
brandPageViewModel: BrandPageViewModel;
|
|
53
64
|
isMobile: boolean;
|
|
54
65
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
55
66
|
export default _default;
|
|
@@ -24,9 +24,11 @@ export declare const context: {
|
|
|
24
24
|
mediaSizes?: "size1x" | "size2x" | "sizeThumb" | undefined;
|
|
25
25
|
renderVideoAsImage?: boolean | undefined;
|
|
26
26
|
shouldPlayVideos?: boolean | undefined;
|
|
27
|
+
showOnGeneratedPreviews?: boolean | undefined;
|
|
27
28
|
} | undefined;
|
|
28
29
|
abTests?: import("../../../models").AbTest | undefined;
|
|
29
30
|
isCapturingPreview: boolean;
|
|
31
|
+
showOnGeneratedPreviews?: boolean | undefined;
|
|
30
32
|
disableLogoRenderOnServerside?: boolean | undefined;
|
|
31
33
|
};
|
|
32
34
|
export declare const viewModel: RequestPaymentViewModel;
|
|
@@ -24,9 +24,11 @@ export declare const context: {
|
|
|
24
24
|
mediaSizes?: "size1x" | "size2x" | "sizeThumb" | undefined;
|
|
25
25
|
renderVideoAsImage?: boolean | undefined;
|
|
26
26
|
shouldPlayVideos?: boolean | undefined;
|
|
27
|
+
showOnGeneratedPreviews?: boolean | undefined;
|
|
27
28
|
} | undefined;
|
|
28
29
|
abTests?: import("../../../models").AbTest | undefined;
|
|
29
30
|
isCapturingPreview: boolean;
|
|
31
|
+
showOnGeneratedPreviews?: boolean | undefined;
|
|
30
32
|
disableLogoRenderOnServerside?: boolean | undefined;
|
|
31
33
|
};
|
|
32
34
|
export declare const viewModel: SupportMeViewModel;
|
|
@@ -71,10 +71,13 @@ export interface BrandPageContext {
|
|
|
71
71
|
mediaSizes?: MediaSizes;
|
|
72
72
|
renderVideoAsImage?: boolean;
|
|
73
73
|
shouldPlayVideos?: boolean;
|
|
74
|
+
showOnGeneratedPreviews?: boolean;
|
|
74
75
|
};
|
|
75
76
|
abTests?: AbTest;
|
|
76
77
|
/** Is brand page rendered for preview */
|
|
77
78
|
isCapturingPreview: boolean;
|
|
79
|
+
/** Show on generated previews (template gallery, content settings) */
|
|
80
|
+
showOnGeneratedPreviews?: boolean;
|
|
78
81
|
disableLogoRenderOnServerside?: boolean;
|
|
79
82
|
}
|
|
80
83
|
export declare const getValueType: (key: string, abtestValue?: string) => AbTestResult;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ProfileContent, BrandPageModel } from '../models';
|
|
2
|
+
export declare const findProfileContent: (brandPageData?: BrandPageModel | {
|
|
3
|
+
pages?: any[];
|
|
4
|
+
}) => ProfileContent | undefined;
|
|
5
|
+
export declare const hasProfileContent: (brandPageData?: BrandPageModel | {
|
|
6
|
+
pages?: any[];
|
|
7
|
+
}) => boolean;
|
|
8
|
+
export declare const generateVCard: (brandPageData: BrandPageModel | {
|
|
9
|
+
pages?: any[];
|
|
10
|
+
}) => string;
|
|
11
|
+
export declare const saveContact: (brandPageData: BrandPageModel | {
|
|
12
|
+
pages?: any[];
|
|
13
|
+
}) => void;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { isValidUrl } from '../../helpers/url.helper';
|
|
2
|
+
// Constants
|
|
3
|
+
const HTML_ENTITIES = {
|
|
4
|
+
' ': ' ',
|
|
5
|
+
'&': '&',
|
|
6
|
+
'<': '<',
|
|
7
|
+
'>': '>',
|
|
8
|
+
'"': '"',
|
|
9
|
+
};
|
|
10
|
+
const SOCIAL_TYPE_MAP = {
|
|
11
|
+
facebook: 'FACEBOOK',
|
|
12
|
+
instagram: 'INSTAGRAM',
|
|
13
|
+
x: 'TWITTER',
|
|
14
|
+
linkedin: 'LINKEDIN',
|
|
15
|
+
youtube: 'YOUTUBE',
|
|
16
|
+
pinterest: 'PINTEREST',
|
|
17
|
+
tiktok: 'TIKTOK',
|
|
18
|
+
twitch: 'TWITCH',
|
|
19
|
+
website: 'WEBSITE',
|
|
20
|
+
};
|
|
21
|
+
// Utility Functions
|
|
22
|
+
const sanitizeForVCard = (value) => {
|
|
23
|
+
if (!value || typeof value !== 'string')
|
|
24
|
+
return '';
|
|
25
|
+
let text = value.replace(/<[^>]*>/g, ''); // Strip HTML tags
|
|
26
|
+
// Decode HTML entities
|
|
27
|
+
Object.entries(HTML_ENTITIES).forEach(([entity, char]) => {
|
|
28
|
+
text = text.replace(new RegExp(entity, 'g'), char);
|
|
29
|
+
});
|
|
30
|
+
// Escape backslash FIRST, then other vCard special characters
|
|
31
|
+
text = text.replace(/\\/g, '\\\\');
|
|
32
|
+
text = text.replace(/\n/g, '\\n');
|
|
33
|
+
text = text.replace(/,/g, '\\,');
|
|
34
|
+
text = text.replace(/;/g, '\\;');
|
|
35
|
+
return text.trim();
|
|
36
|
+
};
|
|
37
|
+
const normalizeUrl = (url) => {
|
|
38
|
+
const trimmed = url.trim();
|
|
39
|
+
if (!trimmed)
|
|
40
|
+
return '';
|
|
41
|
+
// Add protocol if missing
|
|
42
|
+
if (trimmed.startsWith('//')) {
|
|
43
|
+
return isValidUrl(`https:${trimmed}`) ? `https:${trimmed}` : '';
|
|
44
|
+
}
|
|
45
|
+
if (!trimmed.startsWith('http://') && !trimmed.startsWith('https://')) {
|
|
46
|
+
return isValidUrl(`https://${trimmed}`) ? `https://${trimmed}` : '';
|
|
47
|
+
}
|
|
48
|
+
return isValidUrl(trimmed) ? trimmed : '';
|
|
49
|
+
};
|
|
50
|
+
const findContentsByType = (brandPageData, type) => {
|
|
51
|
+
if (!brandPageData?.pages)
|
|
52
|
+
return [];
|
|
53
|
+
return brandPageData.pages.flatMap((page) => page.contents?.filter((content) => content.type === type) || []);
|
|
54
|
+
};
|
|
55
|
+
export const findProfileContent = (brandPageData) => {
|
|
56
|
+
if (!brandPageData?.pages)
|
|
57
|
+
return undefined;
|
|
58
|
+
for (const page of brandPageData.pages) {
|
|
59
|
+
const profile = page.contents?.find((content) => content.type === 'profile');
|
|
60
|
+
if (profile)
|
|
61
|
+
return profile;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
};
|
|
65
|
+
export const hasProfileContent = (brandPageData) => findProfileContent(brandPageData) !== undefined;
|
|
66
|
+
// vCard Entry Handlers
|
|
67
|
+
const addPhoneEntry = (phoneNumber, vcardLines) => {
|
|
68
|
+
const cleaned = phoneNumber.replace(/[^\d+]/g, '');
|
|
69
|
+
vcardLines.push(`TEL;TYPE=CELL:${cleaned}`);
|
|
70
|
+
};
|
|
71
|
+
const addEmailEntry = (email, vcardLines) => {
|
|
72
|
+
vcardLines.push(`EMAIL:${email}`, `EMAIL;TYPE=WORK:${email}`);
|
|
73
|
+
};
|
|
74
|
+
const addUrlEntry = (url, type, vcardLines) => {
|
|
75
|
+
const formatted = normalizeUrl(url);
|
|
76
|
+
// Skip invalid URLs
|
|
77
|
+
if (!formatted)
|
|
78
|
+
return;
|
|
79
|
+
if (type) {
|
|
80
|
+
vcardLines.push(`URL;TYPE=${type}:${formatted}`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
vcardLines.push(`URL:${formatted}`);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const processContactUrl = (url, iconType, vcardLines) => {
|
|
87
|
+
if (url.startsWith('tel:')) {
|
|
88
|
+
addPhoneEntry(url.replace('tel:', ''), vcardLines);
|
|
89
|
+
}
|
|
90
|
+
else if (url.startsWith('mailto:')) {
|
|
91
|
+
addEmailEntry(url.replace('mailto:', ''), vcardLines);
|
|
92
|
+
}
|
|
93
|
+
else if (iconType === 'email') {
|
|
94
|
+
addEmailEntry(url, vcardLines);
|
|
95
|
+
}
|
|
96
|
+
else if (iconType === 'phone') {
|
|
97
|
+
addPhoneEntry(url, vcardLines);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
addUrlEntry(url, SOCIAL_TYPE_MAP[iconType], vcardLines);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const processButton = (button, vcardLines) => {
|
|
104
|
+
if (!button.url)
|
|
105
|
+
return;
|
|
106
|
+
const url = button.url.trim();
|
|
107
|
+
const iconType = button.iconUrl?.toLowerCase() || '';
|
|
108
|
+
processContactUrl(url, iconType, vcardLines);
|
|
109
|
+
};
|
|
110
|
+
const processSocialLinks = (socialLinksContent, vcardLines) => {
|
|
111
|
+
if (!socialLinksContent.links?.length)
|
|
112
|
+
return;
|
|
113
|
+
socialLinksContent.links.forEach((link) => {
|
|
114
|
+
if (!link.url)
|
|
115
|
+
return;
|
|
116
|
+
const url = link.url.trim();
|
|
117
|
+
const platform = link.imageUrl?.toLowerCase() || '';
|
|
118
|
+
processContactUrl(url, platform, vcardLines);
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
const addProfileInfo = (profile, vcardLines) => {
|
|
122
|
+
const name = sanitizeForVCard(profile.name || '');
|
|
123
|
+
const title = sanitizeForVCard(profile.title || '');
|
|
124
|
+
const description = sanitizeForVCard(profile.description || '');
|
|
125
|
+
if (name) {
|
|
126
|
+
const nameParts = name.trim().split(/\s+/);
|
|
127
|
+
const lastName = nameParts.length > 1 ? nameParts.pop() || '' : '';
|
|
128
|
+
const middleName = nameParts.length > 1 ? nameParts.pop() || '' : '';
|
|
129
|
+
const firstName = nameParts.join(' ');
|
|
130
|
+
vcardLines.push(`FN:${name}`, `N:${lastName};${firstName};${middleName};;`);
|
|
131
|
+
}
|
|
132
|
+
if (title)
|
|
133
|
+
vcardLines.push(`TITLE:${title}`);
|
|
134
|
+
if (description)
|
|
135
|
+
vcardLines.push(`NOTE:${description}`);
|
|
136
|
+
};
|
|
137
|
+
// Main Functions
|
|
138
|
+
export const generateVCard = (brandPageData) => {
|
|
139
|
+
const vcardLines = ['BEGIN:VCARD', 'VERSION:3.0'];
|
|
140
|
+
const profile = findProfileContent(brandPageData);
|
|
141
|
+
if (profile) {
|
|
142
|
+
addProfileInfo(profile, vcardLines);
|
|
143
|
+
}
|
|
144
|
+
const buttons = findContentsByType(brandPageData, 'button');
|
|
145
|
+
buttons.forEach((button) => processButton(button, vcardLines));
|
|
146
|
+
const socialLinks = findContentsByType(brandPageData, 'social-links');
|
|
147
|
+
socialLinks.forEach((links) => processSocialLinks(links, vcardLines));
|
|
148
|
+
vcardLines.push('END:VCARD');
|
|
149
|
+
return vcardLines.join('\r\n');
|
|
150
|
+
};
|
|
151
|
+
const generateVCardFilename = (name) => {
|
|
152
|
+
if (!name)
|
|
153
|
+
return 'contact.vcf';
|
|
154
|
+
const safeName = name
|
|
155
|
+
.replace(/[^a-z0-9]/gi, '_')
|
|
156
|
+
.toLowerCase()
|
|
157
|
+
.slice(0, 50);
|
|
158
|
+
return `${safeName}.vcf`;
|
|
159
|
+
};
|
|
160
|
+
const downloadVCard = (vcard, filename) => {
|
|
161
|
+
const blob = new Blob([vcard], { type: 'text/vcard;charset=utf-8' });
|
|
162
|
+
const url = URL.createObjectURL(blob);
|
|
163
|
+
const link = document.createElement('a');
|
|
164
|
+
link.href = url;
|
|
165
|
+
link.download = filename;
|
|
166
|
+
document.body.appendChild(link);
|
|
167
|
+
link.click();
|
|
168
|
+
document.body.removeChild(link);
|
|
169
|
+
URL.revokeObjectURL(url);
|
|
170
|
+
};
|
|
171
|
+
export const saveContact = (brandPageData) => {
|
|
172
|
+
const vcard = generateVCard(brandPageData);
|
|
173
|
+
const profile = findProfileContent(brandPageData);
|
|
174
|
+
const filename = generateVCardFilename(profile?.name);
|
|
175
|
+
downloadVCard(vcard, filename);
|
|
176
|
+
};
|
package/lib/src/brand-page-maker/assessors/banner-section-description-visibility.assessor.js
CHANGED
|
@@ -18,7 +18,7 @@ export const bannerDisplayTypeVisibilityAssessor = (content) => {
|
|
|
18
18
|
content?.displayStyle === ALIGN_CARD_LEFT_IMAGE);
|
|
19
19
|
};
|
|
20
20
|
export const bannerOverlayOptionsVisibilityAssessor = (content) => {
|
|
21
|
-
return Boolean(content.imageUrl &&
|
|
21
|
+
return Boolean((content.media?.type === 'getty-video' || content.imageUrl) &&
|
|
22
22
|
[
|
|
23
23
|
ALIGN_CARD_CENTER_IMAGE,
|
|
24
24
|
ALIGN_CARD_LEFT_IMAGE,
|
package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts
CHANGED
|
@@ -1169,6 +1169,7 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
1169
1169
|
bpShowTopNavigationMobile(): boolean;
|
|
1170
1170
|
bpShowTopNavigationDesktop(): boolean;
|
|
1171
1171
|
slug(): string;
|
|
1172
|
+
shouldShowSaveContactWidget(): boolean;
|
|
1172
1173
|
}, {
|
|
1173
1174
|
openSideMenu(): void;
|
|
1174
1175
|
onLogoClick(tabName: string): void;
|
|
@@ -81,6 +81,7 @@ export default defineComponent({
|
|
|
81
81
|
mediaSizes: MEDIA_SIZES.size1x,
|
|
82
82
|
renderVideoAsImage: false,
|
|
83
83
|
shouldPlayVideos: this.shouldPlayVideos,
|
|
84
|
+
showOnGeneratedPreviews: false,
|
|
84
85
|
},
|
|
85
86
|
stripePublishableKey: undefined,
|
|
86
87
|
runtimeEnvironment: this.runtimeEnvironment,
|
|
@@ -432,6 +432,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
432
432
|
scaledContainerStyle(): BrandPageCssStyle;
|
|
433
433
|
innerContainerStyle(): BrandPageCssStyle;
|
|
434
434
|
isPersonalisable(): boolean;
|
|
435
|
+
isAiTemplate(): boolean;
|
|
436
|
+
shouldRenderAsPage(): boolean;
|
|
435
437
|
cssVariablesStyle(): Record<string, string>;
|
|
436
438
|
previewImageUrl(): string;
|
|
437
439
|
}, {
|
|
@@ -118,8 +118,10 @@ export default defineComponent({
|
|
|
118
118
|
disableNavigationSideMenu: true,
|
|
119
119
|
mediaSizes: MEDIA_SIZES.sizeThumb,
|
|
120
120
|
renderVideoAsImage: true,
|
|
121
|
+
showOnGeneratedPreviews: false,
|
|
121
122
|
},
|
|
122
123
|
isCapturingPreview: false,
|
|
124
|
+
showOnGeneratedPreviews: false,
|
|
123
125
|
};
|
|
124
126
|
},
|
|
125
127
|
previewViewport() {
|
|
@@ -147,6 +149,13 @@ export default defineComponent({
|
|
|
147
149
|
isPersonalisable() {
|
|
148
150
|
return this.template.isPersonalisable || false;
|
|
149
151
|
},
|
|
152
|
+
isAiTemplate() {
|
|
153
|
+
return this.selectedTab.key === TEMPLATE_TABS.AI;
|
|
154
|
+
},
|
|
155
|
+
shouldRenderAsPage() {
|
|
156
|
+
const result = this.isPrePurchase || this.isAiTemplate;
|
|
157
|
+
return result;
|
|
158
|
+
},
|
|
150
159
|
cssVariablesStyle() {
|
|
151
160
|
if (!this.logoTheme) {
|
|
152
161
|
return {};
|
|
@@ -47,6 +47,8 @@ export declare const EVENTS: {
|
|
|
47
47
|
WEBSITE_MAKER_AI_SEND_PROMPT: string;
|
|
48
48
|
WEBSITE_MAKER_AI_COPY_RESPONSE: string;
|
|
49
49
|
WEBSITE_MAKER_AI_STOP_GENERATION: string;
|
|
50
|
+
WEBSITE_SAVE_CONTACT: string;
|
|
51
|
+
WEBSITE_START_FOR_FREE: string;
|
|
50
52
|
};
|
|
51
53
|
export declare const SELECT_LOCATIONS: {
|
|
52
54
|
MAKER_PREVIEW: string;
|
|
@@ -30,6 +30,8 @@ export const EVENTS = {
|
|
|
30
30
|
WEBSITE_MAKER_AI_SEND_PROMPT: 'website_maker_ai_send_prompt',
|
|
31
31
|
WEBSITE_MAKER_AI_COPY_RESPONSE: 'website_maker_ai_copy_response',
|
|
32
32
|
WEBSITE_MAKER_AI_STOP_GENERATION: 'website_maker_ai_stop_generation',
|
|
33
|
+
WEBSITE_SAVE_CONTACT: 'website_save_contact',
|
|
34
|
+
WEBSITE_START_FOR_FREE: 'website_start_for_free',
|
|
33
35
|
};
|
|
34
36
|
export const SELECT_LOCATIONS = {
|
|
35
37
|
MAKER_PREVIEW: 'maker_preview',
|