@gem-sdk/pages 1.23.0-staging.442 → 1.23.0-staging.459

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.
@@ -45,7 +45,7 @@ const Footer = (props)=>{
45
45
  children: /*#__PURE__*/ jsxRuntime.jsx("div", {
46
46
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between gp-py-6",
47
47
  style: {
48
- maxWidth: `var(--g-ct-w)`,
48
+ maxWidth: `var(--g-ct-w, 1200px)`,
49
49
  ...core.makeStyleResponsive('ml', defaultMargin),
50
50
  ...core.makeStyleResponsive('mr', defaultMargin)
51
51
  },
@@ -16,7 +16,7 @@ const FooterForPostPurchase = (props)=>{
16
16
  children: /*#__PURE__*/ jsxRuntime.jsx("div", {
17
17
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between gp-py-6",
18
18
  style: {
19
- maxWidth: `var(--g-ct-w)`,
19
+ maxWidth: `var(--g-ct-w, 1200px)`,
20
20
  ...core.makeStyleResponsive('ml', defaultMargin),
21
21
  ...core.makeStyleResponsive('mr', defaultMargin)
22
22
  },
@@ -24,7 +24,7 @@ const Header = (props)=>{
24
24
  children: pageType === 'POST_PURCHASE' ? /*#__PURE__*/ jsxRuntime.jsx("div", {
25
25
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between",
26
26
  style: {
27
- maxWidth: `var(--g-ct-w)`,
27
+ maxWidth: `var(--g-ct-w, 1200px)`,
28
28
  ...core.makeStyleResponsive('ml', defaultMargin),
29
29
  ...core.makeStyleResponsive('mr', defaultMargin)
30
30
  },
@@ -16,13 +16,13 @@ const BASE_DATA = [
16
16
  {
17
17
  title: 'Insert URL',
18
18
  content: 'to generate layout',
19
- hasAILogo: true,
19
+ hasAILogo: false,
20
20
  id: 'gps-add-section-bottom-from-url'
21
21
  },
22
22
  {
23
23
  title: 'Upload image',
24
24
  content: 'to generate layout',
25
- hasAILogo: true,
25
+ hasAILogo: false,
26
26
  id: 'gps-add-section-bottom-from-image'
27
27
  }
28
28
  ];
@@ -141,19 +141,13 @@ const DropElement = ()=>{
141
141
  ]
142
142
  })
143
143
  }),
144
- /*#__PURE__*/ jsxRuntime.jsxs("div", {
144
+ /*#__PURE__*/ jsxRuntime.jsx("div", {
145
145
  className: "gp-flex gp-items-center gp-gap-2 gp-text-xs",
146
- children: [
147
- /*#__PURE__*/ jsxRuntime.jsx("div", {
148
- id: "gp-img-to-layout-gallery-btn",
149
- className: "gp-relative gp-cursor-pointer gp-text-[14px] gp-font-medium gp-text-[#3C67FF]",
150
- children: "Start with Generating from URL or image"
151
- }),
152
- /*#__PURE__*/ jsxRuntime.jsx("div", {
153
- className: "gp-text-medium gp-flex gp-h-[20px] gp-w-[58px] gp-items-center gp-justify-center gp-rounded-[8px] gp-bg-[#3C67FF1A] gp-text-[#0008C9]",
154
- children: "AI Beta"
155
- })
156
- ]
146
+ children: /*#__PURE__*/ jsxRuntime.jsx("div", {
147
+ id: "gp-img-to-layout-gallery-btn",
148
+ className: "gp-relative gp-cursor-pointer gp-text-[14px] gp-font-medium gp-text-[#3C67FF]",
149
+ children: "Start with Generating from URL or image"
150
+ })
157
151
  })
158
152
  ]
159
153
  })
@@ -1,19 +1,50 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@gem-sdk/core');
4
- var adapterShopify = require('@gem-sdk/adapter-shopify');
5
4
  var nextjs = require('@sentry/nextjs');
6
5
  var googleFonts = require('../google-fonts.js');
7
6
  var getFallback = require('../helpers/get-fallback.js');
8
7
  var normalize = require('../helpers/normalize.js');
9
8
  var usePagePreview = require('../hooks/usePagePreview.js');
10
9
  var parseJson = require('../helpers/parse-json.js');
10
+ var genCss = require('../helpers/gen-css.js');
11
11
 
12
- const fetchThemePageDataByID = async (themePageId, fetcher, shopifyFetcher)=>{
12
+ const fetchSalePageDataByID = async (data, fetcher)=>{
13
13
  const variables = {
14
- themePageId
14
+ themePageId: data.themePageId,
15
+ first: 1,
16
+ where: {
17
+ default: true
18
+ }
19
+ };
20
+ const [theme, storeProperty] = await Promise.allSettled([
21
+ fetcher([
22
+ core.ThemePageDocument,
23
+ variables
24
+ ]),
25
+ fetcher([
26
+ core.StorePropertyDocument
27
+ ])
28
+ ]);
29
+ if (theme.status === 'rejected') {
30
+ throw new Error(theme.reason?.[0]);
31
+ }
32
+ return {
33
+ dataBuilder: theme.value.themePage,
34
+ pageStyle: theme.value.themePage?.theme?.themeStyles?.edges?.[0]?.node?.data,
35
+ storeProperty,
36
+ productOffers: []
37
+ };
38
+ };
39
+ const fetchPostPurchasePageDataByID = async (data, fetcher)=>{
40
+ const variables = {
41
+ themePageId: data.themePageId,
42
+ first: 1,
43
+ where: {
44
+ default: true
45
+ }
15
46
  };
16
- const [theme, storeProperty, shopifyMeta] = await Promise.allSettled([
47
+ const [theme, storeProperty, saleFunnelDiscounts] = await Promise.allSettled([
17
48
  fetcher([
18
49
  core.ThemePageDocument,
19
50
  variables
@@ -21,65 +52,107 @@ const fetchThemePageDataByID = async (themePageId, fetcher, shopifyFetcher)=>{
21
52
  fetcher([
22
53
  core.StorePropertyDocument
23
54
  ]),
24
- shopifyFetcher([
25
- adapterShopify.ShopMetaDocument
55
+ fetcher([
56
+ core.SaleFunnelDiscountsDocument,
57
+ {
58
+ where: {
59
+ saleFunnelOfferID: data.currentOfferID
60
+ }
61
+ }
26
62
  ])
27
63
  ]);
28
64
  if (theme.status === 'rejected') {
29
65
  throw new Error(theme.reason?.[0]);
30
66
  }
67
+ if (saleFunnelDiscounts.status === 'rejected') {
68
+ throw new Error(saleFunnelDiscounts.reason?.[0]);
69
+ }
31
70
  return {
32
71
  dataBuilder: theme.value.themePage,
72
+ pageStyle: theme.value.themePage?.theme?.themeStyles?.edges?.[0]?.node?.data,
33
73
  storeProperty,
34
- shopifyMeta
74
+ productOffers: saleFunnelDiscounts.value.saleFunnelDiscounts?.edges?.filter((item)=>item?.node?.objectType === 'PRODUCT' && item?.node?.type === 'ORDER_VALUE') || []
35
75
  };
36
76
  };
37
- const fetchThemePageDataByTemplateID = async (libraryTemplateId, fetcher, shopifyFetcher)=>{
77
+ const fetchThemePageDataByTemplateID = async (data, fetcher)=>{
38
78
  const variables = {
39
- libraryTemplateId
79
+ libraryTemplateId: data.libraryTemplateId
40
80
  };
41
- const [theme, storeProperty, shopifyMeta] = await Promise.allSettled([
81
+ let productOffers = [];
82
+ const [theme, storeProperty] = await Promise.allSettled([
42
83
  fetcher([
43
84
  core.LibraryTemplateDocument,
44
85
  variables
45
86
  ]),
46
87
  fetcher([
47
88
  core.StorePropertyDocument
48
- ]),
49
- shopifyFetcher([
50
- adapterShopify.ShopMetaDocument
51
89
  ])
52
90
  ]);
91
+ if (data.currentOfferID) {
92
+ const [librarySaleFunnel] = await Promise.allSettled([
93
+ fetcher([
94
+ core.LibrarySaleFunnelDocument,
95
+ {
96
+ librarySaleFunnelId: data.librarySaleFunnelID
97
+ }
98
+ ])
99
+ ]);
100
+ if (librarySaleFunnel.status === 'rejected') {
101
+ throw new Error(librarySaleFunnel.reason?.[0]);
102
+ }
103
+ const offer = librarySaleFunnel.value.librarySaleFunnel?.offers?.find((offer)=>offer?.id === data.currentOfferID);
104
+ if (offer) {
105
+ productOffers = offer.discounts?.filter((item)=>item?.objectType === 'PRODUCT' && item.type === 'ORDER_VALUE').map((item)=>({
106
+ node: {
107
+ ...item
108
+ }
109
+ })) || [];
110
+ }
111
+ }
53
112
  if (theme.status === 'rejected') {
54
113
  throw new Error(theme.reason?.[0]);
55
114
  }
56
115
  return {
57
116
  dataBuilder: theme.value.libraryTemplate,
117
+ pageStyle: undefined,
58
118
  storeProperty,
59
- shopifyMeta
119
+ productOffers: productOffers
60
120
  };
61
121
  };
62
- const getPostPurchasePropsPreview = (fetcher, shopifyFetcher, isTemplate)=>async (id)=>{
122
+ const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFetcher)=>async (id, currentOfferID)=>{
63
123
  try {
64
- const { dataBuilder, storeProperty, shopifyMeta } = isTemplate ? await fetchThemePageDataByTemplateID(id, fetcher, shopifyFetcher) : await fetchThemePageDataByID(id, fetcher, shopifyFetcher);
124
+ const { dataBuilder, storeProperty, productOffers, pageStyle } = librarySaleFunnelID ? await fetchThemePageDataByTemplateID({
125
+ libraryTemplateId: id,
126
+ currentOfferID,
127
+ librarySaleFunnelID
128
+ }, fetcher) : currentOfferID ? await fetchPostPurchasePageDataByID({
129
+ themePageId: id,
130
+ currentOfferID
131
+ }, fetcher) : await fetchSalePageDataByID({
132
+ themePageId: id
133
+ }, fetcher);
65
134
  if (!dataBuilder) {
66
135
  throw new Error(`No data builder found for slug: /preview/${id}`);
67
136
  }
68
- const pageTemplate = normalize.parseBuilderTemplateV2(dataBuilder);
69
- const [elementFontStyle, fallback] = await Promise.all([
137
+ const pageTemplate = librarySaleFunnelID ? normalize.parseBuilderLibraryTemplate(dataBuilder) : normalize.parseBuilderTemplateV2(dataBuilder);
138
+ const gemPagesStoreFrontFetcher = storeFrontFetcher || fetcher;
139
+ const [elementFontStyle, fontStyle, fallback] = await Promise.all([
70
140
  googleFonts.getFontStyleFromPageTemplate(pageTemplate),
71
- getFallback.getFallbackV2(fetcher, pageTemplate)
141
+ googleFonts.getFontFromGlobalStyle(pageStyle),
142
+ getFallback.getFallbackV2(gemPagesStoreFrontFetcher, pageTemplate, false)
72
143
  ]);
73
- const { seo, pageConfig } = usePagePreview.usePagePreview(dataBuilder, storeProperty, shopifyMeta);
144
+ const { seo, pageConfig } = usePagePreview.usePagePreview(dataBuilder, storeProperty);
74
145
  return parseJson.serializableJson({
146
+ themeStyle: genCss.genCSS(pageStyle),
75
147
  seo,
76
148
  ...pageConfig,
77
149
  elementFontStyle,
150
+ fontStyle,
78
151
  builderData: pageTemplate,
79
- pageType: 'POST_PURCHASE',
80
152
  swr: {
81
153
  fallback
82
- }
154
+ },
155
+ productOffers
83
156
  });
84
157
  } catch (err) {
85
158
  nextjs.captureException(err);
@@ -87,6 +160,7 @@ const getPostPurchasePropsPreview = (fetcher, shopifyFetcher, isTemplate)=>async
87
160
  }
88
161
  };
89
162
 
90
- exports.fetchThemePageDataByID = fetchThemePageDataByID;
163
+ exports.fetchPostPurchasePageDataByID = fetchPostPurchasePageDataByID;
164
+ exports.fetchSalePageDataByID = fetchSalePageDataByID;
91
165
  exports.fetchThemePageDataByTemplateID = fetchThemePageDataByTemplateID;
92
166
  exports.getPostPurchasePropsPreview = getPostPurchasePropsPreview;
@@ -2,9 +2,8 @@
2
2
 
3
3
  var core = require('@gem-sdk/core');
4
4
 
5
- const isStorefront = true;
6
- const getFallbackV2 = async (fetcher, data)=>{
7
- const isSample = !process.env.NEXT_PUBLIC_STOREFRONT_TOKEN;
5
+ const getFallbackV2 = async (fetcher, data, isStorefront = true)=>{
6
+ const isSample = isStorefront ? !process.env.NEXT_PUBLIC_STOREFRONT_TOKEN : false;
8
7
  const queries = data.map((v)=>core.prefetchQueries(v.data, {
9
8
  isSample,
10
9
  isStorefront
@@ -30,7 +30,7 @@ const orderSection = (sections, orders)=>{
30
30
  // Return the ordered sections
31
31
  const orderedSections = ids?.map((id)=>sections?.find((v)=>v?.id === id)) ?? [];
32
32
  // Return the sections that are not in the order list
33
- const sectionsNotInOrder = sections?.filter((v)=>!v?.id || !ids?.includes(v.id)) ?? [];
33
+ const sectionsNotInOrder = sections?.filter((v)=>(!v?.id || !ids?.includes(v.id)) && !v?.deletedAt) ?? [];
34
34
  // Return the ordered sections + the sections that are not in the order list
35
35
  return orderedSections.concat(sectionsNotInOrder);
36
36
  };
@@ -83,8 +83,14 @@ const parseBuilderTemplate = (data)=>{
83
83
  ...data?.themePageCustomSections ?? []
84
84
  ], data?.sectionPosition);
85
85
  };
86
+ const parseBuilderLibraryTemplate = (data)=>{
87
+ return normalizePageSectionResponseV2([
88
+ ...data?.sections ?? []
89
+ ], data?.sectionPosition);
90
+ };
86
91
 
87
92
  exports.normalizeBuilderData = normalizeBuilderData;
88
93
  exports.normalizePageSectionResponseV2 = normalizePageSectionResponseV2;
94
+ exports.parseBuilderLibraryTemplate = parseBuilderLibraryTemplate;
89
95
  exports.parseBuilderTemplate = parseBuilderTemplate;
90
96
  exports.parseBuilderTemplateV2 = parseBuilderTemplateV2;
@@ -5,7 +5,7 @@ var parseJson = require('../helpers/parse-json.js');
5
5
 
6
6
  const usePagePreview = (dataBuilder, storeProperty, shopifyMeta)=>{
7
7
  const mobileOnly = dataBuilder?.isMobile ?? false;
8
- const shopMeta = shopifyMeta.status === 'fulfilled' ? shopifyMeta.value : undefined;
8
+ const shopMeta = shopifyMeta?.status === 'fulfilled' ? shopifyMeta.value : undefined;
9
9
  const shopData = storeProperty.status === 'fulfilled' ? storeProperty.value : undefined;
10
10
  const favicon = shopData?.storeProperty?.favicon ?? '/favicon/favicon-32x32.png';
11
11
  const languageIsoCode = shopMeta?.localization.language.isoCode ?? null;
@@ -10,7 +10,7 @@ var parseHtml = require('../libs/parse-html.js');
10
10
  var Header = require('../components/Header.js');
11
11
  var FooterForPostPurchase = require('../components/FooterForPostPurchase.js');
12
12
 
13
- const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, isPostPurchase, shopName, customFonts })=>{
13
+ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, isPostPurchase, shopName, customFonts, productOffers, publicStoreFrontData, isPreview })=>{
14
14
  const router$1 = router.useRouter();
15
15
  useTrackingView.useTrackingView(shopToken, pageHandle, router$1.isFallback);
16
16
  if (router$1.isFallback) {
@@ -71,6 +71,8 @@ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, f
71
71
  ]
72
72
  }),
73
73
  /*#__PURE__*/ jsxRuntime.jsx(core.PageProvider, {
74
+ productOffers: productOffers,
75
+ publicStoreFrontData: publicStoreFrontData,
74
76
  children: /*#__PURE__*/ jsxRuntime.jsxs(core.BuilderComponentProvider, {
75
77
  components: components,
76
78
  children: [
@@ -84,6 +86,7 @@ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, f
84
86
  lazy: builder.lazy,
85
87
  priority: builder.priority,
86
88
  isPostPurchase: isPostPurchase,
89
+ isPreview: isPreview,
87
90
  children: /*#__PURE__*/ jsxRuntime.jsx(core.Render, {
88
91
  uid: builder.uid
89
92
  })
@@ -41,7 +41,7 @@ const Footer = (props)=>{
41
41
  children: /*#__PURE__*/ jsx("div", {
42
42
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between gp-py-6",
43
43
  style: {
44
- maxWidth: `var(--g-ct-w)`,
44
+ maxWidth: `var(--g-ct-w, 1200px)`,
45
45
  ...makeStyleResponsive('ml', defaultMargin),
46
46
  ...makeStyleResponsive('mr', defaultMargin)
47
47
  },
@@ -12,7 +12,7 @@ const FooterForPostPurchase = (props)=>{
12
12
  children: /*#__PURE__*/ jsx("div", {
13
13
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between gp-py-6",
14
14
  style: {
15
- maxWidth: `var(--g-ct-w)`,
15
+ maxWidth: `var(--g-ct-w, 1200px)`,
16
16
  ...makeStyleResponsive('ml', defaultMargin),
17
17
  ...makeStyleResponsive('mr', defaultMargin)
18
18
  },
@@ -20,7 +20,7 @@ const Header = (props)=>{
20
20
  children: pageType === 'POST_PURCHASE' ? /*#__PURE__*/ jsx("div", {
21
21
  className: "gp-flex gp-flex-1 gp-items-center gp-justify-between",
22
22
  style: {
23
- maxWidth: `var(--g-ct-w)`,
23
+ maxWidth: `var(--g-ct-w, 1200px)`,
24
24
  ...makeStyleResponsive('ml', defaultMargin),
25
25
  ...makeStyleResponsive('mr', defaultMargin)
26
26
  },
@@ -12,13 +12,13 @@ const BASE_DATA = [
12
12
  {
13
13
  title: 'Insert URL',
14
14
  content: 'to generate layout',
15
- hasAILogo: true,
15
+ hasAILogo: false,
16
16
  id: 'gps-add-section-bottom-from-url'
17
17
  },
18
18
  {
19
19
  title: 'Upload image',
20
20
  content: 'to generate layout',
21
- hasAILogo: true,
21
+ hasAILogo: false,
22
22
  id: 'gps-add-section-bottom-from-image'
23
23
  }
24
24
  ];
@@ -139,19 +139,13 @@ const DropElement = ()=>{
139
139
  ]
140
140
  })
141
141
  }),
142
- /*#__PURE__*/ jsxs("div", {
142
+ /*#__PURE__*/ jsx("div", {
143
143
  className: "gp-flex gp-items-center gp-gap-2 gp-text-xs",
144
- children: [
145
- /*#__PURE__*/ jsx("div", {
146
- id: "gp-img-to-layout-gallery-btn",
147
- className: "gp-relative gp-cursor-pointer gp-text-[14px] gp-font-medium gp-text-[#3C67FF]",
148
- children: "Start with Generating from URL or image"
149
- }),
150
- /*#__PURE__*/ jsx("div", {
151
- className: "gp-text-medium gp-flex gp-h-[20px] gp-w-[58px] gp-items-center gp-justify-center gp-rounded-[8px] gp-bg-[#3C67FF1A] gp-text-[#0008C9]",
152
- children: "AI Beta"
153
- })
154
- ]
144
+ children: /*#__PURE__*/ jsx("div", {
145
+ id: "gp-img-to-layout-gallery-btn",
146
+ className: "gp-relative gp-cursor-pointer gp-text-[14px] gp-font-medium gp-text-[#3C67FF]",
147
+ children: "Start with Generating from URL or image"
148
+ })
155
149
  })
156
150
  ]
157
151
  })
@@ -1,17 +1,48 @@
1
- import { ThemePageDocument, StorePropertyDocument, LibraryTemplateDocument } from '@gem-sdk/core';
2
- import { ShopMetaDocument } from '@gem-sdk/adapter-shopify';
1
+ import { ThemePageDocument, StorePropertyDocument, SaleFunnelDiscountsDocument, LibraryTemplateDocument, LibrarySaleFunnelDocument } from '@gem-sdk/core';
3
2
  import { captureException } from '@sentry/nextjs';
4
- import { getFontStyleFromPageTemplate } from '../google-fonts.js';
3
+ import { getFontStyleFromPageTemplate, getFontFromGlobalStyle } from '../google-fonts.js';
5
4
  import { getFallbackV2 } from '../helpers/get-fallback.js';
6
- import { parseBuilderTemplateV2 } from '../helpers/normalize.js';
5
+ import { parseBuilderLibraryTemplate, parseBuilderTemplateV2 } from '../helpers/normalize.js';
7
6
  import { usePagePreview } from '../hooks/usePagePreview.js';
8
7
  import { serializableJson } from '../helpers/parse-json.js';
8
+ import { genCSS } from '../helpers/gen-css.js';
9
9
 
10
- const fetchThemePageDataByID = async (themePageId, fetcher, shopifyFetcher)=>{
10
+ const fetchSalePageDataByID = async (data, fetcher)=>{
11
11
  const variables = {
12
- themePageId
12
+ themePageId: data.themePageId,
13
+ first: 1,
14
+ where: {
15
+ default: true
16
+ }
17
+ };
18
+ const [theme, storeProperty] = await Promise.allSettled([
19
+ fetcher([
20
+ ThemePageDocument,
21
+ variables
22
+ ]),
23
+ fetcher([
24
+ StorePropertyDocument
25
+ ])
26
+ ]);
27
+ if (theme.status === 'rejected') {
28
+ throw new Error(theme.reason?.[0]);
29
+ }
30
+ return {
31
+ dataBuilder: theme.value.themePage,
32
+ pageStyle: theme.value.themePage?.theme?.themeStyles?.edges?.[0]?.node?.data,
33
+ storeProperty,
34
+ productOffers: []
35
+ };
36
+ };
37
+ const fetchPostPurchasePageDataByID = async (data, fetcher)=>{
38
+ const variables = {
39
+ themePageId: data.themePageId,
40
+ first: 1,
41
+ where: {
42
+ default: true
43
+ }
13
44
  };
14
- const [theme, storeProperty, shopifyMeta] = await Promise.allSettled([
45
+ const [theme, storeProperty, saleFunnelDiscounts] = await Promise.allSettled([
15
46
  fetcher([
16
47
  ThemePageDocument,
17
48
  variables
@@ -19,65 +50,107 @@ const fetchThemePageDataByID = async (themePageId, fetcher, shopifyFetcher)=>{
19
50
  fetcher([
20
51
  StorePropertyDocument
21
52
  ]),
22
- shopifyFetcher([
23
- ShopMetaDocument
53
+ fetcher([
54
+ SaleFunnelDiscountsDocument,
55
+ {
56
+ where: {
57
+ saleFunnelOfferID: data.currentOfferID
58
+ }
59
+ }
24
60
  ])
25
61
  ]);
26
62
  if (theme.status === 'rejected') {
27
63
  throw new Error(theme.reason?.[0]);
28
64
  }
65
+ if (saleFunnelDiscounts.status === 'rejected') {
66
+ throw new Error(saleFunnelDiscounts.reason?.[0]);
67
+ }
29
68
  return {
30
69
  dataBuilder: theme.value.themePage,
70
+ pageStyle: theme.value.themePage?.theme?.themeStyles?.edges?.[0]?.node?.data,
31
71
  storeProperty,
32
- shopifyMeta
72
+ productOffers: saleFunnelDiscounts.value.saleFunnelDiscounts?.edges?.filter((item)=>item?.node?.objectType === 'PRODUCT' && item?.node?.type === 'ORDER_VALUE') || []
33
73
  };
34
74
  };
35
- const fetchThemePageDataByTemplateID = async (libraryTemplateId, fetcher, shopifyFetcher)=>{
75
+ const fetchThemePageDataByTemplateID = async (data, fetcher)=>{
36
76
  const variables = {
37
- libraryTemplateId
77
+ libraryTemplateId: data.libraryTemplateId
38
78
  };
39
- const [theme, storeProperty, shopifyMeta] = await Promise.allSettled([
79
+ let productOffers = [];
80
+ const [theme, storeProperty] = await Promise.allSettled([
40
81
  fetcher([
41
82
  LibraryTemplateDocument,
42
83
  variables
43
84
  ]),
44
85
  fetcher([
45
86
  StorePropertyDocument
46
- ]),
47
- shopifyFetcher([
48
- ShopMetaDocument
49
87
  ])
50
88
  ]);
89
+ if (data.currentOfferID) {
90
+ const [librarySaleFunnel] = await Promise.allSettled([
91
+ fetcher([
92
+ LibrarySaleFunnelDocument,
93
+ {
94
+ librarySaleFunnelId: data.librarySaleFunnelID
95
+ }
96
+ ])
97
+ ]);
98
+ if (librarySaleFunnel.status === 'rejected') {
99
+ throw new Error(librarySaleFunnel.reason?.[0]);
100
+ }
101
+ const offer = librarySaleFunnel.value.librarySaleFunnel?.offers?.find((offer)=>offer?.id === data.currentOfferID);
102
+ if (offer) {
103
+ productOffers = offer.discounts?.filter((item)=>item?.objectType === 'PRODUCT' && item.type === 'ORDER_VALUE').map((item)=>({
104
+ node: {
105
+ ...item
106
+ }
107
+ })) || [];
108
+ }
109
+ }
51
110
  if (theme.status === 'rejected') {
52
111
  throw new Error(theme.reason?.[0]);
53
112
  }
54
113
  return {
55
114
  dataBuilder: theme.value.libraryTemplate,
115
+ pageStyle: undefined,
56
116
  storeProperty,
57
- shopifyMeta
117
+ productOffers: productOffers
58
118
  };
59
119
  };
60
- const getPostPurchasePropsPreview = (fetcher, shopifyFetcher, isTemplate)=>async (id)=>{
120
+ const getPostPurchasePropsPreview = (fetcher, librarySaleFunnelID, storeFrontFetcher)=>async (id, currentOfferID)=>{
61
121
  try {
62
- const { dataBuilder, storeProperty, shopifyMeta } = isTemplate ? await fetchThemePageDataByTemplateID(id, fetcher, shopifyFetcher) : await fetchThemePageDataByID(id, fetcher, shopifyFetcher);
122
+ const { dataBuilder, storeProperty, productOffers, pageStyle } = librarySaleFunnelID ? await fetchThemePageDataByTemplateID({
123
+ libraryTemplateId: id,
124
+ currentOfferID,
125
+ librarySaleFunnelID
126
+ }, fetcher) : currentOfferID ? await fetchPostPurchasePageDataByID({
127
+ themePageId: id,
128
+ currentOfferID
129
+ }, fetcher) : await fetchSalePageDataByID({
130
+ themePageId: id
131
+ }, fetcher);
63
132
  if (!dataBuilder) {
64
133
  throw new Error(`No data builder found for slug: /preview/${id}`);
65
134
  }
66
- const pageTemplate = parseBuilderTemplateV2(dataBuilder);
67
- const [elementFontStyle, fallback] = await Promise.all([
135
+ const pageTemplate = librarySaleFunnelID ? parseBuilderLibraryTemplate(dataBuilder) : parseBuilderTemplateV2(dataBuilder);
136
+ const gemPagesStoreFrontFetcher = storeFrontFetcher || fetcher;
137
+ const [elementFontStyle, fontStyle, fallback] = await Promise.all([
68
138
  getFontStyleFromPageTemplate(pageTemplate),
69
- getFallbackV2(fetcher, pageTemplate)
139
+ getFontFromGlobalStyle(pageStyle),
140
+ getFallbackV2(gemPagesStoreFrontFetcher, pageTemplate, false)
70
141
  ]);
71
- const { seo, pageConfig } = usePagePreview(dataBuilder, storeProperty, shopifyMeta);
142
+ const { seo, pageConfig } = usePagePreview(dataBuilder, storeProperty);
72
143
  return serializableJson({
144
+ themeStyle: genCSS(pageStyle),
73
145
  seo,
74
146
  ...pageConfig,
75
147
  elementFontStyle,
148
+ fontStyle,
76
149
  builderData: pageTemplate,
77
- pageType: 'POST_PURCHASE',
78
150
  swr: {
79
151
  fallback
80
- }
152
+ },
153
+ productOffers
81
154
  });
82
155
  } catch (err) {
83
156
  captureException(err);
@@ -85,4 +158,4 @@ const getPostPurchasePropsPreview = (fetcher, shopifyFetcher, isTemplate)=>async
85
158
  }
86
159
  };
87
160
 
88
- export { fetchThemePageDataByID, fetchThemePageDataByTemplateID, getPostPurchasePropsPreview };
161
+ export { fetchPostPurchasePageDataByID, fetchSalePageDataByID, fetchThemePageDataByTemplateID, getPostPurchasePropsPreview };
@@ -1,8 +1,7 @@
1
1
  import { prefetchQueries } from '@gem-sdk/core';
2
2
 
3
- const isStorefront = true;
4
- const getFallbackV2 = async (fetcher, data)=>{
5
- const isSample = !process.env.NEXT_PUBLIC_STOREFRONT_TOKEN;
3
+ const getFallbackV2 = async (fetcher, data, isStorefront = true)=>{
4
+ const isSample = isStorefront ? !process.env.NEXT_PUBLIC_STOREFRONT_TOKEN : false;
6
5
  const queries = data.map((v)=>prefetchQueries(v.data, {
7
6
  isSample,
8
7
  isStorefront
@@ -28,7 +28,7 @@ const orderSection = (sections, orders)=>{
28
28
  // Return the ordered sections
29
29
  const orderedSections = ids?.map((id)=>sections?.find((v)=>v?.id === id)) ?? [];
30
30
  // Return the sections that are not in the order list
31
- const sectionsNotInOrder = sections?.filter((v)=>!v?.id || !ids?.includes(v.id)) ?? [];
31
+ const sectionsNotInOrder = sections?.filter((v)=>(!v?.id || !ids?.includes(v.id)) && !v?.deletedAt) ?? [];
32
32
  // Return the ordered sections + the sections that are not in the order list
33
33
  return orderedSections.concat(sectionsNotInOrder);
34
34
  };
@@ -81,5 +81,10 @@ const parseBuilderTemplate = (data)=>{
81
81
  ...data?.themePageCustomSections ?? []
82
82
  ], data?.sectionPosition);
83
83
  };
84
+ const parseBuilderLibraryTemplate = (data)=>{
85
+ return normalizePageSectionResponseV2([
86
+ ...data?.sections ?? []
87
+ ], data?.sectionPosition);
88
+ };
84
89
 
85
- export { normalizeBuilderData, normalizePageSectionResponseV2, parseBuilderTemplate, parseBuilderTemplateV2 };
90
+ export { normalizeBuilderData, normalizePageSectionResponseV2, parseBuilderLibraryTemplate, parseBuilderTemplate, parseBuilderTemplateV2 };
@@ -3,7 +3,7 @@ import { parseJson } from '../helpers/parse-json.js';
3
3
 
4
4
  const usePagePreview = (dataBuilder, storeProperty, shopifyMeta)=>{
5
5
  const mobileOnly = dataBuilder?.isMobile ?? false;
6
- const shopMeta = shopifyMeta.status === 'fulfilled' ? shopifyMeta.value : undefined;
6
+ const shopMeta = shopifyMeta?.status === 'fulfilled' ? shopifyMeta.value : undefined;
7
7
  const shopData = storeProperty.status === 'fulfilled' ? storeProperty.value : undefined;
8
8
  const favicon = shopData?.storeProperty?.favicon ?? '/favicon/favicon-32x32.png';
9
9
  const languageIsoCode = shopMeta?.localization.language.isoCode ?? null;
@@ -8,7 +8,7 @@ import { parseHtml } from '../libs/parse-html.js';
8
8
  import Header from '../components/Header.js';
9
9
  import FooterForPostPurchase from '../components/FooterForPostPurchase.js';
10
10
 
11
- const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, isPostPurchase, shopName, customFonts })=>{
11
+ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, fontStyle, elementFontStyle, customCodeHeader, shopToken, pageHandle, isPostPurchase, shopName, customFonts, productOffers, publicStoreFrontData, isPreview })=>{
12
12
  const router = useRouter();
13
13
  useTrackingView(shopToken, pageHandle, router.isFallback);
14
14
  if (router.isFallback) {
@@ -69,6 +69,8 @@ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, f
69
69
  ]
70
70
  }),
71
71
  /*#__PURE__*/ jsx(PageProvider, {
72
+ productOffers: productOffers,
73
+ publicStoreFrontData: publicStoreFrontData,
72
74
  children: /*#__PURE__*/ jsxs(BuilderComponentProvider, {
73
75
  components: components,
74
76
  children: [
@@ -82,6 +84,7 @@ const StaticPageV2 = ({ components, builderData, sectionData, seo, themeStyle, f
82
84
  lazy: builder.lazy,
83
85
  priority: builder.priority,
84
86
  isPostPurchase: isPostPurchase,
87
+ isPreview: isPreview,
85
88
  children: /*#__PURE__*/ jsx(Render, {
86
89
  uid: builder.uid
87
90
  })
@@ -1,4 +1,4 @@
1
- import { BuilderState, SectionData as SectionData$1, ShopType, RenderMode, CollectionQueryResponse, FetchFunc, ProductSelectFragment, ThemePageQueryResponse, StorePropertyQueryResponse, PublishedThemePageSelectFragment } from '@gem-sdk/core';
1
+ import { BuilderState, SectionData as SectionData$1, ShopType, RenderMode, CollectionQueryResponse, FetchFunc, ProductSelectFragment, ProductOffer, PublicStoreFrontData, ThemePageQueryResponse, StorePropertyQueryResponse, PublishedThemePageSelectFragment } from '@gem-sdk/core';
2
2
  import { NextPage, GetStaticPaths } from 'next';
3
3
  import * as next_seo from 'next-seo';
4
4
  import { NextSeoProps } from 'next-seo';
@@ -84,7 +84,16 @@ declare const getProductProps: (fetcher: FetchFunc) => (handle?: string) => Prom
84
84
 
85
85
  declare const getStaticPagePropsV2: (fetcher: FetchFunc, shopifyFetcher: FetchFunc) => (slug: string) => Promise<PageBuilderPropsV2>;
86
86
 
87
- declare const getPostPurchasePropsPreview: (fetcher: FetchFunc, shopifyFetcher: FetchFunc, isTemplate?: boolean) => (id: string) => Promise<PageBuilderPropsV2>;
87
+ type StaticPagePropsV2 = PageBuilderPropsV2 & {
88
+ isPostPurchase?: boolean;
89
+ shopName?: string;
90
+ productOffers?: ProductOffer[];
91
+ publicStoreFrontData?: PublicStoreFrontData | null;
92
+ isPreview?: boolean;
93
+ };
94
+ declare const StaticPageV2: React.FC<StaticPagePropsV2 & AdditionalPageBuilderProps>;
95
+
96
+ declare const getPostPurchasePropsPreview: (fetcher: FetchFunc, librarySaleFunnelID?: string, storeFrontFetcher?: FetchFunc) => (id: string, currentOfferID: string) => Promise<Omit<StaticPagePropsV2, 'publicStoreFrontData'>>;
88
97
 
89
98
  declare const getStaticPagePropsPreview: (fetcher: FetchFunc, shopifyFetcher: FetchFunc) => (slug: string) => Promise<PageBuilderPropsV2>;
90
99
 
@@ -98,7 +107,7 @@ declare const genCSS: (input?: string | Record<string, any>, mobileOnly?: boolea
98
107
 
99
108
  declare const useTrackingView: (token?: string | null, handle?: string | null, isFallback?: boolean) => void;
100
109
 
101
- declare const usePagePreview: (dataBuilder: ThemePageQueryResponse['themePage'], storeProperty: PromiseSettledResult<StorePropertyQueryResponse>, shopifyMeta: PromiseSettledResult<ShopMetaQueryResponse>) => {
110
+ declare const usePagePreview: (dataBuilder: ThemePageQueryResponse['themePage'], storeProperty: PromiseSettledResult<StorePropertyQueryResponse>, shopifyMeta?: PromiseSettledResult<ShopMetaQueryResponse>) => {
102
111
  seo: next_seo.NextSeoProps;
103
112
  pageConfig: {
104
113
  mobileOnly: boolean;
@@ -133,7 +142,7 @@ declare const parseBuilderTemplateV2: (data?: PublishedThemePageSelectFragment)
133
142
 
134
143
  declare const getFallbackV2: (fetcher: FetchFunc, data: {
135
144
  data: any;
136
- }[]) => Promise<{}>;
145
+ }[], isStorefront?: boolean) => Promise<{}>;
137
146
 
138
147
  type RetryConfig = {
139
148
  retries?: number;
@@ -170,12 +179,6 @@ type BuilderPageProps = {
170
179
  };
171
180
  declare const BuilderPage: React.FC<BuilderPageProps>;
172
181
 
173
- type StaticPagePropsV2 = PageBuilderPropsV2 & {
174
- isPostPurchase?: boolean;
175
- shopName?: string;
176
- };
177
- declare const StaticPageV2: React.FC<StaticPagePropsV2 & AdditionalPageBuilderProps>;
178
-
179
182
  declare const getStaticPaths: GetStaticPaths;
180
183
 
181
184
  type FontItem = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gem-sdk/pages",
3
- "version": "1.23.0-staging.442",
3
+ "version": "1.23.0-staging.459",
4
4
  "license": "MIT",
5
5
  "sideEffects": false,
6
6
  "main": "dist/cjs/index.js",
@@ -22,17 +22,15 @@
22
22
  "@sentry/nextjs": "7.77.0",
23
23
  "deepmerge": "4.3.1",
24
24
  "html-react-parser": "3.0.15",
25
- "next-seo": "^6.0.0"
25
+ "next-seo": "^6.0.0",
26
+ "next": "latest"
26
27
  },
27
28
  "devDependencies": {
28
- "@gem-sdk/core": "1.23.0-staging.436",
29
+ "@gem-sdk/core": "1.23.0-staging.458",
29
30
  "@gem-sdk/plugin-cookie-bar": "1.23.0-staging.383",
30
31
  "@gem-sdk/plugin-quick-view": "1.23.0-staging.383",
31
32
  "@gem-sdk/plugin-sticky-add-to-cart": "1.23.0-staging.383"
32
33
  },
33
- "peerDependencies": {
34
- "next": ">=13"
35
- },
36
34
  "module": "dist/esm/index.js",
37
35
  "types": "dist/types/index.d.ts",
38
36
  "exports": {