@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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +36 -36
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/react-loadable-manifest.json +26 -20
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/1454.js +1 -0
- package/.next/server/chunks/1506.js +1 -1
- package/.next/server/chunks/3684.js +1 -1
- package/.next/server/chunks/416.js +1 -0
- package/.next/server/chunks/4289.js +13 -5
- package/.next/server/chunks/4746.js +1 -1
- package/.next/server/chunks/4816.js +1 -0
- package/.next/server/chunks/6030.js +1 -0
- package/.next/server/chunks/6076.js +1 -1
- package/.next/server/chunks/6594.js +1 -0
- package/.next/server/chunks/{8112.js → 6968.js} +2 -2
- package/.next/server/chunks/6999.js +1 -0
- package/.next/server/chunks/7371.js +1 -0
- package/.next/server/chunks/831.js +1 -0
- package/.next/server/chunks/8482.js +1 -0
- package/.next/server/chunks/8646.js +1 -1
- package/.next/server/chunks/UIBannerText.js +1 -1
- package/.next/server/chunks/UISKUMatrixSidebar.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.js +1 -1
- package/.next/server/pages/404.js.nft.json +1 -1
- package/.next/server/pages/500.js +1 -1
- package/.next/server/pages/500.js.nft.json +1 -1
- package/.next/server/pages/[...slug].js +1 -1
- package/.next/server/pages/[...slug].js.nft.json +1 -1
- package/.next/server/pages/[slug]/p.js +1 -1
- package/.next/server/pages/[slug]/p.js.nft.json +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/account/profile.js +1 -1
- package/.next/server/pages/account/profile.js.nft.json +1 -1
- package/.next/server/pages/account.js.nft.json +1 -1
- package/.next/server/pages/api/graphql.js +1 -1
- package/.next/server/pages/api/graphql.js.nft.json +1 -1
- package/.next/server/pages/api/health/live.js.nft.json +1 -1
- package/.next/server/pages/api/health/ready.js.nft.json +1 -1
- package/.next/server/pages/api/preview.js +1 -1
- package/.next/server/pages/api/preview.js.nft.json +1 -1
- package/.next/server/pages/checkout.js +1 -1
- package/.next/server/pages/checkout.js.nft.json +1 -1
- package/.next/server/pages/en-US/404.html +2 -2
- package/.next/server/pages/en-US/404.json +1 -1
- package/.next/server/pages/en-US/500.html +2 -2
- package/.next/server/pages/en-US/500.json +1 -1
- package/.next/server/pages/en-US/checkout.html +2 -2
- package/.next/server/pages/en-US/checkout.json +1 -1
- package/.next/server/pages/en-US/login.html +2 -2
- package/.next/server/pages/en-US/login.json +1 -1
- package/.next/server/pages/en-US/s.html +2 -2
- package/.next/server/pages/en-US/s.json +1 -1
- package/.next/server/pages/en-US.html +2 -2
- package/.next/server/pages/en-US.json +1 -1
- package/.next/server/pages/index.js +1 -1
- package/.next/server/pages/index.js.nft.json +1 -1
- package/.next/server/pages/login.js +1 -1
- package/.next/server/pages/login.js.nft.json +1 -1
- package/.next/server/pages/s.js +1 -1
- package/.next/server/pages/s.js.nft.json +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/server/webpack-runtime.js +1 -1
- package/.next/static/chunks/417.c39c1c5e5ef57b4a.js +1 -0
- package/.next/static/chunks/4865.3e2ae9feb511c870.js +1 -0
- package/.next/static/chunks/630.13d3dd939b789798.js +6 -0
- package/.next/static/chunks/6335-5870fc075bf96b86.js +1 -0
- package/.next/static/chunks/{7498-49bf89838314b503.js → 7498-415859c993f5002b.js} +1 -1
- package/.next/static/chunks/8827.179b49f8ab3afe48.js +1 -0
- package/.next/static/chunks/UISKUMatrixSidebar.c68540bda6d40e13.js +1 -0
- package/.next/static/chunks/pages/[...slug]-2cfb2b1b8ee3b7a9.js +1 -0
- package/.next/static/chunks/pages/[slug]/p-3b513ae37c648620.js +1 -0
- package/.next/static/chunks/pages/{_app-0f16b6b5d7dfab2a.js → _app-f02182ccd58f2781.js} +1 -1
- package/.next/static/chunks/webpack-0dd5a14ceff64065.js +1 -0
- package/.next/static/css/31fb64e064998460.css +1 -0
- package/.next/static/{YZbl2rCQaXL1-tNjqawX_ → f5jWOXDXh3GdBy9EK8IDc}/_buildManifest.js +1 -1
- package/.next/trace +111 -109
- package/.turbo/turbo-build.log +18 -24
- package/.turbo/turbo-test.log +5 -5
- package/@generated/gql.ts +2 -2
- package/@generated/graphql.ts +59 -7
- package/@generated/persisted-documents.json +3 -3
- package/CHANGELOG.md +12 -0
- package/cms/faststore/sections.json +85 -0
- package/discovery.config.default.js +6 -0
- package/package.json +5 -4
- package/src/components/cms/GlobalSections.tsx +13 -9
- package/src/components/navigation/Navbar/Navbar.tsx +2 -0
- package/src/components/product/ProductCard/ProductCard.tsx +8 -0
- package/src/components/search/SearchDropdown/SearchDropdown.tsx +14 -1
- package/src/components/search/SearchInput/SearchInput.tsx +17 -2
- package/src/components/search/SearchProductItem/SearchProductItem.tsx +120 -1
- package/src/components/sections/Navbar/DefaultComponents.ts +7 -0
- package/src/components/sections/Navbar/Navbar.tsx +16 -0
- package/src/components/sections/Navbar/section.module.scss +11 -0
- package/src/components/templates/LandingPage/LandingPage.tsx +22 -18
- package/src/components/templates/ProductListingPage/ProductListing.tsx +6 -1
- package/src/components/ui/SKUMatrix/SKUMatrixSidebar.tsx +12 -4
- package/src/experimental/searchServerSideFunctions/getServerSideProps.ts +8 -5
- package/src/experimental/searchServerSideFunctions/getStaticProps.ts +9 -7
- package/src/pages/404.tsx +6 -5
- package/src/pages/500.tsx +6 -5
- package/src/pages/[...slug].tsx +11 -4
- package/src/pages/[slug]/p.tsx +14 -5
- package/src/pages/api/preview.ts +43 -18
- package/src/pages/index.tsx +9 -7
- package/src/pages/login.tsx +6 -5
- package/src/sdk/cart/useBuyButton.ts +7 -2
- package/src/sdk/error/MissingContentError/MissingContentError.ts +6 -4
- package/src/sdk/error/MultipleContentError/MultipleContentError.ts +6 -4
- package/src/server/cms/index.ts +1 -2
- package/src/server/content/service.ts +227 -0
- package/src/server/content/types.ts +26 -0
- package/src/server/content/utils.ts +8 -0
- package/src/typings/overrides.ts +1 -0
- package/.next/server/chunks/5071.js +0 -1
- package/.next/server/chunks/5284.js +0 -1
- package/.next/server/chunks/6198.js +0 -1
- package/.next/server/chunks/804.js +0 -1
- package/.next/server/chunks/9019.js +0 -1
- package/.next/server/chunks/9068.js +0 -1
- package/.next/static/chunks/1036.27f5244aaf7d0915.js +0 -1
- package/.next/static/chunks/417.08663bd4b5809548.js +0 -1
- package/.next/static/chunks/485.a35fab0c7c75a11b.js +0 -1
- package/.next/static/chunks/4865.8b1970610c412187.js +0 -1
- package/.next/static/chunks/6335-7aa183582a89bc0e.js +0 -1
- package/.next/static/chunks/pages/[...slug]-f4fd6c8d7dc53f8f.js +0 -1
- package/.next/static/chunks/pages/[slug]/p-2e02254149cef33d.js +0 -1
- package/.next/static/chunks/webpack-f0ee32c953ec8952.js +0 -1
- package/.next/static/css/b0c0e0632c5d7f52.css +0 -1
- /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({
|
|
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, () =>
|
|
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
|
|
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: [
|
|
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:
|
|
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 =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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 =
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
69
|
-
...(previewData?.contentType === '404' && previewData),
|
|
69
|
+
contentService.getSingleContent<PageContentType>({
|
|
70
70
|
contentType: '404',
|
|
71
|
+
previewData,
|
|
71
72
|
}),
|
|
72
73
|
globalSectionsPromise,
|
|
73
74
|
globalSectionsHeaderPromise,
|