@faststore/core 3.41.9 → 3.43.0

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 (142) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +36 -36
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/server-production/0.pack +0 -0
  8. package/.next/cache/webpack/server-production/index.pack +0 -0
  9. package/.next/prerender-manifest.js +1 -1
  10. package/.next/prerender-manifest.json +1 -1
  11. package/.next/react-loadable-manifest.json +26 -20
  12. package/.next/routes-manifest.json +1 -1
  13. package/.next/server/chunks/1454.js +1 -0
  14. package/.next/server/chunks/1506.js +1 -1
  15. package/.next/server/chunks/3684.js +1 -1
  16. package/.next/server/chunks/416.js +1 -0
  17. package/.next/server/chunks/4289.js +13 -5
  18. package/.next/server/chunks/4746.js +1 -1
  19. package/.next/server/chunks/4816.js +1 -0
  20. package/.next/server/chunks/6030.js +1 -0
  21. package/.next/server/chunks/6076.js +1 -1
  22. package/.next/server/chunks/6594.js +1 -0
  23. package/.next/server/chunks/{8112.js → 6968.js} +2 -2
  24. package/.next/server/chunks/6999.js +1 -0
  25. package/.next/server/chunks/7371.js +1 -0
  26. package/.next/server/chunks/831.js +1 -0
  27. package/.next/server/chunks/8482.js +1 -0
  28. package/.next/server/chunks/8646.js +1 -1
  29. package/.next/server/chunks/UIBannerText.js +1 -1
  30. package/.next/server/chunks/UISKUMatrixSidebar.js +1 -0
  31. package/.next/server/middleware-build-manifest.js +1 -1
  32. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  33. package/.next/server/pages/404.js +1 -1
  34. package/.next/server/pages/404.js.nft.json +1 -1
  35. package/.next/server/pages/500.js +1 -1
  36. package/.next/server/pages/500.js.nft.json +1 -1
  37. package/.next/server/pages/[...slug].js +1 -1
  38. package/.next/server/pages/[...slug].js.nft.json +1 -1
  39. package/.next/server/pages/[slug]/p.js +1 -1
  40. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  41. package/.next/server/pages/_app.js.nft.json +1 -1
  42. package/.next/server/pages/_document.js.nft.json +1 -1
  43. package/.next/server/pages/_error.js.nft.json +1 -1
  44. package/.next/server/pages/account/profile.js +1 -1
  45. package/.next/server/pages/account/profile.js.nft.json +1 -1
  46. package/.next/server/pages/account.js.nft.json +1 -1
  47. package/.next/server/pages/api/graphql.js +1 -1
  48. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  49. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  50. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  51. package/.next/server/pages/api/preview.js +1 -1
  52. package/.next/server/pages/api/preview.js.nft.json +1 -1
  53. package/.next/server/pages/checkout.js +1 -1
  54. package/.next/server/pages/checkout.js.nft.json +1 -1
  55. package/.next/server/pages/en-US/404.html +2 -2
  56. package/.next/server/pages/en-US/404.json +1 -1
  57. package/.next/server/pages/en-US/500.html +2 -2
  58. package/.next/server/pages/en-US/500.json +1 -1
  59. package/.next/server/pages/en-US/checkout.html +2 -2
  60. package/.next/server/pages/en-US/checkout.json +1 -1
  61. package/.next/server/pages/en-US/login.html +2 -2
  62. package/.next/server/pages/en-US/login.json +1 -1
  63. package/.next/server/pages/en-US/s.html +2 -2
  64. package/.next/server/pages/en-US/s.json +1 -1
  65. package/.next/server/pages/en-US.html +2 -2
  66. package/.next/server/pages/en-US.json +1 -1
  67. package/.next/server/pages/index.js +1 -1
  68. package/.next/server/pages/index.js.nft.json +1 -1
  69. package/.next/server/pages/login.js +1 -1
  70. package/.next/server/pages/login.js.nft.json +1 -1
  71. package/.next/server/pages/s.js +1 -1
  72. package/.next/server/pages/s.js.nft.json +1 -1
  73. package/.next/server/pages-manifest.json +1 -1
  74. package/.next/server/webpack-runtime.js +1 -1
  75. package/.next/static/chunks/417.c39c1c5e5ef57b4a.js +1 -0
  76. package/.next/static/chunks/4865.3e2ae9feb511c870.js +1 -0
  77. package/.next/static/chunks/630.13d3dd939b789798.js +6 -0
  78. package/.next/static/chunks/6335-5870fc075bf96b86.js +1 -0
  79. package/.next/static/chunks/{7498-49bf89838314b503.js → 7498-415859c993f5002b.js} +1 -1
  80. package/.next/static/chunks/8827.179b49f8ab3afe48.js +1 -0
  81. package/.next/static/chunks/UISKUMatrixSidebar.c68540bda6d40e13.js +1 -0
  82. package/.next/static/chunks/pages/[...slug]-2cfb2b1b8ee3b7a9.js +1 -0
  83. package/.next/static/chunks/pages/[slug]/p-3b513ae37c648620.js +1 -0
  84. package/.next/static/chunks/pages/{_app-0f16b6b5d7dfab2a.js → _app-f02182ccd58f2781.js} +1 -1
  85. package/.next/static/chunks/webpack-0dd5a14ceff64065.js +1 -0
  86. package/.next/static/css/31fb64e064998460.css +1 -0
  87. package/.next/static/{YZbl2rCQaXL1-tNjqawX_ → f5jWOXDXh3GdBy9EK8IDc}/_buildManifest.js +1 -1
  88. package/.next/trace +111 -109
  89. package/.turbo/turbo-build.log +18 -24
  90. package/.turbo/turbo-test.log +5 -5
  91. package/@generated/gql.ts +2 -2
  92. package/@generated/graphql.ts +59 -7
  93. package/@generated/persisted-documents.json +3 -3
  94. package/CHANGELOG.md +12 -0
  95. package/cms/faststore/sections.json +85 -0
  96. package/discovery.config.default.js +6 -0
  97. package/package.json +5 -4
  98. package/src/components/cms/GlobalSections.tsx +13 -9
  99. package/src/components/navigation/Navbar/Navbar.tsx +2 -0
  100. package/src/components/product/ProductCard/ProductCard.tsx +8 -0
  101. package/src/components/search/SearchDropdown/SearchDropdown.tsx +14 -1
  102. package/src/components/search/SearchInput/SearchInput.tsx +17 -2
  103. package/src/components/search/SearchProductItem/SearchProductItem.tsx +120 -1
  104. package/src/components/sections/Navbar/DefaultComponents.ts +7 -0
  105. package/src/components/sections/Navbar/Navbar.tsx +16 -0
  106. package/src/components/sections/Navbar/section.module.scss +11 -0
  107. package/src/components/templates/LandingPage/LandingPage.tsx +22 -18
  108. package/src/components/templates/ProductListingPage/ProductListing.tsx +6 -1
  109. package/src/components/ui/SKUMatrix/SKUMatrixSidebar.tsx +12 -4
  110. package/src/experimental/searchServerSideFunctions/getServerSideProps.ts +8 -5
  111. package/src/experimental/searchServerSideFunctions/getStaticProps.ts +9 -7
  112. package/src/pages/404.tsx +6 -5
  113. package/src/pages/500.tsx +6 -5
  114. package/src/pages/[...slug].tsx +11 -4
  115. package/src/pages/[slug]/p.tsx +14 -5
  116. package/src/pages/api/preview.ts +43 -18
  117. package/src/pages/index.tsx +9 -7
  118. package/src/pages/login.tsx +6 -5
  119. package/src/sdk/cart/useBuyButton.ts +7 -2
  120. package/src/sdk/error/MissingContentError/MissingContentError.ts +6 -4
  121. package/src/sdk/error/MultipleContentError/MultipleContentError.ts +6 -4
  122. package/src/server/cms/index.ts +1 -2
  123. package/src/server/content/service.ts +227 -0
  124. package/src/server/content/types.ts +26 -0
  125. package/src/server/content/utils.ts +8 -0
  126. package/src/typings/overrides.ts +1 -0
  127. package/.next/server/chunks/5071.js +0 -1
  128. package/.next/server/chunks/5284.js +0 -1
  129. package/.next/server/chunks/6198.js +0 -1
  130. package/.next/server/chunks/804.js +0 -1
  131. package/.next/server/chunks/9019.js +0 -1
  132. package/.next/server/chunks/9068.js +0 -1
  133. package/.next/static/chunks/1036.27f5244aaf7d0915.js +0 -1
  134. package/.next/static/chunks/417.08663bd4b5809548.js +0 -1
  135. package/.next/static/chunks/485.a35fab0c7c75a11b.js +0 -1
  136. package/.next/static/chunks/4865.8b1970610c412187.js +0 -1
  137. package/.next/static/chunks/6335-7aa183582a89bc0e.js +0 -1
  138. package/.next/static/chunks/pages/[...slug]-f4fd6c8d7dc53f8f.js +0 -1
  139. package/.next/static/chunks/pages/[slug]/p-2e02254149cef33d.js +0 -1
  140. package/.next/static/chunks/webpack-f0ee32c953ec8952.js +0 -1
  141. package/.next/static/css/b0c0e0632c5d7f52.css +0 -1
  142. /package/.next/static/{YZbl2rCQaXL1-tNjqawX_ → f5jWOXDXh3GdBy9EK8IDc}/_ssgManifest.js +0 -0
@@ -1,3 +1,4 @@
1
+ import type { Dispatch, SetStateAction } from 'react'
1
2
  import {
2
3
  SearchProducts,
3
4
  SearchAutoComplete as UISearchAutoComplete,
@@ -17,10 +18,13 @@ import type {
17
18
  IntelligentSearchAutocompleteClickEvent,
18
19
  IntelligentSearchAutocompleteClickParams,
19
20
  } from 'src/sdk/analytics/types'
21
+ import type { NavbarProps } from 'src/components/sections/Navbar'
20
22
 
21
23
  interface SearchDropdownProps {
22
24
  sort: SearchState['sort']
25
+ quickOrderSettings?: NavbarProps['searchInput']['quickOrderSettings']
23
26
  [key: string]: any
27
+ onChangeCustomSearchDropdownVisible: Dispatch<SetStateAction<boolean>>
24
28
  }
25
29
 
26
30
  export function sendAutocompleteClickEvent({
@@ -37,7 +41,12 @@ export function sendAutocompleteClickEvent({
37
41
  })
38
42
  }
39
43
 
40
- function SearchDropdown({ sort, ...otherProps }: SearchDropdownProps) {
44
+ function SearchDropdown({
45
+ sort,
46
+ quickOrderSettings,
47
+ onChangeCustomSearchDropdownVisible,
48
+ ...otherProps
49
+ }: SearchDropdownProps) {
41
50
  const {
42
51
  values: { onSearchSelection, products, term, terms },
43
52
  } = useSearch()
@@ -79,6 +88,10 @@ function SearchDropdown({ sort, ...otherProps }: SearchDropdownProps) {
79
88
  key={productParsed.id}
80
89
  product={productParsed}
81
90
  index={index}
91
+ quickOrderSettings={quickOrderSettings}
92
+ onChangeCustomSearchDropdownVisible={
93
+ onChangeCustomSearchDropdownVisible
94
+ }
82
95
  />
83
96
  )
84
97
  })}
@@ -30,6 +30,7 @@ import type { SearchProviderContextValue } from '@faststore/ui'
30
30
  import useSearchHistory from 'src/sdk/search/useSearchHistory'
31
31
  import useSuggestions from 'src/sdk/search/useSuggestions'
32
32
  import useOnClickOutside from 'src/sdk/ui/useOnClickOutside'
33
+ import type { NavbarProps } from 'src/components/sections/Navbar'
33
34
 
34
35
  import { formatSearchPath } from 'src/sdk/search/formatSearchPath'
35
36
 
@@ -50,6 +51,7 @@ export type SearchInputProps = {
50
51
  buttonTestId?: string
51
52
  containerStyle?: CSSProperties
52
53
  placeholder?: string
54
+ quickOrderSettings?: NavbarProps['searchInput']['quickOrderSettings']
53
55
  sort?: string
54
56
  } & Omit<UISearchInputFieldProps, 'onSubmit'>
55
57
 
@@ -74,12 +76,17 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
74
76
  containerStyle,
75
77
  sort,
76
78
  placeholder,
79
+ quickOrderSettings,
77
80
  ...otherProps
78
81
  },
79
82
  ref
80
83
  ) {
81
84
  const { hidden } = otherProps
82
85
  const [searchQuery, setSearchQuery] = useState<string>('')
86
+ const [
87
+ customSearchDropdownVisibleCondition,
88
+ setCustomSearchDropdownVisibleCondition,
89
+ ] = useState<boolean>(false)
83
90
  const searchQueryDeferred = useDeferredValue(searchQuery)
84
91
  const [searchDropdownVisible, setSearchDropdownVisible] =
85
92
  useState<boolean>(false)
@@ -102,7 +109,9 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
102
109
  setSearchQuery(term)
103
110
  }
104
111
 
105
- useOnClickOutside(searchRef, () => setSearchDropdownVisible(false))
112
+ useOnClickOutside(searchRef, () =>
113
+ setSearchDropdownVisible(customSearchDropdownVisibleCondition ?? false)
114
+ )
106
115
 
107
116
  const { data, error } = useSuggestions(searchQueryDeferred)
108
117
  const terms = (data?.search.suggestions.terms ?? []).slice(
@@ -163,7 +172,13 @@ const SearchInput = forwardRef<SearchInputRef, SearchInputProps>(
163
172
 
164
173
  {searchDropdownVisible && (
165
174
  <Suspense fallback={null}>
166
- <SearchDropdown sort={sort as SearchState['sort']} />
175
+ <SearchDropdown
176
+ sort={sort as SearchState['sort']}
177
+ quickOrderSettings={quickOrderSettings}
178
+ onChangeCustomSearchDropdownVisible={
179
+ setCustomSearchDropdownVisibleCondition
180
+ }
181
+ />
167
182
  </Suspense>
168
183
  )}
169
184
  </UISearchInput>
@@ -1,8 +1,13 @@
1
+ import { type Dispatch, type SetStateAction, useMemo, useState } from 'react'
1
2
  import {
3
+ Icon,
2
4
  SearchProductItem as UISearchProductItem,
3
5
  SearchProductItemContent as UISearchProductItemContent,
4
6
  SearchProductItemImage as UISearchProductItemImage,
7
+ SKUMatrix as UISKUMatrix,
8
+ SKUMatrixTrigger as UISKUMatrixTrigger,
5
9
  useSearch,
10
+ useUI,
6
11
  } from '@faststore/ui'
7
12
 
8
13
  import { Image } from 'src/components/ui/Image'
@@ -10,6 +15,11 @@ import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice'
10
15
  import { useProductLink } from 'src/sdk/product/useProductLink'
11
16
  import { sendAutocompleteClickEvent } from '../SearchDropdown'
12
17
  import type { ProductSummary_ProductFragment } from '@generated/graphql'
18
+ import { useBuyButton } from 'src/sdk/cart/useBuyButton'
19
+ import type { NavbarProps } from 'src/components/sections/Navbar'
20
+ import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext'
21
+
22
+ import styles from 'src/components/sections/Navbar/section.module.scss'
13
23
 
14
24
  type SearchProductItemProps = {
15
25
  /**
@@ -20,16 +30,30 @@ type SearchProductItemProps = {
20
30
  * Index to generate product link.
21
31
  */
22
32
  index: number
33
+ /**
34
+ * Quick Order settings.
35
+ */
36
+ quickOrderSettings: NavbarProps['searchInput']['quickOrderSettings']
37
+ /**
38
+ * Method to manage the visibility state of the dropdown when SKU Matrix is active.
39
+ */
40
+ onChangeCustomSearchDropdownVisible: Dispatch<SetStateAction<boolean>>
23
41
  }
24
42
 
25
43
  function SearchProductItem({
26
44
  product,
27
45
  index,
46
+ quickOrderSettings,
47
+ onChangeCustomSearchDropdownVisible,
28
48
  ...otherProps
29
49
  }: SearchProductItemProps) {
30
50
  const {
31
51
  values: { onSearchSelection },
32
52
  } = useSearch()
53
+ const { pushToast } = useUI()
54
+
55
+ const { __experimentalSKUMatrixSidebar: UISKUMatrixSidebar } =
56
+ useOverrideComponents<'Navbar'>()
33
57
 
34
58
  const { href, onClick, ...baseLinkProps } = useProductLink({
35
59
  product,
@@ -37,13 +61,32 @@ function SearchProductItem({
37
61
  index,
38
62
  })
39
63
 
64
+ const [quantity, setQuantity] = useState<number>(1)
65
+
40
66
  const {
67
+ id,
68
+ sku,
69
+ gtin,
70
+ brand,
71
+ isVariantOf,
41
72
  isVariantOf: { name },
73
+ unitMultiplier,
42
74
  image: [img],
43
75
  offers: {
44
76
  lowPrice: spotPrice,
45
- offers: [{ listPrice }],
77
+ offers: [
78
+ {
79
+ listPrice,
80
+ availability,
81
+ price,
82
+ listPriceWithTaxes,
83
+ seller,
84
+ priceWithTaxes,
85
+ quantity: offersQuantity,
86
+ },
87
+ ],
46
88
  },
89
+ additionalProperty,
47
90
  } = product
48
91
 
49
92
  const linkProps = {
@@ -61,6 +104,43 @@ function SearchProductItem({
61
104
  ...baseLinkProps,
62
105
  }
63
106
 
107
+ const outOfStock = useMemo(
108
+ () => availability === 'https://schema.org/OutOfStock',
109
+ [availability]
110
+ )
111
+
112
+ const hasVariants = useMemo(
113
+ () =>
114
+ Boolean(
115
+ Object.keys(product.isVariantOf.skuVariants.allVariantsByName).length
116
+ ),
117
+
118
+ [product]
119
+ )
120
+
121
+ const buyProps = useBuyButton(
122
+ {
123
+ id,
124
+ price,
125
+ priceWithTaxes,
126
+ listPrice,
127
+ listPriceWithTaxes,
128
+ seller,
129
+ quantity,
130
+ itemOffered: {
131
+ sku,
132
+ name,
133
+ gtin,
134
+ image: [img],
135
+ brand,
136
+ isVariantOf,
137
+ additionalProperty,
138
+ unitMultiplier,
139
+ },
140
+ },
141
+ false
142
+ )
143
+
64
144
  return (
65
145
  <UISearchProductItem linkProps={linkProps} {...otherProps}>
66
146
  <UISearchProductItemImage>
@@ -73,6 +153,45 @@ function SearchProductItem({
73
153
  listPrice: listPrice,
74
154
  formatter: useFormattedPrice,
75
155
  }}
156
+ onValidateBlur={(min, max, quantity) =>
157
+ pushToast({
158
+ title: 'Invalid quantity!',
159
+ message: `The quantity you entered is outside the range of ${min} to ${max}. The quantity was set to ${quantity}.`,
160
+ status: 'INFO',
161
+ icon: <Icon name="CircleWavyWarning" width={30} height={30} />,
162
+ })
163
+ }
164
+ quickOrder={{
165
+ enabled: quickOrderSettings?.quickOrder,
166
+ outOfStockLabel: 'Out of stock',
167
+ availability: !outOfStock,
168
+ hasVariants,
169
+ buyProps,
170
+ quantity,
171
+ onChangeQuantity: setQuantity,
172
+ max: offersQuantity,
173
+ skuMatrixControl: (
174
+ <>
175
+ {quickOrderSettings?.quickOrder && (
176
+ <UISKUMatrix>
177
+ <UISKUMatrixTrigger>
178
+ {quickOrderSettings?.skuMatrix.triggerButtonLabel}
179
+ </UISKUMatrixTrigger>
180
+
181
+ <UISKUMatrixSidebar.Component
182
+ overlayProps={{ className: styles.section }}
183
+ formatter={useFormattedPrice}
184
+ columns={quickOrderSettings?.skuMatrix.columns}
185
+ product={product}
186
+ status={(status: string | null) =>
187
+ onChangeCustomSearchDropdownVisible(status === 'visible')
188
+ }
189
+ />
190
+ </UISKUMatrix>
191
+ )}
192
+ </>
193
+ ),
194
+ }}
76
195
  ></UISearchProductItemContent>
77
196
  </UISearchProductItem>
78
197
  )
@@ -37,6 +37,12 @@ const UINavbarSliderFooter = dynamic(() =>
37
37
  )
38
38
  )
39
39
 
40
+ const SKUMatrixSidebar = dynamic(() =>
41
+ import(
42
+ /* webpackChunkName: "UISKUMatrixSidebar" */ 'src/components/ui/SKUMatrix/SKUMatrixSidebar'
43
+ ).then((module) => module.default)
44
+ )
45
+
40
46
  export const NavbarDefaultComponents = {
41
47
  Navbar: UINavbar,
42
48
  NavbarLinks: UINavbarLinks,
@@ -50,4 +56,5 @@ export const NavbarDefaultComponents = {
50
56
  NavbarButtons: UINavbarButtons,
51
57
  IconButton: UIIconButton,
52
58
  _experimentalButtonSignIn: ButtonSignIn,
59
+ __experimentalSKUMatrixSidebar: SKUMatrixSidebar,
53
60
  } as const
@@ -23,6 +23,22 @@ export interface NavbarProps {
23
23
  searchInput: {
24
24
  placeholder?: string
25
25
  sort: string
26
+ quickOrderSettings: {
27
+ quickOrder: boolean
28
+ skuMatrix: {
29
+ triggerButtonLabel: string
30
+ columns: {
31
+ name: string
32
+ additionalColumns: Array<{ label: string; value: string }>
33
+ price: number
34
+ quantitySelector: number
35
+ availability: {
36
+ label: string
37
+ stockDisplaySettings: 'showAvailability' | 'showStockQuantity'
38
+ }
39
+ }
40
+ }
41
+ }
26
42
  }
27
43
  signInButton: {
28
44
  icon: {
@@ -7,12 +7,15 @@
7
7
  @import "@faststore/ui/src/components/atoms/Badge/styles.scss";
8
8
  @import "@faststore/ui/src/components/atoms/Button/styles.scss";
9
9
  @import "@faststore/ui/src/components/atoms/Icon/styles.scss";
10
+ @import "@faststore/ui/src/components/atoms/Loader/styles.scss";
10
11
  @import "@faststore/ui/src/components/atoms/Input/styles.scss";
11
12
  @import "@faststore/ui/src/components/atoms/Link/styles.scss";
12
13
  @import "@faststore/ui/src/components/atoms/List/styles.scss";
13
14
  @import "@faststore/ui/src/components/atoms/Logo/styles.scss";
15
+ @import "@faststore/ui/src/components/atoms/Overlay/styles.scss";
14
16
  @import "@faststore/ui/src/components/atoms/Price/styles.scss";
15
17
  @import "@faststore/ui/src/components/molecules/LinkButton/styles.scss";
18
+ @import "@faststore/ui/src/components/molecules/QuantitySelector/styles.scss";
16
19
  @import "@faststore/ui/src/components/molecules/NavbarLinks/styles.scss";
17
20
  @import "@faststore/ui/src/components/molecules/ProductPrice/styles.scss";
18
21
  @import "@faststore/ui/src/components/molecules/SearchAutoComplete/styles.scss";
@@ -21,8 +24,12 @@
21
24
  @import "@faststore/ui/src/components/molecules/SearchInputField/styles.scss";
22
25
  @import "@faststore/ui/src/components/molecules/SearchProducts/styles.scss";
23
26
  @import "@faststore/ui/src/components/molecules/SearchTop/styles.scss";
27
+ @import "@faststore/ui/src/components/molecules/SkuSelector/styles.scss";
28
+ @import "@faststore/ui/src/components/molecules/Table/styles.scss";
24
29
  @import "@faststore/ui/src/components/organisms/SearchInput/styles.scss";
25
30
  @import "@faststore/ui/src/components/organisms/Navbar/styles.scss";
31
+ @import "@faststore/ui/src/components/organisms/SlideOver/styles.scss";
32
+ @import "@faststore/ui/src/components/organisms/SKUMatrix/styles.scss";
26
33
 
27
34
  // Sets Navbar height on desktop to avoid CLS issue - Cumulative Layout Shift
28
35
  --fs-navbar-height-desktop: 4.5rem;
@@ -39,5 +46,9 @@
39
46
  margin-bottom: 0;
40
47
  }
41
48
  }
49
+
50
+ &[data-fs-overlay] {
51
+ height: 100%;
52
+ }
42
53
  }
43
54
  }
@@ -1,4 +1,3 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import { NextSeo, SiteLinksSearchBoxJsonLd } from 'next-seo'
3
2
  import type { ComponentType } from 'react'
4
3
 
@@ -17,9 +16,10 @@ import { default as GLOBAL_COMPONENTS } from 'src/components/cms/global/Componen
17
16
  import MissingContentError from 'src/sdk/error/MissingContentError/MissingContentError'
18
17
  import PageProvider from 'src/sdk/overrides/PageProvider'
19
18
  import type { PageContentType } from 'src/server/cms'
20
- import { getPage } from 'src/server/cms'
21
19
 
22
20
  import storeConfig from 'discovery.config'
21
+ import type { PreviewData } from 'src/server/content/types'
22
+ import { contentService } from 'src/server/content/service'
23
23
 
24
24
  /* A list of components that can be used in the CMS. */
25
25
  const COMPONENTS: Record<string, ComponentType<any>> = {
@@ -105,7 +105,7 @@ export default function LandingPage({
105
105
 
106
106
  export const getLandingPageBySlug = async (
107
107
  slug: string,
108
- previewData: Locator
108
+ previewData: PreviewData
109
109
  ) => {
110
110
  try {
111
111
  if (storeConfig.cms.data) {
@@ -115,26 +115,30 @@ export const getLandingPageBySlug = async (
115
115
  })
116
116
 
117
117
  if (pageBySlug) {
118
- const landingPageData = await getPage<PageContentType>({
119
- contentType: 'landingPage',
120
- documentId: pageBySlug.documentId,
121
- versionId: pageBySlug.versionId,
122
- })
118
+ const landingPageData =
119
+ await contentService.getSingleContent<PageContentType>({
120
+ contentType: 'landingPage',
121
+ previewData,
122
+ documentId: pageBySlug.documentId,
123
+ versionId: pageBySlug.versionId,
124
+ releaseId: pageBySlug.releaseId,
125
+ slug: pageBySlug.settings?.seo?.slug,
126
+ })
123
127
 
124
128
  return landingPageData
125
129
  }
126
130
  }
127
131
 
128
- const landingPageData = await getPage<PageContentType>({
129
- ...(previewData?.contentType === 'landingPage'
130
- ? previewData
131
- : {
132
- filters: {
133
- filters: { 'settings.seo.slug': `/${slug}` },
134
- },
135
- }),
136
- contentType: 'landingPage',
137
- })
132
+ const landingPageData =
133
+ await contentService.getSingleContent<PageContentType>({
134
+ contentType: 'landingPage',
135
+ previewData,
136
+ slug,
137
+ filters:
138
+ previewData?.contentType !== 'landingPage'
139
+ ? { filters: { 'settings.seo.slug': `/${slug}` } }
140
+ : undefined,
141
+ })
138
142
  return landingPageData
139
143
  } catch (error) {
140
144
  if (error instanceof MissingContentError) {
@@ -23,6 +23,8 @@ import {
23
23
  } from 'src/sdk/product/usePageProductsQuery'
24
24
  import { useProductGalleryQuery } from 'src/sdk/product/useProductGalleryQuery'
25
25
  import { useApplySearchState } from 'src/sdk/search/state'
26
+ import { useRouter } from 'next/router'
27
+ import { isContentPlatformSource } from 'src/server/content/utils'
26
28
 
27
29
  const ScrollToTopButton = dynamic(
28
30
  () =>
@@ -49,6 +51,7 @@ export default function ProductListing({
49
51
  serverManyProductsVariables,
50
52
  globalSections,
51
53
  }: ProductListingPageProps) {
54
+ const router = useRouter()
52
55
  const { state } = useSearch()
53
56
  const { sort, term, selectedFacets } = state
54
57
 
@@ -56,7 +59,9 @@ export default function ProductListing({
56
59
 
57
60
  const applySearchState = useApplySearchState()
58
61
  useEffect(() => {
59
- applySearchState(formatSearchState(state))
62
+ if (!isContentPlatformSource() || !router.isPreview) {
63
+ applySearchState(formatSearchState(state))
64
+ }
60
65
  }, [])
61
66
 
62
67
  const { data: pageProductGalleryData } = useProductGalleryQuery({
@@ -1,15 +1,20 @@
1
+ import { useEffect } from 'react'
1
2
  import type { SKUMatrixSidebarProps as UISKUMatrixSidebarProps } from '@faststore/ui'
2
3
  import {
3
4
  SKUMatrixSidebar as UISKUMatrixSidebar,
4
5
  useSKUMatrix,
5
6
  } from '@faststore/ui'
6
7
  import { gql } from '@generated/gql'
8
+ import type { ProductSummary_ProductFragment } from '@generated/graphql'
7
9
  import { useBuyButton } from 'src/sdk/cart/useBuyButton'
8
10
  import { usePDP } from 'src/sdk/overrides/PageProvider'
9
11
  import { useAllVariantProducts } from 'src/sdk/product/useAllVariantProducts'
10
12
  import { Image } from '../Image'
11
13
 
12
- interface SKUMatrixProps extends UISKUMatrixSidebarProps {}
14
+ interface SKUMatrixProps extends UISKUMatrixSidebarProps {
15
+ product?: ProductSummary_ProductFragment
16
+ status?(data: 'visible' | null): void
17
+ }
13
18
 
14
19
  const ImageComponent: UISKUMatrixSidebarProps['ImageComponent'] = ({
15
20
  src,
@@ -18,9 +23,8 @@ const ImageComponent: UISKUMatrixSidebarProps['ImageComponent'] = ({
18
23
  }) => <Image src={src} alt={alt} width={48} height={48} {...otherProps} />
19
24
 
20
25
  function SKUMatrixSidebar(props: SKUMatrixProps) {
21
- const {
22
- data: { product },
23
- } = usePDP()
26
+ const { data } = usePDP()
27
+ const product = props.product ?? data.product
24
28
 
25
29
  const { allVariantProducts, isOpen, setAllVariantProducts } = useSKUMatrix()
26
30
  const { isValidating } = useAllVariantProducts(
@@ -29,6 +33,10 @@ function SKUMatrixSidebar(props: SKUMatrixProps) {
29
33
  setAllVariantProducts
30
34
  )
31
35
 
36
+ useEffect(() => {
37
+ props.status?.(isOpen ? 'visible' : null)
38
+ }, [isOpen])
39
+
32
40
  const {
33
41
  gtin,
34
42
  unitMultiplier,
@@ -1,16 +1,17 @@
1
1
  import type { GetServerSideProps } from 'next'
2
2
  import type { SearchPageProps } from './getStaticProps'
3
3
 
4
- import type { Locator } from '@vtex/client-cms'
5
4
  import storeConfig from 'discovery.config'
6
5
  import { getGlobalSectionsData } from 'src/components/cms/GlobalSections'
7
6
  import { type SearchContentType, getPage } from 'src/server/cms'
8
7
  import { injectGlobalSections } from 'src/server/cms/global'
8
+ import type { PreviewData } from 'src/server/content/types'
9
+ import { contentService } from 'src/server/content/service'
9
10
 
10
11
  export const getServerSideProps: GetServerSideProps<
11
12
  SearchPageProps,
12
13
  Record<string, string>,
13
- Locator
14
+ PreviewData
14
15
  > = async (context) => {
15
16
  const { previewData, query, res } = context
16
17
  const searchTerm = (query.q as string)?.split('+').join(' ')
@@ -31,10 +32,12 @@ export const getServerSideProps: GetServerSideProps<
31
32
  globalSectionsHeader,
32
33
  globalSectionsFooter,
33
34
  ] = await Promise.all([
34
- getPage<SearchContentType>({
35
+ contentService.getSingleContent<SearchContentType>({
35
36
  contentType: 'search',
37
+ previewData,
36
38
  documentId: page.documentId,
37
39
  versionId: page.versionId,
40
+ releaseId: page.releaseId,
38
41
  }),
39
42
  globalSectionsPromise,
40
43
  globalSectionsHeaderPromise,
@@ -58,9 +61,9 @@ export const getServerSideProps: GetServerSideProps<
58
61
 
59
62
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
60
63
  await Promise.all([
61
- getPage<SearchContentType>({
62
- ...(previewData?.contentType === 'search' ? previewData : null),
64
+ contentService.getSingleContent<SearchContentType>({
63
65
  contentType: 'search',
66
+ previewData,
64
67
  }),
65
68
  globalSectionsPromise,
66
69
  globalSectionsHeaderPromise,
@@ -1,12 +1,13 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import storeConfig from 'discovery.config'
3
2
  import type { GetStaticProps } from 'next'
4
3
  import {
5
4
  getGlobalSectionsData,
6
5
  type GlobalSectionsData,
7
6
  } from 'src/components/cms/GlobalSections'
8
- import { getPage, type SearchContentType } from 'src/server/cms'
7
+ import type { SearchContentType } from 'src/server/cms'
9
8
  import { injectGlobalSections } from 'src/server/cms/global'
9
+ import { contentService } from 'src/server/content/service'
10
+ import type { PreviewData } from 'src/server/content/types'
10
11
 
11
12
  export type SearchPageProps = {
12
13
  page: SearchContentType
@@ -21,10 +22,9 @@ export type SearchPageProps = {
21
22
  export const getStaticProps: GetStaticProps<
22
23
  SearchPageProps,
23
24
  Record<string, string>,
24
- Locator
25
+ PreviewData
25
26
  > = async (context) => {
26
27
  const { previewData } = context
27
-
28
28
  const [
29
29
  globalSectionsPromise,
30
30
  globalSectionsHeaderPromise,
@@ -42,10 +42,12 @@ export const getStaticProps: GetStaticProps<
42
42
  globalSectionsHeader,
43
43
  globalSectionsFooter,
44
44
  ] = await Promise.all([
45
- getPage<SearchContentType>({
45
+ contentService.getSingleContent<SearchContentType>({
46
46
  contentType: 'search',
47
+ previewData,
47
48
  documentId: page.documentId,
48
49
  versionId: page.versionId,
50
+ releaseId: page.releaseId,
49
51
  }),
50
52
  globalSectionsPromise,
51
53
  globalSectionsHeaderPromise,
@@ -66,9 +68,9 @@ export const getStaticProps: GetStaticProps<
66
68
 
67
69
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
68
70
  await Promise.all([
69
- getPage<SearchContentType>({
70
- ...(previewData?.contentType === 'search' ? previewData : null),
71
+ contentService.getSingleContent<SearchContentType>({
71
72
  contentType: 'search',
73
+ previewData,
72
74
  }),
73
75
  globalSectionsPromise,
74
76
  globalSectionsHeaderPromise,
package/src/pages/404.tsx CHANGED
@@ -1,4 +1,3 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import type { GetStaticProps } from 'next'
3
2
  import { NextSeo } from 'next-seo'
4
3
  import type { ComponentType } from 'react'
@@ -12,8 +11,10 @@ import RenderSections from 'src/components/cms/RenderSections'
12
11
  import { OverriddenDefaultEmptyState as EmptyState } from 'src/components/sections/EmptyState/OverriddenDefaultEmptyState'
13
12
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
14
13
  import PLUGINS_COMPONENTS from 'src/plugins'
15
- import { type PageContentType, getPage } from 'src/server/cms'
14
+ import type { PageContentType } from 'src/server/cms'
16
15
  import { injectGlobalSections } from 'src/server/cms/global'
16
+ import { contentService } from 'src/server/content/service'
17
+ import type { PreviewData } from 'src/server/content/types'
17
18
 
18
19
  /* A list of components that can be used in the CMS. */
19
20
  const COMPONENTS: Record<string, ComponentType<any>> = {
@@ -55,7 +56,7 @@ function Page({ page: { sections }, globalSections }: Props) {
55
56
  export const getStaticProps: GetStaticProps<
56
57
  Props,
57
58
  Record<string, string>,
58
- Locator
59
+ PreviewData
59
60
  > = async ({ previewData }) => {
60
61
  const [
61
62
  globalSectionsPromise,
@@ -65,9 +66,9 @@ export const getStaticProps: GetStaticProps<
65
66
 
66
67
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
67
68
  await Promise.all([
68
- getPage<PageContentType>({
69
- ...(previewData?.contentType === '404' && previewData),
69
+ contentService.getSingleContent<PageContentType>({
70
70
  contentType: '404',
71
+ previewData,
71
72
  }),
72
73
  globalSectionsPromise,
73
74
  globalSectionsHeaderPromise,