@designcrowd/library.brand-page 5.15.24 → 5.15.25-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-D7rRFKgr.js → CreatedOnBrandCrowd-de-de-DvyH2DZQ.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-CaTNBPEK.js → CreatedOnBrandCrowd-en-us-BkhFX5IH.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-zdp6A-zF.js → CreatedOnBrandCrowd-es-es-BXVsJsEz.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-TS3XLzo6.js → CreatedOnBrandCrowd-fr-ca-xVXVxfTs.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-TS3XLzo6.js → CreatedOnBrandCrowd-fr-fr-xVXVxfTs.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-DkyF49-j.js → CreatedOnBrandCrowd-pt-br-BClAECgN.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-DkyF49-j.js → CreatedOnBrandCrowd-pt-pt-BClAECgN.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-BckUcm9C.js → CreatedOnDcom-de-de-DlzLknwo.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-CqgIo3AG.js → CreatedOnDcom-en-us-NjczWDeO.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-DOEOu0Gx.js → CreatedOnDcom-es-es-Dazo-CXa.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-DjbwfTN3.js → CreatedOnDcom-fr-ca-DXzP_BfL.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-By17z-yX.js → CreatedOnDcom-fr-fr-DSBumzDY.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-D9AAR_em.js → CreatedOnDcom-pt-br-DrQC5tTd.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-Bz8SLuU2.js → CreatedOnDcom-pt-pt-CJubdGWs.js} +1 -1
  15. package/lib/src/brand-page/utils/migration/migration-07.js +1 -1
  16. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +287 -1
  17. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.js +60 -5
  18. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +11 -1
  19. package/lib/src/css/library.brand-page-brandCrowd.min.css +43 -19
  20. package/lib/src/css/library.brand-page-brandPage.min.css +43 -19
  21. package/lib/src/css/library.brand-page-designCom.min.css +43 -19
  22. package/lib/src/css/library.brand-page-preview.min.css +43 -19
  23. package/lib/src/index.mjs +1 -1
  24. package/lib/src/{lib-CgMLUv91.js → lib-BGjUW0Xe.js} +5839 -5764
  25. package/lib/src/shared/template-settings/store/template-settings-store.js +22 -5
  26. package/package.json +1 -1
  27. package/src/brand-page/components/page/Page.vue +2 -2
  28. package/src/brand-page/utils/migration/migration-07.ts +6 -4
  29. package/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.ts +87 -6
  30. package/src/brand-page-maker/components/template-preview/TemplatePreview.vue +42 -4
  31. package/src/brand-page-maker/components/template-preview-with-state/TemplatePreviewWithState.vue +4 -6
  32. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +16 -1
  33. package/src/shared/template-settings/store/template-settings-store.ts +29 -8
@@ -171,11 +171,28 @@ export const useUiTemplateSettingsStore = defineStore('uiTemplateSettings', {
171
171
  return;
172
172
  }
173
173
  this._setPageCount({ pageCount: result.pageCount });
174
- const templates = (await Promise.all(result.paginatedItems.map(async (i) => {
175
- const template = await designTemplateClient.getTemplateByTemplateToken(i.designTemplateToken);
176
- return this.safeMapToTemplateSettingsTemplate(template);
177
- }))).filter((t) => Boolean(t));
178
- this._addTemplates({ templates });
174
+ const templates = await Promise.all(result.paginatedItems.map(async (i) => {
175
+ try {
176
+ const template = await designTemplateClient.getTemplateByTemplateToken(i.designTemplateToken);
177
+ const isAiTemplate = uiStore.personalisationData &&
178
+ uiStore.personalisationData.length > 0 &&
179
+ this.selectedTab.key === TEMPLATE_TABS.AI;
180
+ if (brandPageContainerStore.isPrePurchase || isAiTemplate) {
181
+ const result = await this.safeMapToTemplateSettingsTemplate(template);
182
+ return result;
183
+ }
184
+ else {
185
+ return {
186
+ id: i.designTemplateToken,
187
+ };
188
+ }
189
+ }
190
+ catch (error) {
191
+ return null;
192
+ }
193
+ }));
194
+ const validTemplates = templates.filter((template) => template !== null);
195
+ this._addTemplates({ templates: validTemplates });
179
196
  this._setPageNoLoaded({ pageNoLoaded: pageNo });
180
197
  }
181
198
  finally {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "5.15.24",
4
+ "version": "5.15.25-2",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -50,9 +50,9 @@
50
50
  'tw-cursor-pointer': context.isPreview,
51
51
  'brand-page__content--outline-selected': isHeaderSelected,
52
52
  }"
53
+ :is-mobile="true"
53
54
  @open-side-menu="openSideMenu"
54
55
  @header-container-click="onPageHeaderContainerClick"
55
- :is-mobile="true"
56
56
  />
57
57
  </template>
58
58
  </MediaQuery>
@@ -211,9 +211,9 @@
211
211
  isFooterSelected,
212
212
  }"
213
213
  :show-brand-crowd-logo="showBrandCrowdLogo"
214
+ :is-mobile="true"
214
215
  @footer-container-click="onPageFooterContainerClick"
215
216
  @on-logo-click="onLogoClick"
216
- :is-mobile="true"
217
217
  />
218
218
  </template>
219
219
  </MediaQuery>
@@ -1,12 +1,14 @@
1
- import {
2
- BRAND_PAGE_TYPES,
3
- DEFAULT_LOGO_HEIGHT,
4
- DEFAULT_LOGO_WIDTH,
1
+ import type {
5
2
  PageFooterDesktop,
6
3
  PageFooterMobile,
7
4
  PageHeaderDesktop,
8
5
  PageHeaderMobile,
9
6
  } from '../..';
7
+ import {
8
+ BRAND_PAGE_TYPES,
9
+ DEFAULT_LOGO_HEIGHT,
10
+ DEFAULT_LOGO_WIDTH,
11
+ } from '../..';
10
12
  import { FabricRenderClient } from '../../../clients/fabric-render-client';
11
13
  import { calculateLogoDimensions } from '../logo.util';
12
14
  import type { MigrationData } from '../migration.util';
@@ -15,17 +15,24 @@ import {
15
15
  getBrandPageViewModelFromBrandPageModel,
16
16
  } from '../../../brand-page/utils';
17
17
  import { STYLE_THEME_KEYS } from '../../../brand-page/constants';
18
- import type { TemplateSettingsTemplate } from '../../../shared/template-settings/models';
18
+ import {
19
+ TEMPLATE_TABS,
20
+ type TemplateSettingsTemplate,
21
+ } from '../../../shared/template-settings/models';
19
22
  import type { DebounceHandle } from 'lodash.debounce';
20
23
  import debounce from 'lodash.debounce';
21
24
  import { MOBILE_HEIGHT, MOBILE_WIDTH } from '../../constants';
22
- import { useBrandPageMakerStore } from '../../stores';
25
+ import {
26
+ useBrandPageContainerStore,
27
+ useBrandPageMakerStore,
28
+ } from '../../stores';
23
29
  import {
24
30
  applyLogoImageBase64UrlToBrandPageTemplateModel,
25
31
  applyLogoImageToBrandPageTemplateModel,
26
32
  applyLogoTemplateImageToBrandPageTemplateModel,
27
33
  } from '../../../brand-page/utils/logo.util';
28
34
  import { useVideoStore } from '../../../lib';
35
+ import { useUiTemplateSettingsStore } from '../../../shared/template-settings/store';
29
36
 
30
37
  const DEBOUNCE_IN_MS = 250;
31
38
 
@@ -41,18 +48,29 @@ interface TemplatePreviewData {
41
48
  renderHeight: number;
42
49
  renderWidth: number;
43
50
  rootStyles: BrandPageCssStyle;
51
+ imageLoadError: boolean;
52
+ imageLoading: boolean;
44
53
  }
45
54
 
46
55
  export default defineComponent({
47
56
  emits: ['template-selected'],
48
57
  setup() {
49
58
  const brandPageMakerStore = useBrandPageMakerStore();
59
+ const brandPageContainerStore = useBrandPageContainerStore();
60
+ const templateSettingsStore = useUiTemplateSettingsStore();
50
61
 
51
62
  return {
52
63
  selectedTemplateId: computed(
53
64
  () => brandPageMakerStore.selectedTemplateId,
54
65
  ),
66
+ isPrePurchase: computed(() => brandPageContainerStore.isPrePurchase),
67
+ runtimeEnvironment: computed(
68
+ () => brandPageContainerStore.runtimeEnvironment,
69
+ ),
70
+ selectedTab: computed(() => templateSettingsStore.selectedTab),
71
+ templateSettingsStore,
55
72
  brandPageMakerStore,
73
+ brandPageContainerStore,
56
74
  };
57
75
  },
58
76
  props: {
@@ -111,6 +129,8 @@ export default defineComponent({
111
129
  renderWidth: 400,
112
130
  rootStyles: {},
113
131
  viewModel: undefined,
132
+ imageLoadError: false,
133
+ imageLoading: true,
114
134
  };
115
135
 
116
136
  return data;
@@ -182,6 +202,16 @@ export default defineComponent({
182
202
  return this.template.isPersonalisable || false;
183
203
  },
184
204
 
205
+ isAiTemplate(): boolean {
206
+ return this.selectedTab.key === TEMPLATE_TABS.AI;
207
+ },
208
+
209
+ shouldRenderAsPage(): boolean {
210
+ const result = this.isPrePurchase || this.isAiTemplate;
211
+
212
+ return result;
213
+ },
214
+
185
215
  cssVariablesStyle(): Record<string, string> {
186
216
  if (!this.logoTheme) {
187
217
  return {};
@@ -202,17 +232,25 @@ export default defineComponent({
202
232
 
203
233
  return cssVariables;
204
234
  },
235
+
236
+ previewImageUrl(): string {
237
+ return this.generatePreviewImageUrl();
238
+ },
205
239
  },
206
240
  watch: {
241
+ template() {
242
+ if (this.isPrePurchase) {
243
+ this.updateViewModel();
244
+ }
245
+ },
207
246
  logoTheme: {
208
247
  handler() {
209
- this.updateViewModel();
248
+ if (this.isPrePurchase) {
249
+ this.updateViewModel();
250
+ }
210
251
  },
211
252
  deep: true,
212
253
  },
213
- template() {
214
- this.updateViewModel();
215
- },
216
254
  },
217
255
  created() {
218
256
  this.updateViewModel(false);
@@ -260,7 +298,50 @@ export default defineComponent({
260
298
  this.rootStyles = styles;
261
299
  },
262
300
 
301
+ onImageError() {
302
+ console.warn(
303
+ `Failed to load preview image for template ${this.template.id}`,
304
+ );
305
+ this.imageLoadError = true;
306
+ this.imageLoading = false;
307
+ },
308
+
309
+ onImageLoad() {
310
+ this.imageLoadError = false;
311
+ this.imageLoading = false;
312
+ },
313
+
314
+ generatePreviewImageUrl(): string {
315
+ const baseUrl = this.getPreviewBaseUrl();
316
+ const logoDraftToken =
317
+ this.logoImage?.logoDraftToken ||
318
+ '0B660926-D94A-4E29-99D1-F07E67AA6E49';
319
+
320
+ const deviceType =
321
+ this.brandPageMakerStore.brandPageType === 'brandSite'
322
+ ? 'desktop'
323
+ : 'mobile';
324
+
325
+ return `${baseUrl}/preview/template/${this.template.id}/${logoDraftToken}?deviceType=${deviceType}`;
326
+ },
327
+
328
+ getPreviewBaseUrl(): string {
329
+ const domainSuffix = '.brand.page';
330
+
331
+ return `https://preview-${this.runtimeEnvironment}${domainSuffix}`;
332
+ },
333
+
334
+ regeneratePreview() {
335
+ this.imageLoadError = false;
336
+ this.imageLoading = true;
337
+ this.$forceUpdate();
338
+ },
339
+
263
340
  async updateViewModel(forceUpdate = true) {
341
+ if (!this.isPrePurchase) {
342
+ return;
343
+ }
344
+
264
345
  const videoStore = useVideoStore();
265
346
 
266
347
  let model = this.template.brandPageModel;
@@ -18,8 +18,11 @@
18
18
  <span class="tw-sr-only">Select Template</span>
19
19
  </button>
20
20
  <!-- End Overlay-->
21
- <!-- Start Page -->
22
- <div class="template-preview__page" :style="cssVariablesStyle">
21
+ <div
22
+ v-if="shouldRenderAsPage"
23
+ class="template-preview__page"
24
+ :style="cssVariablesStyle"
25
+ >
23
26
  <Page
24
27
  v-if="viewModel"
25
28
  :context="context"
@@ -29,7 +32,28 @@
29
32
  @on-set-preview-styles="onSetPreviewStyles"
30
33
  />
31
34
  </div>
32
- <!-- End Page -->
35
+ <!-- Start Preview Image -->
36
+ <div v-else class="template-preview__image-container">
37
+ <!-- Loading spinner -->
38
+ <div
39
+ v-if="imageLoading"
40
+ class="tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center tw-bg-gray-50 tw-z-10"
41
+ >
42
+ <div class="tw-scale-150">
43
+ <Loader size="lg" />
44
+ </div>
45
+ </div>
46
+
47
+ <img
48
+ :src="previewImageUrl"
49
+ :alt="`Template ${template.id} preview`"
50
+ class="template-preview__image"
51
+ :class="{ 'tw-opacity-0': imageLoading }"
52
+ @error="onImageError"
53
+ @load="onImageLoad"
54
+ />
55
+ </div>
56
+ <!-- End Preview Image -->
33
57
  <!-- Start personalisation tag -->
34
58
  <div
35
59
  v-if="isPersonalisable"
@@ -45,12 +69,14 @@
45
69
  </template>
46
70
  <script>
47
71
  import { defineComponent } from 'vue';
72
+ import { Loader } from '@designcrowd/fe-shared-lib';
48
73
  import TemplatePreviewMixin from './TemplatePreview.mixin.ts';
49
74
  import Page from '../../../brand-page/components/page/Page.vue';
50
75
 
51
76
  export default defineComponent({
52
77
  components: {
53
78
  Page,
79
+ Loader,
54
80
  },
55
81
  mixins: [TemplatePreviewMixin],
56
82
  setup(props, context) {
@@ -68,11 +94,23 @@ export default defineComponent({
68
94
  @apply tw-absolute tw-top-0 tw-left-0 tw-right-0 tw-bottom-0 tw-opacity-0 tw-cursor-pointer tw-w-full tw-h-full;
69
95
  }
70
96
 
71
- .template-preview__page {
97
+ .template-preview__image-container {
72
98
  @apply tw-pointer-events-none;
99
+ @apply tw-w-full tw-h-full;
73
100
  }
74
101
 
102
+ .template-preview__image {
103
+ @apply tw-w-full tw-h-full tw-object-fill;
104
+ transition: filter 0.2s ease;
105
+ }
106
+
107
+ .template-preview__page {
108
+ @apply tw-pointer-events-none;
109
+ }
75
110
  .template-preview :deep(.c-shape-background) {
76
111
  @apply tw-absolute;
77
112
  }
113
+ .template-preview__image :deep(.c-shape-background) {
114
+ @apply tw-absolute;
115
+ }
78
116
  </style>
@@ -41,12 +41,10 @@ const pageSettingsStore = useUiPageSettingsStore();
41
41
 
42
42
  const logoTheme = computed(() => uiStore.logoTheme);
43
43
 
44
- const personalisationData = computed(() =>
45
- uiStore.personalisationData?.length
46
- ? uiStore.personalisationData[props.template.personalisationContentIndex]
47
- .userPersonalisation
48
- : undefined,
49
- );
44
+ const personalisationData = computed(() => {
45
+ const index = props.template.personalisationContentIndex;
46
+ return uiStore.personalisationData?.[index]?.userPersonalisation;
47
+ });
50
48
 
51
49
  const templateLogoImage = computed(() => {
52
50
  const desktopPageHeader =
@@ -360,7 +360,7 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
360
360
  return;
361
361
  }
362
362
 
363
- const template = templateSettingsStore.getTemplateByTemplateId(
363
+ let template = templateSettingsStore.getTemplateByTemplateId(
364
364
  this.selectedTemplateId,
365
365
  );
366
366
 
@@ -372,6 +372,21 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
372
372
  return;
373
373
  }
374
374
 
375
+ // If template doesn't have brandPageModel (post-purchase mode), fetch it
376
+ if (!template.brandPageModel) {
377
+ template = await templateSettingsStore.getCachedTemplateByTokenAsync(
378
+ this.selectedTemplateId,
379
+ );
380
+
381
+ if (!template || !template.brandPageModel) {
382
+ if (process.env.NODE_ENV !== 'production') {
383
+ throw new Error('Failed to fetch template brandPageModel');
384
+ }
385
+
386
+ return;
387
+ }
388
+ }
389
+
375
390
  this.isApplyingTemplate = true;
376
391
 
377
392
  let brandPageModel = cloneDeep(template.brandPageModel);
@@ -273,20 +273,41 @@ export const useUiTemplateSettingsStore = defineStore('uiTemplateSettings', {
273
273
 
274
274
  this._setPageCount({ pageCount: result.pageCount });
275
275
 
276
- const templates = (
277
- await Promise.all(
278
- result.paginatedItems.map(async (i) => {
276
+ const templates = await Promise.all(
277
+ result.paginatedItems.map(async (i) => {
278
+ try {
279
279
  const template =
280
280
  await designTemplateClient.getTemplateByTemplateToken(
281
281
  i.designTemplateToken,
282
282
  );
283
283
 
284
- return this.safeMapToTemplateSettingsTemplate(template);
285
- }),
286
- )
287
- ).filter((t): t is TemplateSettingsTemplate => Boolean(t));
284
+ const isAiTemplate =
285
+ uiStore.personalisationData &&
286
+ uiStore.personalisationData.length > 0 &&
287
+ this.selectedTab.key === TEMPLATE_TABS.AI;
288
+
289
+ if (brandPageContainerStore.isPrePurchase || isAiTemplate) {
290
+ const result =
291
+ await this.safeMapToTemplateSettingsTemplate(template);
292
+
293
+ return result;
294
+ } else {
295
+ return {
296
+ id: i.designTemplateToken,
297
+ } as TemplateSettingsTemplate;
298
+ }
299
+ } catch (error) {
300
+ return null;
301
+ }
302
+ }),
303
+ );
304
+
305
+ const validTemplates = templates.filter(
306
+ (template) => template !== null,
307
+ );
308
+
309
+ this._addTemplates({ templates: validTemplates });
288
310
 
289
- this._addTemplates({ templates });
290
311
  this._setPageNoLoaded({ pageNoLoaded: pageNo });
291
312
  } finally {
292
313
  this._setIsBusy({ isBusy: false });