@gem-sdk/pages 2.0.0-staging.152 → 2.0.0-staging.709

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 (62) hide show
  1. package/dist/cjs/components/FooterForPostPurchase.js +1 -1
  2. package/dist/cjs/components/builder/Footer.js +2 -2
  3. package/dist/cjs/components/builder/Header.js +0 -1
  4. package/dist/cjs/components/builder/Toolbar.js +6 -0
  5. package/dist/cjs/components/builder/Toolbox.js +27 -14
  6. package/dist/cjs/components/composable/getListFontWeightTypos.js +14 -0
  7. package/dist/cjs/components/image-to-layout/AddSectionImageToLayout.js +5 -4
  8. package/dist/cjs/components/image-to-layout/DropElement.js +34 -9
  9. package/dist/cjs/constants/index.js +15 -0
  10. package/dist/cjs/libs/api/get-home-page-props-v2.js +20 -8
  11. package/dist/cjs/libs/api/get-home-page-props.js +15 -3
  12. package/dist/cjs/libs/api/get-post-purchase-props-preview.js +38 -5
  13. package/dist/cjs/libs/api/get-static-page-props-preview.js +5 -0
  14. package/dist/cjs/libs/api/get-static-page-props-v2.js +19 -10
  15. package/dist/cjs/libs/api/get-static-page-props.js +16 -3
  16. package/dist/cjs/libs/google-fonts.js +25 -5
  17. package/dist/cjs/libs/helpers/gen-fonts.js +9 -3
  18. package/dist/cjs/libs/helpers/get-metafield.js +7 -0
  19. package/dist/cjs/libs/helpers/normalize.js +2 -1
  20. package/dist/cjs/libs/helpers/parse-json.js +1 -1
  21. package/dist/cjs/libs/helpers/sentry.js +17 -0
  22. package/dist/cjs/pages/404.js +1 -0
  23. package/dist/cjs/pages/500.js +1 -0
  24. package/dist/cjs/pages/CollectionGlobalProvider.js +1 -0
  25. package/dist/cjs/pages/builder.js +46 -41
  26. package/dist/cjs/pages/collection-detail.js +1 -0
  27. package/dist/cjs/pages/preview.js +1 -0
  28. package/dist/cjs/pages/product-detail.js +1 -0
  29. package/dist/cjs/pages/static-v2.js +22 -17
  30. package/dist/cjs/pages/static.js +1 -0
  31. package/dist/esm/components/FooterForPostPurchase.js +1 -1
  32. package/dist/esm/components/builder/Footer.js +2 -2
  33. package/dist/esm/components/builder/Header.js +1 -2
  34. package/dist/esm/components/builder/Toolbar.js +6 -0
  35. package/dist/esm/components/builder/Toolbox.js +27 -14
  36. package/dist/esm/components/composable/getListFontWeightTypos.js +12 -0
  37. package/dist/esm/components/image-to-layout/AddSectionImageToLayout.js +6 -5
  38. package/dist/esm/components/image-to-layout/DropElement.js +34 -9
  39. package/dist/esm/constants/index.js +15 -0
  40. package/dist/esm/libs/api/get-home-page-props-v2.js +21 -9
  41. package/dist/esm/libs/api/get-home-page-props.js +16 -4
  42. package/dist/esm/libs/api/get-post-purchase-props-preview.js +39 -6
  43. package/dist/esm/libs/api/get-static-page-props-preview.js +5 -0
  44. package/dist/esm/libs/api/get-static-page-props-v2.js +19 -10
  45. package/dist/esm/libs/api/get-static-page-props.js +17 -4
  46. package/dist/esm/libs/google-fonts.js +25 -5
  47. package/dist/esm/libs/helpers/gen-fonts.js +9 -3
  48. package/dist/esm/libs/helpers/get-metafield.js +5 -0
  49. package/dist/esm/libs/helpers/normalize.js +2 -1
  50. package/dist/esm/libs/helpers/parse-json.js +1 -1
  51. package/dist/esm/libs/helpers/sentry.js +15 -0
  52. package/dist/esm/pages/404.js +1 -0
  53. package/dist/esm/pages/500.js +1 -0
  54. package/dist/esm/pages/CollectionGlobalProvider.js +1 -0
  55. package/dist/esm/pages/builder.js +47 -42
  56. package/dist/esm/pages/collection-detail.js +1 -0
  57. package/dist/esm/pages/preview.js +1 -0
  58. package/dist/esm/pages/product-detail.js +1 -0
  59. package/dist/esm/pages/static-v2.js +23 -18
  60. package/dist/esm/pages/static.js +1 -0
  61. package/dist/types/index.d.ts +61 -53
  62. package/package.json +6 -6
@@ -4,11 +4,12 @@ import { useMatchMutate, useShopStore, usePageStore, useBuilderPreviewStore, use
4
4
  import { memo, useMemo, useCallback, useEffect } from 'react';
5
5
  import { getStorefrontApi } from '../../libs/get-storefront-api.js';
6
6
  import { createFontUrl } from '../../libs/google-fonts.js';
7
+ import { checkNotInOptionFont } from '../../libs/helpers/check-option-font.js';
7
8
  import { genCSS } from '../../libs/helpers/gen-css.js';
8
9
  import { getFontsFromDataBuilder } from '../../libs/helpers/gen-fonts.js';
9
10
  import { shopifyCdnWithGoogleFonts } from '../../libs/shopify-cdn-with-google-fonts.js';
10
11
  import { libsStore } from '../../store/libs-store.js';
11
- import { checkNotInOptionFont } from '../../libs/helpers/check-option-font.js';
12
+ import { getListFontWeightTypos } from '../composable/getListFontWeightTypos.js';
12
13
 
13
14
  const globalStyleId = 'global-style';
14
15
  const Toolbox = ()=>{
@@ -17,6 +18,7 @@ const Toolbox = ()=>{
17
18
  const changeStorefrontInfo = useShopStore((s)=>s.changeStorefrontInfo);
18
19
  const setDynamicProduct = usePageStore((s)=>s.setDynamicProduct);
19
20
  const setPostPurchaseProductOffers = usePageStore((s)=>s.setPostPurchaseProductOffers);
21
+ const setDynamicDiscountOffer = usePageStore((s)=>s.setDynamicDiscountOffer);
20
22
  const setSalePageProductId = usePageStore((s)=>s.setSalePageProductId);
21
23
  const setDynamicCollection = usePageStore((s)=>s.setDynamicCollection);
22
24
  const initState = useBuilderPreviewStore((s)=>s.initState);
@@ -34,7 +36,7 @@ const Toolbox = ()=>{
34
36
  const changeLayoutSettings = useShopStore((s)=>s.changeLayoutSettings);
35
37
  const changeCreateThemeSectionCount = useShopStore((s)=>s.changeCreateThemeSectionCount);
36
38
  const changeShopPlan = useShopStore((s)=>s.changeShopPlan);
37
- const changeShopifyPlan = useShopStore((s)=>s.changeShopifyPlan);
39
+ const updatePriceWithCurrency = useShopStore((s)=>s.updatePriceWithCurrency);
38
40
  const changeFontType = libsStore((s)=>s.changeFontType);
39
41
  const fontType = libsStore((s)=>s.fontType);
40
42
  const clearModal = useModalStore((s)=>s.clearModal);
@@ -133,9 +135,11 @@ const Toolbox = ()=>{
133
135
  try {
134
136
  if (detail.data) {
135
137
  const themeStyle = genCSS(detail.data, detail.mobileOnly);
136
- const font = Object.entries(detail.data?.font).map(([, value])=>{
137
- return value;
138
- }).map((item)=>{
138
+ const fontWeights = getListFontWeightTypos(detail.data?.typography);
139
+ const font = Object.entries(detail.data?.font).map(([, value])=>({
140
+ ...value,
141
+ variants: value.variants.filter((variant)=>fontWeights.includes(variant) || variant === 'regular' && fontWeights.includes('400')).map((variant)=>variant === 'regular' ? '400' : variant)
142
+ })).map((item)=>{
139
143
  if (item.type == 'custom') {
140
144
  const isGoogleFont = shopifyCdnWithGoogleFonts.find((ggFont)=>ggFont.family == item.family);
141
145
  if (isGoogleFont) {
@@ -292,12 +296,12 @@ const Toolbox = ()=>{
292
296
  }, [
293
297
  changeShopPlan
294
298
  ]);
295
- const onUpdateShopifyPlan = useCallback((e)=>{
296
- const shopifyPlan = e.detail;
297
- if (!shopifyPlan) return;
298
- changeShopifyPlan(shopifyPlan);
299
+ const onUpdatePriceWithCurrency = useCallback((e)=>{
300
+ const showPriceCurrency = e.detail;
301
+ if (!showPriceCurrency) return;
302
+ updatePriceWithCurrency(showPriceCurrency);
299
303
  }, [
300
- changeShopifyPlan
304
+ updatePriceWithCurrency
301
305
  ]);
302
306
  const onUpdateFontType = useCallback((e)=>{
303
307
  const fontType = e.detail;
@@ -350,6 +354,13 @@ const Toolbox = ()=>{
350
354
  }, [
351
355
  setPostPurchaseProductOffers
352
356
  ]);
357
+ const onUpdateDynamicDiscountOffer = useCallback((e)=>{
358
+ const dynamicDiscountOffer = e.detail;
359
+ if (!dynamicDiscountOffer) return;
360
+ setDynamicDiscountOffer(dynamicDiscountOffer);
361
+ }, [
362
+ setDynamicDiscountOffer
363
+ ]);
353
364
  const onUpdateSalePageProductId = useCallback((e)=>{
354
365
  const id = e.detail;
355
366
  if (!id) return;
@@ -416,12 +427,12 @@ const Toolbox = ()=>{
416
427
  window.addEventListener('on-off-header-footer', onChangeLayoutSettingData);
417
428
  window.addEventListener('update-create-theme-section-count', onUpdateCreateThemeSectionCount);
418
429
  window.addEventListener('update-shop-plan', onUpdateShopPlan);
419
- window.addEventListener('update-shopify-plan', onUpdateShopifyPlan);
420
430
  window.addEventListener('set-dynamic-product', onUpdateDynamicProduct);
421
431
  window.addEventListener('set-dynamic-collection', onUpdateDynamicCollection);
422
432
  window.addEventListener('update-item-name', onUpdateItemName);
423
433
  window.addEventListener('update-item-attribute', onUpdateItemAttribute);
424
434
  window.addEventListener('set-product-offer', onUpdateProductOffers);
435
+ window.addEventListener('set-dynamic-discount-offer', onUpdateDynamicDiscountOffer);
425
436
  window.addEventListener('update-sale-page-product-id', onUpdateSalePageProductId);
426
437
  window.addEventListener('limit-create-theme-section', onLimitCreateThemeSection);
427
438
  window.addEventListener('update-interaction-is-select-on-page', onUpdateInteractionIsSelectOnPage);
@@ -429,6 +440,7 @@ const Toolbox = ()=>{
429
440
  window.addEventListener('update-interaction-setting-type', onUpdateInteractionSettingType);
430
441
  window.addEventListener('change-sidebar-mode', onChangeSidebarMode);
431
442
  window.addEventListener('update-font-type', onUpdateFontType);
443
+ window.addEventListener('update-price-with-currency', onUpdatePriceWithCurrency);
432
444
  return ()=>{
433
445
  window.removeEventListener('update-shop-info', onChangeShopInfo);
434
446
  window.removeEventListener('revalidate-query', onRevalidateQuery);
@@ -442,7 +454,7 @@ const Toolbox = ()=>{
442
454
  window.removeEventListener('on-off-header-footer', onChangeLayoutSettingData);
443
455
  window.removeEventListener('update-create-theme-section-count', onUpdateCreateThemeSectionCount);
444
456
  window.removeEventListener('update-shop-plan', onUpdateShopPlan);
445
- window.removeEventListener('update-shopify-plan', onUpdateShopifyPlan);
457
+ window.removeEventListener('update-price-with-currency', onUpdatePriceWithCurrency);
446
458
  window.removeEventListener('set-dynamic-product', onUpdateDynamicProduct);
447
459
  window.removeEventListener('set-dynamic-collection', onUpdateDynamicCollection);
448
460
  window.removeEventListener('update-item-name', onUpdateItemName);
@@ -458,7 +470,6 @@ const Toolbox = ()=>{
458
470
  }, [
459
471
  onAddEntity,
460
472
  onUpdateShopPlan,
461
- onUpdateShopifyPlan,
462
473
  onForceUpdateEntityProps,
463
474
  onUpdateEntityProp,
464
475
  onInitBuilder,
@@ -481,7 +492,9 @@ const Toolbox = ()=>{
481
492
  onUpdateInteractionIsSelectOnPage,
482
493
  onUpdateInteractionSettingType,
483
494
  onUpdateFontType,
484
- onChangeSidebarMode
495
+ onChangeSidebarMode,
496
+ onUpdateDynamicDiscountOffer,
497
+ onUpdatePriceWithCurrency
485
498
  ]);
486
499
  return /*#__PURE__*/ jsx("div", {
487
500
  className: "toolbox"
@@ -0,0 +1,12 @@
1
+ const getListFontWeightTypos = (font)=>{
2
+ const fontWeights = new Set();
3
+ Object.values(font).forEach((fontStyle)=>{
4
+ // Check desktop fontWeight
5
+ if (fontStyle.desktop?.fontWeight) {
6
+ fontWeights.add(fontStyle.desktop.fontWeight);
7
+ }
8
+ });
9
+ return Array.from(fontWeights);
10
+ };
11
+
12
+ export { getListFontWeightTypos };
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { useMemo } from 'react';
4
- import { useShopStore, useBuilderPreviewStore, makeStyleResponsive } from '@gem-sdk/core';
4
+ import { useI18nStore, useShopStore, useBuilderPreviewStore, makeStyleResponsive } from '@gem-sdk/core';
5
5
 
6
6
  const BASE_DATA = [
7
7
  {
@@ -33,6 +33,7 @@ const defaultPadding = {
33
33
  mobile: 'var(--g-ct-p)'
34
34
  };
35
35
  const AddSectionImageToLayout = ({ editorImageToLayout })=>{
36
+ const { t } = useI18nStore();
36
37
  const layoutSetting = useShopStore((s)=>s.layoutSettings);
37
38
  const totalSection = useBuilderPreviewStore((state)=>state.state.ROOT.childrens?.length);
38
39
  const editingPageType = useShopStore((s)=>s.pageType);
@@ -78,11 +79,11 @@ const AddSectionImageToLayout = ({ editorImageToLayout })=>{
78
79
  children: [
79
80
  /*#__PURE__*/ jsx("span", {
80
81
  className: "gp-absolute gp-top-[-12px] gp-bg-white gp-px-[8px] gp-text-[14px] gp-font-normal gp-text-[#9E9E9E]",
81
- children: "Add section"
82
+ children: t('Add section')
82
83
  }),
83
84
  ACTIONS_DATA.map((action)=>{
84
85
  return /*#__PURE__*/ jsxs("div", {
85
- className: `gp-relative gp-mx-1 gp-h-[60px] gp-w-[172px] w375:gp-w-auto w576:gp-w-auto gp-cursor-pointer gp-flex-col gp-items-center gp-justify-center gp-rounded-[3px] gp-bg-[#F4F4F4] hover:gp-bg-black/10 gp-flex`,
86
+ className: `gp-relative gp-mx-1 gp-min-h-[60px] gp-border-box w375:gp-w-auto w576:gp-w-auto gp-cursor-pointer gp-flex-col gp-items-center gp-justify-center gp-rounded-[3px] gp-bg-[#F4F4F4] hover:gp-bg-black/10 gp-flex gp-p-2`,
86
87
  id: action.id,
87
88
  onClick: ()=>handleAddSectionAction(action.eventID),
88
89
  "aria-hidden": true,
@@ -90,7 +91,7 @@ const AddSectionImageToLayout = ({ editorImageToLayout })=>{
90
91
  /*#__PURE__*/ jsxs("div", {
91
92
  className: "gp-mb-[4px] gp-flex gp-gap-2 gp-text-[14px] gp-font-medium gp-text-[#212121]",
92
93
  children: [
93
- action.title,
94
+ t(action.title),
94
95
  action.hasAILogo && /*#__PURE__*/ jsxs("svg", {
95
96
  width: "43",
96
97
  height: "20",
@@ -133,7 +134,7 @@ const AddSectionImageToLayout = ({ editorImageToLayout })=>{
133
134
  className: "gp-flex gp-items-center",
134
135
  children: /*#__PURE__*/ jsx("span", {
135
136
  className: "gp-mr-[3px] gp-text-center gp-text-[12px] gp-font-normal gp-text-[#676767]",
136
- children: action.content
137
+ children: t(action.content)
137
138
  })
138
139
  })
139
140
  ]
@@ -1,7 +1,15 @@
1
1
  'use client';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useI18n, useShopStore } from '@gem-sdk/core';
3
4
 
5
+ const SALE_FUNNEL_PAGE_TYPES = [
6
+ 'GP_FUNNEL_PAGE',
7
+ 'GP_PRE_SALE_PAGE'
8
+ ];
4
9
  const DropElement = ()=>{
10
+ const { t } = useI18n();
11
+ const editingPageType = useShopStore((s)=>s.pageType);
12
+ const isFunnelSalesPage = SALE_FUNNEL_PAGE_TYPES.includes(editingPageType || '');
5
13
  const dispatchEventBuildWithSectionActiveTab = (value)=>{
6
14
  const event = new CustomEvent('editor:sidebar:build-with-section-active-tab', {
7
15
  bubbles: true,
@@ -11,6 +19,15 @@ const DropElement = ()=>{
11
19
  });
12
20
  window.dispatchEvent(event);
13
21
  };
22
+ const dispatchEventBuildWithTemplateActiveTab = (value)=>{
23
+ const event = new CustomEvent('editor:sidebar:build-with-template-active-tab', {
24
+ bubbles: true,
25
+ detail: {
26
+ value
27
+ }
28
+ });
29
+ window.dispatchEvent(event);
30
+ };
14
31
  const handleClickGenerate = (e)=>{
15
32
  const event = new CustomEvent('editor:sidebar:click-img-to-layout-gallery-btn', e);
16
33
  window.dispatchEvent(event);
@@ -99,22 +116,30 @@ const DropElement = ()=>{
99
116
  children: [
100
117
  /*#__PURE__*/ jsx("div", {
101
118
  className: "gp-text-16 gp-font-medium gp-mb-4 gp-text-[#212121]",
102
- children: "Start with Sections from sidebar"
119
+ children: isFunnelSalesPage ? t('Start building with Sections/Elements or') : t('Start with Sections from sidebar')
103
120
  }),
104
121
  /*#__PURE__*/ jsxs("div", {
105
- className: "gp-flex gp-w-[291px] gp-justify-between",
122
+ className: "gp-flex gp-gap-3 gp-justify-between",
106
123
  children: [
107
124
  /*#__PURE__*/ jsx("button", {
108
125
  "data-button-add-section": true,
109
- onClick: ()=>dispatchEventBuildWithSectionActiveTab(true),
110
- className: "gp-flex gp-h-[40px] gp-w-[136px] gp-items-center gp-font-medium gp-justify-center gp-rounded-[8px] gp-bg-[#1C1C1C] gp-text-[14px] gp-text-white hover:gp-bg-[#3B3B3B]",
111
- children: "Add sections"
126
+ onClick: ()=>{
127
+ if (isFunnelSalesPage) {
128
+ dispatchEventBuildWithTemplateActiveTab('funnelExisting');
129
+ } else dispatchEventBuildWithSectionActiveTab(true);
130
+ },
131
+ className: "gp-flex gp-h-[40px] gp-px-6 gp-items-center gp-font-medium gp-justify-center gp-rounded-[8px] gp-bg-[#1C1C1C] gp-text-[14px] gp-text-white hover:gp-bg-[#3B3B3B]",
132
+ children: isFunnelSalesPage ? t('Use existing page designs') : t('Add sections')
112
133
  }),
113
134
  /*#__PURE__*/ jsx("button", {
114
135
  "data-button-add-elements": true,
115
- onClick: ()=>dispatchEventBuildWithSectionActiveTab(false),
116
- className: "gp-flex gp-h-[40px] gp-w-[136px] gp-items-center gp-font-medium gp-justify-center gp-rounded-[8px] gp-bg-[#f4f4f4] gp-text-[14px] gp-text-[#212121] hover:gp-bg-[#E2E2E2]",
117
- children: "Add elements"
136
+ onClick: ()=>{
137
+ if (isFunnelSalesPage) {
138
+ dispatchEventBuildWithTemplateActiveTab('templates');
139
+ } else dispatchEventBuildWithSectionActiveTab(false);
140
+ },
141
+ className: "gp-flex gp-h-[40px] gp-px-6 gp-items-center gp-font-medium gp-justify-center gp-rounded-[8px] gp-bg-[#f4f4f4] gp-text-[14px] gp-text-[#212121] hover:gp-bg-[#E2E2E2]",
142
+ children: isFunnelSalesPage ? t('Explore templates') : t('Add elements')
118
143
  })
119
144
  ]
120
145
  }),
@@ -153,7 +178,7 @@ const DropElement = ()=>{
153
178
  "aria-hidden": "true",
154
179
  id: "gp-img-to-layout-gallery-btn",
155
180
  className: "gp-relative gp-cursor-pointer gp-text-[14px] gp-font-medium gp-text-[#3C67FF]",
156
- children: "Start with Generating from URL or image"
181
+ children: t('Start with Generating from URL or image')
157
182
  })
158
183
  })
159
184
  ]
@@ -0,0 +1,15 @@
1
+ var PublishedThemePageMetafields;
2
+ (function(PublishedThemePageMetafields) {
3
+ PublishedThemePageMetafields["CUSTOM_CODE_HEADER"] = 'custom_code_header';
4
+ PublishedThemePageMetafields["CUSTOM_CODE_BODY"] = 'custom_code_body';
5
+ PublishedThemePageMetafields["ANALYTICS_GA_TRACKING_ID"] = 'analytics_ga_tracking_id';
6
+ PublishedThemePageMetafields["ANALYTICS_FB_PIXEL_ID"] = 'analytics_fb_pixel_id';
7
+ PublishedThemePageMetafields["ANALYTICS_TIKTOK_PIXEL_ID"] = 'analytics_tiktok_pixel_id';
8
+ PublishedThemePageMetafields["GLOBAL_META_DESCRIPTION"] = 'global-meta-description';
9
+ PublishedThemePageMetafields["GLOBAL_META_TITLE"] = 'global-meta-title';
10
+ PublishedThemePageMetafields["GLOBAL_META_THUMBNAIL"] = 'global-meta-thumbnail';
11
+ PublishedThemePageMetafields["NOINDEX_KEY"] = 'noindex';
12
+ PublishedThemePageMetafields["NOFOLLOW_KEY"] = 'nofollow';
13
+ })(PublishedThemePageMetafields || (PublishedThemePageMetafields = {}));
14
+
15
+ export { PublishedThemePageMetafields };
@@ -1,4 +1,4 @@
1
- import { PublishedThemePagesDocument, StorePropertyDocument } from '@gem-sdk/core';
1
+ import { PublishedThemePagesDocument, StorePropertyDocument, PublishedShopMetasDocument } from '@gem-sdk/core';
2
2
  import { ShopMetaDocument } from '@gem-sdk/adapter-shopify';
3
3
  import { getFontStyleFromPageTemplate, getFontFromGlobalStyle } from '../google-fonts.js';
4
4
  import { genCSS } from '../helpers/gen-css.js';
@@ -7,13 +7,15 @@ import { getFallbackV2 } from '../helpers/get-fallback.js';
7
7
  import { parseBuilderTemplateV2 } from '../helpers/normalize.js';
8
8
  import { parseJson, serializableJson } from '../helpers/parse-json.js';
9
9
  import { captureException } from '@sentry/nextjs';
10
+ import { PublishedThemePageMetafields } from '../../constants/index.js';
11
+ import { getPublishedThemePageMetafieldByKey } from '../helpers/get-metafield.js';
10
12
 
11
13
  const getHomePagePropsV2 = (fetcher, shopifyFetcher)=>async ()=>{
12
14
  try {
13
15
  const variables = {
14
16
  slugType: 'STATIC'
15
17
  };
16
- const [theme, storeProperty, shopifyMeta] = await Promise.allSettled([
18
+ const [theme, storeProperty, shopifyMeta, publishedShopMetas] = await Promise.allSettled([
17
19
  fetcher([
18
20
  PublishedThemePagesDocument,
19
21
  variables
@@ -23,11 +25,21 @@ const getHomePagePropsV2 = (fetcher, shopifyFetcher)=>async ()=>{
23
25
  ]),
24
26
  shopifyFetcher([
25
27
  ShopMetaDocument
28
+ ]),
29
+ fetcher([
30
+ PublishedShopMetasDocument,
31
+ {
32
+ keys: [
33
+ PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION,
34
+ PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL
35
+ ]
36
+ }
26
37
  ])
27
38
  ]);
28
39
  if (theme.status === 'rejected') {
29
40
  throw new Error(theme.reason?.[0]);
30
41
  }
42
+ const publishedShopMetaValue = publishedShopMetas.status === 'fulfilled' ? publishedShopMetas.value : undefined;
31
43
  const dataBuilder = theme.value?.publishedThemePages?.[0];
32
44
  if (!dataBuilder) {
33
45
  throw new Error(`No data builder found for Home page`);
@@ -39,8 +51,8 @@ const getHomePagePropsV2 = (fetcher, shopifyFetcher)=>async ()=>{
39
51
  getFallbackV2(fetcher, homeTemplate)
40
52
  ]);
41
53
  const mobileOnly = dataBuilder.isMobile ?? false;
42
- const description = dataBuilder?.themePageDataSEO?.find((item)=>item?.key === 'global-meta-description')?.value;
43
- const thumbnail = parseJson(dataBuilder?.themePageDataSEO?.find((item)=>item?.key === 'global-meta-thumbnail')?.value);
54
+ const description = getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION)?.value;
55
+ const thumbnail = parseJson(getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL)?.value);
44
56
  const shopMeta = shopifyMeta.status === 'fulfilled' ? shopifyMeta.value : undefined;
45
57
  const shopData = storeProperty.status === 'fulfilled' ? storeProperty.value : undefined;
46
58
  const favicon = shopData?.storeProperty?.favicon ?? '/favicon/favicon-32x32.png';
@@ -127,11 +139,11 @@ const getHomePagePropsV2 = (fetcher, shopifyFetcher)=>async ()=>{
127
139
  swatches: parseJson(shopData?.storeProperty?.swatchesConfig),
128
140
  seo,
129
141
  mobileOnly,
130
- gaTrackingId: dataBuilder.themePageAnalytic?.gaTrackingID ?? null,
131
- facebookPixelId: dataBuilder.themePageAnalytic?.fbPixelID ?? null,
132
- tiktokPixelId: dataBuilder.themePageAnalytic?.tiktokPixelID ?? null,
133
- customCodeHeader: dataBuilder.themePageCustomCode?.header ?? null,
134
- customCodeBody: dataBuilder.themePageCustomCode?.body ?? null,
142
+ gaTrackingId: getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.ANALYTICS_GA_TRACKING_ID, dataBuilder?.metafields) ?? null,
143
+ facebookPixelId: getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.ANALYTICS_FB_PIXEL_ID, dataBuilder?.metafields) ?? null,
144
+ tiktokPixelId: getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.ANALYTICS_TIKTOK_PIXEL_ID, dataBuilder?.metafields) ?? null,
145
+ customCodeHeader: getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.CUSTOM_CODE_HEADER, dataBuilder?.metafields) ?? null,
146
+ customCodeBody: getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.CUSTOM_CODE_BODY, dataBuilder?.metafields) ?? null,
135
147
  pageHandle: dataBuilder.handle ?? null
136
148
  });
137
149
  } catch (err) {
@@ -1,10 +1,12 @@
1
- import { PublishedThemePagesDocument, StorePropertyDocument, prefetchQueries } from '@gem-sdk/core';
1
+ import { PublishedThemePagesDocument, StorePropertyDocument, PublishedShopMetasDocument, prefetchQueries } from '@gem-sdk/core';
2
2
  import { ShopMetaDocument } from '@gem-sdk/adapter-shopify';
3
3
  import { getFontFromGlobalStyle } from '../google-fonts.js';
4
4
  import { genCSS } from '../helpers/gen-css.js';
5
5
  import { generateManifest } from '../helpers/generate-manifres.js';
6
6
  import { parseBuilderTemplate } from '../helpers/normalize.js';
7
7
  import { parseJson, serializableJson } from '../helpers/parse-json.js';
8
+ import { PublishedThemePageMetafields } from '../../constants/index.js';
9
+ import { getPublishedThemePageMetafieldByKey } from '../helpers/get-metafield.js';
8
10
 
9
11
  const getHomePageProps = (fetcher, shopifyFetcher)=>async ()=>{
10
12
  const pageType = 'STATIC';
@@ -15,7 +17,7 @@ const getHomePageProps = (fetcher, shopifyFetcher)=>async ()=>{
15
17
  // PublishedThemePagesDocument,
16
18
  // variables,
17
19
  // ]);
18
- const [theme, storeProperty, shopifyMeta] = await Promise.allSettled([
20
+ const [theme, storeProperty, shopifyMeta, publishedShopMetas] = await Promise.allSettled([
19
21
  fetcher([
20
22
  PublishedThemePagesDocument,
21
23
  variables
@@ -25,6 +27,15 @@ const getHomePageProps = (fetcher, shopifyFetcher)=>async ()=>{
25
27
  ]),
26
28
  shopifyFetcher([
27
29
  ShopMetaDocument
30
+ ]),
31
+ fetcher([
32
+ PublishedShopMetasDocument,
33
+ {
34
+ keys: [
35
+ PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION,
36
+ PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL
37
+ ]
38
+ }
28
39
  ])
29
40
  ]);
30
41
  if (theme.status === 'rejected') {
@@ -32,6 +43,7 @@ const getHomePageProps = (fetcher, shopifyFetcher)=>async ()=>{
32
43
  pageType
33
44
  };
34
45
  }
46
+ const publishedShopMetaValue = publishedShopMetas.status === 'fulfilled' ? publishedShopMetas.value : undefined;
35
47
  const dataBuilder = theme.value.publishedThemePages?.[0];
36
48
  const homeTemplate = parseBuilderTemplate(dataBuilder);
37
49
  const fontStyle = await getFontFromGlobalStyle(dataBuilder?.pageStyle?.data);
@@ -56,8 +68,8 @@ const getHomePageProps = (fetcher, shopifyFetcher)=>async ()=>{
56
68
  }
57
69
  return acc;
58
70
  }, {});
59
- const description = dataBuilder?.themePageDataSEO?.find((item)=>item?.key === 'global-meta-description')?.value;
60
- const thumbnail = parseJson(dataBuilder?.themePageDataSEO?.find((item)=>item?.key === 'global-meta-thumbnail')?.value);
71
+ const description = getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION)?.value;
72
+ const thumbnail = parseJson(getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL)?.value);
61
73
  const shopMeta = shopifyMeta.status === 'fulfilled' ? shopifyMeta.value : undefined;
62
74
  const shopData = storeProperty.status === 'fulfilled' ? storeProperty.value : undefined;
63
75
  const favicon = shopData?.storeProperty?.favicon ?? '/favicon/favicon-32x32.png';
@@ -1,4 +1,4 @@
1
- import { ThemePageDocument, StorePropertyDocument, SaleFunnelDiscountsDocument, LibraryTemplateDocument, LibrarySaleFunnelDocument, ShopLibraryPageDocument } from '@gem-sdk/core';
1
+ import { ThemePageDocument, StorePropertyDocument, SaleFunnelDiscountsDocument, SaleFunnelOfferDocument, LibraryTemplateDocument, LibrarySaleFunnelDocument, ShopLibraryPageDocument } from '@gem-sdk/core';
2
2
  import { captureException } from '@sentry/nextjs';
3
3
  import { getFontStyleFromPageTemplate, getFontFromGlobalStyle } from '../google-fonts.js';
4
4
  import { getFallbackV2 } from '../helpers/get-fallback.js';
@@ -31,6 +31,7 @@ const fetchSalePageDataByID = async (data, fetcher)=>{
31
31
  dataBuilder: theme.value.themePage,
32
32
  pageStyle: theme.value.themePage?.theme?.themeStyles?.edges?.[0]?.node?.data,
33
33
  storeProperty,
34
+ dynamicDiscountOffer: undefined,
34
35
  productOffers: []
35
36
  };
36
37
  };
@@ -42,7 +43,7 @@ const fetchPostPurchasePageDataByID = async (data, fetcher)=>{
42
43
  default: true
43
44
  }
44
45
  };
45
- const [theme, storeProperty, saleFunnelDiscounts] = await Promise.allSettled([
46
+ const [theme, storeProperty, saleFunnelDiscounts, saleFunnelOffer] = await Promise.allSettled([
46
47
  fetcher([
47
48
  ThemePageDocument,
48
49
  variables
@@ -57,6 +58,12 @@ const fetchPostPurchasePageDataByID = async (data, fetcher)=>{
57
58
  saleFunnelOfferID: data.currentOfferID
58
59
  }
59
60
  }
61
+ ]),
62
+ fetcher([
63
+ SaleFunnelOfferDocument,
64
+ {
65
+ saleFunnelOfferId: data.currentOfferID
66
+ }
60
67
  ])
61
68
  ]);
62
69
  if (theme.status === 'rejected') {
@@ -65,10 +72,14 @@ const fetchPostPurchasePageDataByID = async (data, fetcher)=>{
65
72
  if (saleFunnelDiscounts.status === 'rejected') {
66
73
  throw new Error(saleFunnelDiscounts.reason?.[0]);
67
74
  }
75
+ if (saleFunnelOffer.status === 'rejected') {
76
+ throw new Error(saleFunnelOffer.reason?.[0]);
77
+ }
68
78
  return {
69
79
  dataBuilder: theme.value.themePage,
70
80
  pageStyle: theme.value.themePage?.theme?.themeStyles?.edges?.[0]?.node?.data,
71
81
  storeProperty,
82
+ dynamicDiscountOffer: saleFunnelOffer.value.saleFunnelOffer?.dynamicDiscounts?.[0],
72
83
  productOffers: saleFunnelDiscounts.value.saleFunnelDiscounts?.edges?.filter((item)=>item?.node?.objectType === 'PRODUCT' && item?.node?.type === 'ORDER_VALUE') || []
73
84
  };
74
85
  };
@@ -114,6 +125,7 @@ const fetchThemePageDataByTemplateID = async (data, fetcher)=>{
114
125
  dataBuilder: theme.value.libraryTemplate,
115
126
  pageStyle: undefined,
116
127
  storeProperty,
128
+ dynamicDiscountOffer: undefined,
117
129
  productOffers: productOffers
118
130
  };
119
131
  };
@@ -121,7 +133,7 @@ const fetchShopLibraryPageDataByID = async (data, fetcher)=>{
121
133
  const variables = {
122
134
  shopLibraryPageId: data.shopLibraryPageId
123
135
  };
124
- const [theme, storeProperty, saleFunnelDiscounts] = await Promise.allSettled([
136
+ const [theme, storeProperty, saleFunnelDiscounts, saleFunnelOffer] = await Promise.allSettled([
125
137
  fetcher([
126
138
  ShopLibraryPageDocument,
127
139
  variables
@@ -136,6 +148,12 @@ const fetchShopLibraryPageDataByID = async (data, fetcher)=>{
136
148
  saleFunnelOfferID: data.currentOfferID
137
149
  }
138
150
  }
151
+ ]),
152
+ fetcher([
153
+ SaleFunnelOfferDocument,
154
+ {
155
+ saleFunnelOfferId: data.currentOfferID
156
+ }
139
157
  ])
140
158
  ]);
141
159
  if (theme.status === 'rejected') {
@@ -144,10 +162,14 @@ const fetchShopLibraryPageDataByID = async (data, fetcher)=>{
144
162
  if (saleFunnelDiscounts.status === 'rejected') {
145
163
  throw new Error(saleFunnelDiscounts.reason?.[0]);
146
164
  }
165
+ if (saleFunnelOffer.status === 'rejected') {
166
+ throw new Error(saleFunnelOffer.reason?.[0]);
167
+ }
147
168
  return {
148
169
  dataBuilder: theme.value.shopLibraryPage,
149
170
  pageStyle: undefined,
150
171
  storeProperty,
172
+ dynamicDiscountOffer: saleFunnelOffer.value.saleFunnelOffer?.dynamicDiscounts?.[0],
151
173
  productOffers: saleFunnelDiscounts.value.saleFunnelDiscounts?.edges?.filter((item)=>item?.node?.objectType === 'PRODUCT' && item?.node?.type === 'ORDER_VALUE') || []
152
174
  };
153
175
  };
@@ -155,7 +177,7 @@ const fetchLibraryTemplateDataByID = async (data, fetcher)=>{
155
177
  const variables = {
156
178
  libraryTemplateId: data.libraryTemplateId
157
179
  };
158
- const [theme, storeProperty, saleFunnelDiscounts] = await Promise.allSettled([
180
+ const [theme, storeProperty, saleFunnelDiscounts, saleFunnelOffer] = await Promise.allSettled([
159
181
  fetcher([
160
182
  LibraryTemplateDocument,
161
183
  variables
@@ -170,6 +192,12 @@ const fetchLibraryTemplateDataByID = async (data, fetcher)=>{
170
192
  saleFunnelOfferID: data.currentOfferID
171
193
  }
172
194
  }
195
+ ]),
196
+ fetcher([
197
+ SaleFunnelOfferDocument,
198
+ {
199
+ saleFunnelOfferId: data.currentOfferID
200
+ }
173
201
  ])
174
202
  ]);
175
203
  if (theme.status === 'rejected') {
@@ -178,10 +206,14 @@ const fetchLibraryTemplateDataByID = async (data, fetcher)=>{
178
206
  if (saleFunnelDiscounts.status === 'rejected') {
179
207
  throw new Error(saleFunnelDiscounts.reason?.[0]);
180
208
  }
209
+ if (saleFunnelOffer.status === 'rejected') {
210
+ throw new Error(saleFunnelOffer.reason?.[0]);
211
+ }
181
212
  return {
182
213
  dataBuilder: theme.value.libraryTemplate,
183
214
  pageStyle: undefined,
184
215
  storeProperty,
216
+ dynamicDiscountOffer: saleFunnelOffer.value.saleFunnelOffer?.dynamicDiscounts?.[0],
185
217
  productOffers: saleFunnelDiscounts.value.saleFunnelDiscounts?.edges?.filter((item)=>item?.node?.objectType === 'PRODUCT' && item?.node?.type === 'ORDER_VALUE') || []
186
218
  };
187
219
  };
@@ -219,7 +251,7 @@ const getRelevantPageData = async (data)=>{
219
251
  const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFetcher)=>async (data)=>{
220
252
  try {
221
253
  const { id, currentOfferID, isLibraryTemplate, isShopLibraryPage } = data;
222
- const { dataBuilder, storeProperty, productOffers, pageStyle } = await getRelevantPageData({
254
+ const { dataBuilder, storeProperty, productOffers, pageStyle, dynamicDiscountOffer } = await getRelevantPageData({
223
255
  id,
224
256
  currentOfferID,
225
257
  fetcher,
@@ -248,7 +280,8 @@ const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFet
248
280
  swr: {
249
281
  fallback
250
282
  },
251
- productOffers
283
+ productOffers,
284
+ dynamicDiscountOffer
252
285
  });
253
286
  } catch (err) {
254
287
  console.log('error', err);
@@ -8,6 +8,7 @@ import { getFallbackV2 } from '../helpers/get-fallback.js';
8
8
  import { parseBuilderTemplateV2, extractPageBackground } from '../helpers/normalize.js';
9
9
  import { parseJson, serializableJson } from '../helpers/parse-json.js';
10
10
  import { getCustomFonts } from '../custom-fonts.js';
11
+ import { sentryCaptureException } from '../helpers/sentry.js';
11
12
 
12
13
  const getStaticPagePropsPreview = (fetcher, shopifyFetcher)=>async (slug)=>{
13
14
  try {
@@ -29,6 +30,10 @@ const getStaticPagePropsPreview = (fetcher, shopifyFetcher)=>async (slug)=>{
29
30
  ])
30
31
  ]);
31
32
  if (theme.status === 'rejected') {
33
+ sentryCaptureException('PreviewThemePageDocument', theme.reason, {
34
+ variables,
35
+ theme
36
+ });
32
37
  throw new Error(theme.reason?.[0]);
33
38
  }
34
39
  const dataBuilder = theme.value.previewThemePage;