@gem-sdk/pages 2.0.0-staging.159 → 2.0.0-staging.711

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 (52) 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 +17 -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 +3 -0
  10. package/dist/cjs/libs/api/get-static-page-props-preview.js +5 -0
  11. package/dist/cjs/libs/api/get-static-page-props-v2.js +7 -2
  12. package/dist/cjs/libs/google-fonts.js +25 -5
  13. package/dist/cjs/libs/helpers/gen-fonts.js +9 -3
  14. package/dist/cjs/libs/helpers/normalize.js +2 -1
  15. package/dist/cjs/libs/helpers/parse-json.js +1 -1
  16. package/dist/cjs/libs/helpers/sentry.js +17 -0
  17. package/dist/cjs/pages/404.js +1 -0
  18. package/dist/cjs/pages/500.js +1 -0
  19. package/dist/cjs/pages/CollectionGlobalProvider.js +1 -0
  20. package/dist/cjs/pages/builder.js +46 -41
  21. package/dist/cjs/pages/collection-detail.js +1 -0
  22. package/dist/cjs/pages/preview.js +1 -0
  23. package/dist/cjs/pages/product-detail.js +1 -0
  24. package/dist/cjs/pages/static-v2.js +20 -16
  25. package/dist/cjs/pages/static.js +1 -0
  26. package/dist/esm/components/FooterForPostPurchase.js +1 -1
  27. package/dist/esm/components/builder/Footer.js +2 -2
  28. package/dist/esm/components/builder/Header.js +1 -2
  29. package/dist/esm/components/builder/Toolbar.js +6 -0
  30. package/dist/esm/components/builder/Toolbox.js +17 -14
  31. package/dist/esm/components/composable/getListFontWeightTypos.js +12 -0
  32. package/dist/esm/components/image-to-layout/AddSectionImageToLayout.js +6 -5
  33. package/dist/esm/components/image-to-layout/DropElement.js +34 -9
  34. package/dist/esm/constants/index.js +3 -0
  35. package/dist/esm/libs/api/get-static-page-props-preview.js +5 -0
  36. package/dist/esm/libs/api/get-static-page-props-v2.js +7 -2
  37. package/dist/esm/libs/google-fonts.js +25 -5
  38. package/dist/esm/libs/helpers/gen-fonts.js +9 -3
  39. package/dist/esm/libs/helpers/normalize.js +2 -1
  40. package/dist/esm/libs/helpers/parse-json.js +1 -1
  41. package/dist/esm/libs/helpers/sentry.js +15 -0
  42. package/dist/esm/pages/404.js +1 -0
  43. package/dist/esm/pages/500.js +1 -0
  44. package/dist/esm/pages/CollectionGlobalProvider.js +1 -0
  45. package/dist/esm/pages/builder.js +47 -42
  46. package/dist/esm/pages/collection-detail.js +1 -0
  47. package/dist/esm/pages/preview.js +1 -0
  48. package/dist/esm/pages/product-detail.js +1 -0
  49. package/dist/esm/pages/static-v2.js +21 -17
  50. package/dist/esm/pages/static.js +1 -0
  51. package/dist/types/index.d.ts +63 -57
  52. package/package.json +6 -6
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  'use strict';
2
3
 
3
4
  var jsxRuntime = require('react/jsx-runtime');
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  'use strict';
2
3
 
3
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -14,6 +14,7 @@ var react = require('react');
14
14
 
15
15
  const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, customFonts, isPostPurchase, shopName, productOffers, publicStoreFrontData, dynamicDiscountOffer, isPreview, interaction, pageBackground })=>{
16
16
  const router$1 = router.useRouter();
17
+ const { t } = core.useI18n();
17
18
  const baseAssetURL = process.env.NEXT_GP_BASE_ASSET_URL || 'https://d3kbi0je7pp4lw.cloudfront.net';
18
19
  useTrackingView.useTrackingView(shopToken, pageHandle, router$1.isFallback);
19
20
  const customCodeHeaderID = 'custom-code-header';
@@ -109,22 +110,25 @@ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, f
109
110
  }),
110
111
  /*#__PURE__*/ jsxRuntime.jsx(core.SectionProvider, {
111
112
  data: sectionData,
112
- children: builderData?.map((builder)=>/*#__PURE__*/ jsxRuntime.jsxs(core.BuilderProvider, {
113
- state: builder.data,
114
- lazy: builder.lazy,
115
- priority: builder.priority,
116
- isPostPurchase: isPostPurchase,
117
- isPreview: isPreview,
118
- children: [
119
- /*#__PURE__*/ jsxRuntime.jsx(core.Render, {
120
- uid: builder.uid
121
- }),
122
- hasInteraction && /*#__PURE__*/ jsxRuntime.jsx(Script, {
123
- defer: true,
124
- src: `${baseAssetURL}/assets-v2/gp-flow-action-lip.js`
125
- })
126
- ]
127
- }, builder.uid))
113
+ children: /*#__PURE__*/ jsxRuntime.jsx(core.I18nProvider, {
114
+ t: t,
115
+ children: builderData?.map((builder)=>/*#__PURE__*/ jsxRuntime.jsxs(core.BuilderProvider, {
116
+ state: builder.data,
117
+ lazy: builder.lazy,
118
+ priority: builder.priority,
119
+ isPostPurchase: isPostPurchase,
120
+ isPreview: isPreview,
121
+ children: [
122
+ /*#__PURE__*/ jsxRuntime.jsx(core.Render, {
123
+ uid: builder.uid
124
+ }),
125
+ hasInteraction && /*#__PURE__*/ jsxRuntime.jsx(Script, {
126
+ defer: true,
127
+ src: `${baseAssetURL}/assets-v2/gp-flow-action-lip.js`
128
+ })
129
+ ]
130
+ }, builder.uid))
131
+ })
128
132
  }),
129
133
  isPostPurchase && /*#__PURE__*/ jsxRuntime.jsx(FooterForPostPurchase.default, {
130
134
  shopName: shopName || ''
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  'use strict';
2
3
 
3
4
  Object.defineProperty(exports, '__esModule', { value: true });
@@ -9,7 +9,7 @@ const defaultMargin = {
9
9
  };
10
10
  const FooterForPostPurchase = (props)=>{
11
11
  return /*#__PURE__*/ jsx("div", {
12
- className: cls('gp-footer-container gp-border-1 gp-group gp-flex gp-justify-center gp-border-y gp-border-[#EEEEEE] gp-bg-white gp-font-sans'),
12
+ className: cls('gp-footer-container gp-border-1 gp-group gp-flex gp-justify-center gp-border-y gp-border-[#EEEEEE] gp-font-sans'),
13
13
  children: /*#__PURE__*/ jsx("div", {
14
14
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between gp-py-6",
15
15
  style: {
@@ -41,7 +41,7 @@ const Footer = (props)=>{
41
41
  ]);
42
42
  return /*#__PURE__*/ jsx(Fragment, {
43
43
  children: pageType === 'POST_PURCHASE' ? /*#__PURE__*/ jsx("div", {
44
- className: cls('gp-footer-container gp-border-1 gp-group gp-flex gp-justify-center gp-border-y gp-border-[#EEEEEE] gp-bg-white gp-font-sans'),
44
+ className: cls('gp-footer-container gp-border-1 gp-group gp-flex gp-justify-center gp-border-y gp-border-[#EEEEEE] gp-font-sans'),
45
45
  children: /*#__PURE__*/ jsx("div", {
46
46
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between gp-py-6",
47
47
  style: {
@@ -58,7 +58,7 @@ const Footer = (props)=>{
58
58
  })
59
59
  })
60
60
  }) : /*#__PURE__*/ jsx("div", {
61
- className: cls('gp-footer-container gp-border-1 gp-group gp-flex gp-justify-center gp-border-y gp-border-[#EEEEEE] gp-bg-white gp-font-sans', {
61
+ className: cls('gp-footer-container gp-border-1 gp-group gp-flex gp-justify-center gp-border-y gp-border-[#EEEEEE gp-font-sans', {
62
62
  'gp-fixed gp-bottom-0 gp-w-full': shouldFixed
63
63
  }),
64
64
  children: /*#__PURE__*/ jsxs("div", {
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
- import { useShopStore, usePageStore, cls, makeStyleResponsive } from '@gem-sdk/core';
3
+ import { useShopStore, cls, makeStyleResponsive } from '@gem-sdk/core';
4
4
  import Devices from './SwitchView.js';
5
5
 
6
6
  const defaultMargin = {
@@ -18,7 +18,6 @@ const sizeCheck = {
18
18
  const Header = (props)=>{
19
19
  const { pageType, isOriginTemplate, openPageSetting } = props;
20
20
  const layoutSetting = useShopStore((s)=>s.layoutSettings);
21
- usePageStore((s)=>s.sidebarMode);
22
21
  const activeHeader = layoutSetting?.showHeader || isOriginTemplate;
23
22
  const headerColor = activeHeader ? HEADER_ON_COLOR : HEADER_OFF_COLOR;
24
23
  return /*#__PURE__*/ jsxs(Fragment, {
@@ -407,6 +407,7 @@ const Toolbar = ()=>{
407
407
  if (!value || !currentComponentActive.current) {
408
408
  return;
409
409
  }
410
+ let isClickProcessing = false;
410
411
  const selector = getSelectorComponent({
411
412
  ...currentComponentActive.current
412
413
  });
@@ -415,6 +416,7 @@ const Toolbar = ()=>{
415
416
  const $parents = $component?.querySelectorAll('[data-toolbar-parent]');
416
417
  if ($parents.length) {
417
418
  const onHover = ($parent)=>{
419
+ if (isClickProcessing) return;
418
420
  const uid = $parent.getAttribute('data-parent-uid');
419
421
  if (!uid) return;
420
422
  const $parentComponents = document.body.querySelector('#storefront')?.querySelectorAll(`[data-uid="${uid}"]`);
@@ -443,6 +445,7 @@ const Toolbar = ()=>{
443
445
  }
444
446
  };
445
447
  const onClick = async ($parent)=>{
448
+ isClickProcessing = true;
446
449
  const uid = $parent.getAttribute('data-parent-uid');
447
450
  if (!uid) return;
448
451
  const isElementInsideProduct = async ()=>{
@@ -474,6 +477,9 @@ const Toolbar = ()=>{
474
477
  });
475
478
  outHover($parent);
476
479
  window.dispatchEvent(event);
480
+ setTimeout(()=>{
481
+ isClickProcessing = false;
482
+ }, 0);
477
483
  };
478
484
  $parents.forEach(($parent)=>{
479
485
  $parent.addEventListener('mouseover', ()=>onHover($parent));
@@ -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 = ()=>{
@@ -35,7 +36,7 @@ const Toolbox = ()=>{
35
36
  const changeLayoutSettings = useShopStore((s)=>s.changeLayoutSettings);
36
37
  const changeCreateThemeSectionCount = useShopStore((s)=>s.changeCreateThemeSectionCount);
37
38
  const changeShopPlan = useShopStore((s)=>s.changeShopPlan);
38
- const changeShopifyPlan = useShopStore((s)=>s.changeShopifyPlan);
39
+ const updatePriceWithCurrency = useShopStore((s)=>s.updatePriceWithCurrency);
39
40
  const changeFontType = libsStore((s)=>s.changeFontType);
40
41
  const fontType = libsStore((s)=>s.fontType);
41
42
  const clearModal = useModalStore((s)=>s.clearModal);
@@ -134,9 +135,11 @@ const Toolbox = ()=>{
134
135
  try {
135
136
  if (detail.data) {
136
137
  const themeStyle = genCSS(detail.data, detail.mobileOnly);
137
- const font = Object.entries(detail.data?.font).map(([, value])=>{
138
- return value;
139
- }).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)=>{
140
143
  if (item.type == 'custom') {
141
144
  const isGoogleFont = shopifyCdnWithGoogleFonts.find((ggFont)=>ggFont.family == item.family);
142
145
  if (isGoogleFont) {
@@ -293,12 +296,12 @@ const Toolbox = ()=>{
293
296
  }, [
294
297
  changeShopPlan
295
298
  ]);
296
- const onUpdateShopifyPlan = useCallback((e)=>{
297
- const shopifyPlan = e.detail;
298
- if (!shopifyPlan) return;
299
- changeShopifyPlan(shopifyPlan);
299
+ const onUpdatePriceWithCurrency = useCallback((e)=>{
300
+ const showPriceCurrency = e.detail;
301
+ if (!showPriceCurrency) return;
302
+ updatePriceWithCurrency(showPriceCurrency);
300
303
  }, [
301
- changeShopifyPlan
304
+ updatePriceWithCurrency
302
305
  ]);
303
306
  const onUpdateFontType = useCallback((e)=>{
304
307
  const fontType = e.detail;
@@ -424,7 +427,6 @@ const Toolbox = ()=>{
424
427
  window.addEventListener('on-off-header-footer', onChangeLayoutSettingData);
425
428
  window.addEventListener('update-create-theme-section-count', onUpdateCreateThemeSectionCount);
426
429
  window.addEventListener('update-shop-plan', onUpdateShopPlan);
427
- window.addEventListener('update-shopify-plan', onUpdateShopifyPlan);
428
430
  window.addEventListener('set-dynamic-product', onUpdateDynamicProduct);
429
431
  window.addEventListener('set-dynamic-collection', onUpdateDynamicCollection);
430
432
  window.addEventListener('update-item-name', onUpdateItemName);
@@ -438,6 +440,7 @@ const Toolbox = ()=>{
438
440
  window.addEventListener('update-interaction-setting-type', onUpdateInteractionSettingType);
439
441
  window.addEventListener('change-sidebar-mode', onChangeSidebarMode);
440
442
  window.addEventListener('update-font-type', onUpdateFontType);
443
+ window.addEventListener('update-price-with-currency', onUpdatePriceWithCurrency);
441
444
  return ()=>{
442
445
  window.removeEventListener('update-shop-info', onChangeShopInfo);
443
446
  window.removeEventListener('revalidate-query', onRevalidateQuery);
@@ -451,7 +454,7 @@ const Toolbox = ()=>{
451
454
  window.removeEventListener('on-off-header-footer', onChangeLayoutSettingData);
452
455
  window.removeEventListener('update-create-theme-section-count', onUpdateCreateThemeSectionCount);
453
456
  window.removeEventListener('update-shop-plan', onUpdateShopPlan);
454
- window.removeEventListener('update-shopify-plan', onUpdateShopifyPlan);
457
+ window.removeEventListener('update-price-with-currency', onUpdatePriceWithCurrency);
455
458
  window.removeEventListener('set-dynamic-product', onUpdateDynamicProduct);
456
459
  window.removeEventListener('set-dynamic-collection', onUpdateDynamicCollection);
457
460
  window.removeEventListener('update-item-name', onUpdateItemName);
@@ -467,7 +470,6 @@ const Toolbox = ()=>{
467
470
  }, [
468
471
  onAddEntity,
469
472
  onUpdateShopPlan,
470
- onUpdateShopifyPlan,
471
473
  onForceUpdateEntityProps,
472
474
  onUpdateEntityProp,
473
475
  onInitBuilder,
@@ -491,7 +493,8 @@ const Toolbox = ()=>{
491
493
  onUpdateInteractionSettingType,
492
494
  onUpdateFontType,
493
495
  onChangeSidebarMode,
494
- onUpdateDynamicDiscountOffer
496
+ onUpdateDynamicDiscountOffer,
497
+ onUpdatePriceWithCurrency
495
498
  ]);
496
499
  return /*#__PURE__*/ jsx("div", {
497
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
  ]
@@ -6,7 +6,10 @@ var PublishedThemePageMetafields;
6
6
  PublishedThemePageMetafields["ANALYTICS_FB_PIXEL_ID"] = 'analytics_fb_pixel_id';
7
7
  PublishedThemePageMetafields["ANALYTICS_TIKTOK_PIXEL_ID"] = 'analytics_tiktok_pixel_id';
8
8
  PublishedThemePageMetafields["GLOBAL_META_DESCRIPTION"] = 'global-meta-description';
9
+ PublishedThemePageMetafields["GLOBAL_META_TITLE"] = 'global-meta-title';
9
10
  PublishedThemePageMetafields["GLOBAL_META_THUMBNAIL"] = 'global-meta-thumbnail';
11
+ PublishedThemePageMetafields["NOINDEX_KEY"] = 'noindex';
12
+ PublishedThemePageMetafields["NOFOLLOW_KEY"] = 'nofollow';
10
13
  })(PublishedThemePageMetafields || (PublishedThemePageMetafields = {}));
11
14
 
12
15
  export { PublishedThemePageMetafields };
@@ -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;
@@ -59,23 +59,28 @@ const getStaticPagePropsV2 = (fetcher, shopifyFetcher)=>async (slug)=>{
59
59
  ]);
60
60
  const mobileOnly = dataBuilder.isMobile ?? false;
61
61
  const description = getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.GLOBAL_META_DESCRIPTION)?.value;
62
+ const title = getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.GLOBAL_META_TITLE, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.GLOBAL_META_TITLE)?.value;
62
63
  const thumbnail = parseJson(getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.GLOBAL_META_THUMBNAIL)?.value);
64
+ const noindex = getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.NOINDEX_KEY, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.NOINDEX_KEY)?.value;
65
+ const nofollow = getPublishedThemePageMetafieldByKey(PublishedThemePageMetafields.NOFOLLOW_KEY, dataBuilder?.metafields) || publishedShopMetaValue?.publishedShopMetas?.find((item)=>item?.key === PublishedThemePageMetafields.NOFOLLOW_KEY)?.value;
63
66
  const shopMeta = shopifyMeta.status === 'fulfilled' ? shopifyMeta.value : undefined;
64
67
  const shopData = storeProperty.status === 'fulfilled' ? storeProperty.value : undefined;
65
68
  const favicon = shopData?.storeProperty?.favicon ?? '/favicon/favicon-32x32.png';
66
69
  const seo = {
67
70
  defaultTitle: shopMeta?.shop.name,
68
- title: dataBuilder?.name,
71
+ title: title || dataBuilder?.name,
69
72
  description: description ?? shopMeta?.shop.description,
70
73
  openGraph: {
71
74
  site_name: shopMeta?.shop.name,
72
75
  locale: shopMeta?.localization.country.isoCode,
73
- title: dataBuilder?.name ?? shopMeta?.shop.name,
76
+ title: (title || dataBuilder?.name) ?? shopMeta?.shop.name,
74
77
  description: description ?? shopMeta?.shop.description,
75
78
  images: thumbnail ? [
76
79
  thumbnail
77
80
  ] : []
78
81
  },
82
+ noindex: noindex === 'true',
83
+ nofollow: nofollow === 'true',
79
84
  canonical: `https://${shopData?.storeProperty?.primaryDomain}/${slug}`,
80
85
  additionalMetaTags: [
81
86
  {
@@ -34,7 +34,27 @@ const composeFonts = (fonts)=>{
34
34
  };
35
35
  });
36
36
  };
37
- const createFontUrl = (fonts, option, fontType)=>{
37
+ const handleGenerateFontParams = (variants, fontType = 'google')=>{
38
+ const regularWeights = [];
39
+ if (!variants.length) {
40
+ return fontType === 'bunny' ? '400' : 'wght@400';
41
+ }
42
+ // Get regular weights and remove italic variants
43
+ variants.forEach((variant)=>{
44
+ if (typeof variant !== 'string' || variant?.includes('italic')) {
45
+ return;
46
+ }
47
+ const weight = variant === 'regular' ? '400' : variant;
48
+ regularWeights.push(weight);
49
+ });
50
+ // Sort weights numerically (ex: [900, 700, 400] -> [400, 700, 900])
51
+ const sortedRegularWeights = regularWeights.sort((a, b)=>Number(a) - Number(b));
52
+ // Build the variant string with only regular weights
53
+ const axisPrefix = 'wght@';
54
+ const listVariantsGoogleFonts = sortedRegularWeights.map((weight)=>weight);
55
+ return fontType === 'google' ? `${axisPrefix}${listVariantsGoogleFonts.join(';')}` : sortedRegularWeights.join(',');
56
+ };
57
+ const createFontUrl = (fonts, option, fontType = 'google')=>{
38
58
  const mainFonts = fonts.filter((font)=>{
39
59
  return !([
40
60
  'bunny',
@@ -48,8 +68,8 @@ const createFontUrl = (fonts, option, fontType)=>{
48
68
  return index === arr.findIndex((t)=>t.family === font.family);
49
69
  });
50
70
  const family = composeFonts(uniqFonts).map((font)=>{
51
- return `${font.family.replace(/ /g, '+')}:${font.variants.join(',')}`;
52
- }).join('|');
71
+ return `${font.family.replace(/ /g, '+')}:${handleGenerateFontParams(font.variants, fontType)}`;
72
+ }).join(fontType === 'google' ? '&family=' : '|');
53
73
  params.append('family', family);
54
74
  params.append('display', display);
55
75
  if (option?.subset) {
@@ -59,7 +79,7 @@ const createFontUrl = (fonts, option, fontType)=>{
59
79
  params.append('effect', option.effect);
60
80
  }
61
81
  const bunnyFontUrl = `https://fonts.bunny.net/css?family=${family}`;
62
- const googleFontUrl = `https://fonts.googleapis.com/css?${decodeURIComponent(params.toString())}`;
82
+ const googleFontUrl = `https://fonts.googleapis.com/css2?${decodeURIComponent(params.toString())}`;
63
83
  return fontType === 'bunny' ? bunnyFontUrl : googleFontUrl;
64
84
  };
65
85
  // eslint-disable-next-line max-params
@@ -85,7 +105,7 @@ async function getFonts(fonts, option, isImportFontByUrl = true, fontType) {
85
105
  }
86
106
  }
87
107
  return value;
88
- } catch (e) {
108
+ } catch (_e) {
89
109
  return '';
90
110
  }
91
111
  }
@@ -33,6 +33,9 @@ const getFontFromGroupSetting = (fonts, groupSetting)=>{
33
33
  }
34
34
  }
35
35
  };
36
+ const uniqueArray = (arr)=>{
37
+ return Array.from(new Set(arr));
38
+ };
36
39
  const getFontValue = (fonts, value)=>{
37
40
  let customFontFamily = value.custom?.fontFamily;
38
41
  if (typeof customFontFamily === 'string') {
@@ -58,15 +61,18 @@ const getFontValue = (fonts, value)=>{
58
61
  });
59
62
  const customFontWeight = value.custom?.fontWeight && variants.includes(value.custom?.fontWeight) ? value.custom?.fontWeight : variants[0];
60
63
  if (customFontWeight) {
64
+ const fontVariants = uniqueArray([
65
+ customFontWeight,
66
+ ...value?.attrs?.isAlwaysLoadBold ? [
67
+ '700'
68
+ ] : []
69
+ ]);
61
70
  const isExist = fonts.find((item)=>item.family == fontFamily && item.variants.includes(customFontWeight));
62
71
  if (!isExist) {
63
72
  const isFontFamily = fonts.find((item)=>item.family == fontFamily);
64
73
  if (isFontFamily) {
65
74
  isFontFamily.variants.push(customFontWeight);
66
75
  } else {
67
- const fontVariants = [
68
- customFontWeight
69
- ];
70
76
  if (customFontWeight !== '700') {
71
77
  if (variants.includes('700')) {
72
78
  fontVariants.push('700'); // Auto add 700 for bold in editor inline
@@ -72,7 +72,8 @@ function normalizePageSectionResponseV2(sections, orders) {
72
72
  const parseBuilderTemplateV2 = (data)=>{
73
73
  return normalizePageSectionResponseV2([
74
74
  ...data?.pageSections ?? [],
75
- ...data?.themePageCustomSections ?? []
75
+ ...data?.themePageCustomSections ?? [],
76
+ ...data?.themeSections ?? []
76
77
  ], data?.sectionPosition);
77
78
  };
78
79
  const parseBuilderTemplate = (data)=>{
@@ -2,7 +2,7 @@ const parseJson = (json)=>{
2
2
  if (!json) return null;
3
3
  try {
4
4
  return JSON.parse(json);
5
- } catch (e) {
5
+ } catch (_e) {
6
6
  return null;
7
7
  }
8
8
  };
@@ -0,0 +1,15 @@
1
+ import { withScope, captureMessage } from '@sentry/nextjs';
2
+
3
+ const sentryCaptureException = (funcName, message, data, options)=>{
4
+ withScope((scope)=>{
5
+ scope.setLevel(options?.level ?? 'log');
6
+ if (options?.tag) {
7
+ scope.setTag(options?.tag.key, options?.tag.value);
8
+ }
9
+ scope.setExtra('function', funcName);
10
+ scope.setExtra('data', JSON.stringify(data));
11
+ captureMessage(`${funcName}: ${message}`);
12
+ });
13
+ };
14
+
15
+ export { sentryCaptureException };
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
3
  import { NextSeo } from 'next-seo';
3
4
  import Image from 'next/image';
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
3
  import { cls } from '@gem-sdk/core';
3
4
  import { NextSeo } from 'next-seo';
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
3
  import { useState, useCallback, useEffect } from 'react';
3
4
  import { useCollectionsQuery } from '@gem-sdk/core';