@faststore/core 3.2.1 → 3.4.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 +30 -30
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/cache/config.json +3 -3
- package/.next/cache/eslint/.cache_1gneedd +1 -1
- 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/next-minimal-server.js.nft.json +1 -1
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.js +1 -1
- package/.next/prerender-manifest.json +1 -1
- package/.next/react-loadable-manifest.json +81 -41
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/2295.js +1 -0
- package/.next/server/chunks/2552.js +1 -1
- package/.next/server/chunks/2710.js +1 -0
- package/.next/server/chunks/3202.js +1 -1
- package/.next/server/chunks/3779.js +1 -0
- package/.next/server/chunks/4358.js +1 -0
- package/.next/server/chunks/5110.js +1 -0
- package/.next/server/chunks/5342.js +1 -0
- package/.next/server/chunks/5671.js +1 -1
- package/.next/server/chunks/5754.js +1 -1
- package/.next/server/chunks/6335.js +1 -0
- package/.next/server/chunks/64.js +1 -0
- package/.next/server/chunks/7228.js +1 -0
- package/.next/server/chunks/7468.js +1 -0
- package/.next/server/chunks/7986.js +1 -0
- package/.next/server/chunks/8724.js +1 -0
- package/.next/server/chunks/9088.js +1 -1
- package/.next/server/chunks/9160.js +1 -0
- package/.next/server/chunks/9410.js +1 -0
- package/.next/server/chunks/945.js +1 -1
- package/.next/server/chunks/9572.js +5 -5
- package/.next/server/chunks/983.js +1 -1
- package/.next/server/chunks/9844.js +1 -1
- package/.next/server/chunks/FilterSkeleton.js +1 -0
- package/.next/server/chunks/ScrollToTopButton.js +1 -1
- package/.next/server/chunks/UIBannerText.js +1 -1
- 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.js.nft.json +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.nft.json +1 -1
- package/.next/server/pages/checkout.js.nft.json +1 -1
- package/.next/server/pages/en-US/404.html +1 -1
- package/.next/server/pages/en-US/404.json +1 -1
- package/.next/server/pages/en-US/500.html +1 -1
- package/.next/server/pages/en-US/500.json +1 -1
- package/.next/server/pages/en-US/account.html +1 -1
- package/.next/server/pages/en-US/account.json +1 -1
- package/.next/server/pages/en-US/checkout.html +1 -1
- package/.next/server/pages/en-US/checkout.json +1 -1
- package/.next/server/pages/en-US/login.html +1 -1
- package/.next/server/pages/en-US/login.json +1 -1
- package/.next/server/pages/en-US/s.html +1 -1
- package/.next/server/pages/en-US/s.json +1 -1
- package/.next/server/pages/en-US.html +1 -1
- 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/NwqA-ReE0HVefCIamuHZW/_buildManifest.js +1 -0
- package/.next/static/chunks/{1153.7f616071da309cf5.js → 1153.d7522522b6c917ed.js} +1 -1
- package/.next/static/chunks/1550-630692a9badd8065.js +1 -0
- package/.next/static/chunks/1978.6d1246731da0f1b0.js +1 -0
- package/.next/static/chunks/2552.35321485d927aa08.js +1 -0
- package/.next/static/chunks/299.0f890f8a7e5b1846.js +1 -0
- package/.next/static/chunks/3202.a1dabb5ce227338a.js +1 -0
- package/.next/static/chunks/4501-e4bf228242a711bc.js +1 -0
- package/.next/static/chunks/4551.fd8f840c3f6ab36f.js +1 -0
- package/.next/static/chunks/6379-6050cc5d5e5f2fa2.js +1 -0
- package/.next/static/chunks/64.225f7439e13cc375.js +1 -0
- package/.next/static/chunks/8724.66f3c6d121015974.js +1 -0
- package/.next/static/chunks/9024.a746900e79690cf9.js +1 -0
- package/.next/static/chunks/9160.f23fc2e8b2b6b813.js +1 -0
- package/.next/static/chunks/9540.d020c6959e15207a.js +1 -0
- package/.next/static/chunks/9638-24a86482d4a4b434.js +1 -0
- package/.next/static/chunks/983.c7179ebdb154d450.js +1 -0
- package/.next/static/chunks/BannerNewsletter.86e9f9fcf3d3e173.js +1 -0
- package/.next/static/chunks/BannerText.9822381f787e697d.js +1 -0
- package/.next/static/chunks/CartSidebar.c6b00aa5b0667b40.js +1 -0
- package/.next/static/chunks/FilterSkeleton.5cea0252ed1ff951.js +1 -0
- package/.next/static/chunks/ProductShelf.9341a11c5282b611.js +1 -0
- package/.next/static/chunks/RegionModal.5dc5ba359a7f5350.js +1 -0
- package/.next/static/chunks/Toast.fabbe374f1d57665.js +1 -0
- package/.next/static/chunks/UIBannerText.6284ec1895c33657.js +1 -0
- package/.next/static/chunks/UIToast.1e5aada1a1b104f5.js +1 -0
- package/.next/static/chunks/pages/{[...slug]-c2bf068f3f84b127.js → [...slug]-0203b74377537f7d.js} +1 -1
- package/.next/static/chunks/pages/[slug]/p-d9260cfe3d276855.js +1 -0
- package/.next/static/chunks/pages/{_app-7d970aad41a57338.js → _app-9d791333b87e7c18.js} +1 -1
- package/.next/static/chunks/pages/s-da1c36b5dafdf07b.js +1 -0
- package/.next/static/chunks/webpack-114d9639b5990b7f.js +1 -0
- package/.next/trace +98 -98
- package/.turbo/turbo-build.log +13 -13
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +5 -5
- package/CHANGELOG.md +12 -0
- package/package.json +3 -3
- package/src/Layout.tsx +2 -2
- package/src/components/search/Filter/FilterDesktop.tsx +34 -0
- package/src/components/search/Filter/FilterSlider.tsx +38 -9
- package/src/components/search/Filter/index.ts +1 -1
- package/src/components/sections/ProductGallery/DefaultComponents.ts +23 -7
- package/src/components/ui/ProductGallery/ProductGallery.tsx +48 -14
- package/src/sdk/analytics/hooks/usePageViewEvent.ts +3 -2
- package/src/sdk/analytics/platform/vtex/index.ts +2 -1
- package/src/sdk/analytics/platform/vtex/rc.ts +128 -0
- package/src/sdk/analytics/platform/vtex/search.ts +2 -14
- package/src/sdk/analytics/types.ts +55 -0
- package/.next/server/chunks/1844.js +0 -1
- package/.next/server/chunks/2195.js +0 -1
- package/.next/server/chunks/3199.js +0 -1
- package/.next/server/chunks/4350.js +0 -1
- package/.next/server/chunks/6150.js +0 -1
- package/.next/server/chunks/7917.js +0 -1
- package/.next/server/chunks/8419.js +0 -1
- package/.next/static/PmpN0_4SJrpkkEJ4TZn7l/_buildManifest.js +0 -1
- package/.next/static/chunks/1550-48e8637718c2dd74.js +0 -1
- package/.next/static/chunks/2552.b245748eb0e40257.js +0 -1
- package/.next/static/chunks/3202.d7d5a83625bed7aa.js +0 -1
- package/.next/static/chunks/459-404aa12d42b08af1.js +0 -1
- package/.next/static/chunks/5810.470a769e37e4b13b.js +0 -1
- package/.next/static/chunks/6379-1578190b254c09a6.js +0 -1
- package/.next/static/chunks/6999-078369e946149546.js +0 -1
- package/.next/static/chunks/9463.6f5675e44c925bfc.js +0 -1
- package/.next/static/chunks/983.024c2c324d061242.js +0 -1
- package/.next/static/chunks/BannerNewsletter.0b61ee5e562a55e0.js +0 -1
- package/.next/static/chunks/BannerText.a10d4f428fc5cd97.js +0 -1
- package/.next/static/chunks/CartSidebar.dfa8017080b88d46.js +0 -1
- package/.next/static/chunks/ProductShelf.0493dbf6e9982f10.js +0 -1
- package/.next/static/chunks/RegionModal.23513fc5245a511f.js +0 -1
- package/.next/static/chunks/Toast.8635143b7896eb54.js +0 -1
- package/.next/static/chunks/UIBannerText.ac22c6843ac720b8.js +0 -1
- package/.next/static/chunks/UIToast.a3b2b8fb137a7e55.js +0 -1
- package/.next/static/chunks/pages/[slug]/p-fa2418810fa3abeb.js +0 -1
- package/.next/static/chunks/pages/s-c4ff9fe20587e49e.js +0 -1
- package/.next/static/chunks/webpack-fcd6fda2fae47824.js +0 -1
- package/src/components/search/Filter/Filter.tsx +0 -101
- /package/.next/static/{PmpN0_4SJrpkkEJ4TZn7l → NwqA-ReE0HVefCIamuHZW}/_ssgManifest.js +0 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -46,33 +46,33 @@ Warning: Dynamic Content not found for the page: home. Refer to the Dynamic Cont
|
|
|
46
46
|
Collecting build traces ...
|
|
47
47
|
|
|
48
48
|
Route (pages) Size First Load JS
|
|
49
|
-
┌ ● / 3.21 kB
|
|
49
|
+
┌ ● / 3.21 kB 122 kB
|
|
50
50
|
├ └ css/b1806cbafd0c1f81.css 3.06 kB
|
|
51
|
-
├ /_app 0 B 91.
|
|
52
|
-
├ ● /[...slug] 2 kB
|
|
53
|
-
├ ● /[slug]/p 30.
|
|
51
|
+
├ /_app 0 B 91.8 kB
|
|
52
|
+
├ ● /[...slug] 2 kB 132 kB
|
|
53
|
+
├ ● /[slug]/p 30.5 kB 149 kB
|
|
54
54
|
├ ├ css/bf1560439df2c1a1.css 5.66 kB
|
|
55
55
|
├ ├ css/e3ff5d95518a5c79.css 6.01 kB
|
|
56
56
|
├ └ css/9718991cd57978e9.css 14.8 kB
|
|
57
57
|
├ ○ /404 1.46 kB 120 kB
|
|
58
58
|
├ ● /500 1.46 kB 120 kB
|
|
59
59
|
├ ● /account 712 B 119 kB
|
|
60
|
-
├ λ /api/graphql 0 B 91.
|
|
61
|
-
├ λ /api/health/live 0 B 91.
|
|
62
|
-
├ λ /api/health/ready 0 B 91.
|
|
63
|
-
├ λ /api/preview 0 B 91.
|
|
60
|
+
├ λ /api/graphql 0 B 91.8 kB
|
|
61
|
+
├ λ /api/health/live 0 B 91.8 kB
|
|
62
|
+
├ λ /api/health/ready 0 B 91.8 kB
|
|
63
|
+
├ λ /api/preview 0 B 91.8 kB
|
|
64
64
|
├ ● /checkout 694 B 119 kB
|
|
65
65
|
├ ● /login 1.57 kB 120 kB
|
|
66
|
-
└ ● /s 2.
|
|
67
|
-
+ First Load JS shared by all 94.
|
|
66
|
+
└ ● /s 2.63 kB 132 kB
|
|
67
|
+
+ First Load JS shared by all 94.9 kB
|
|
68
68
|
├ chunks/framework-12a146e94cfcf7c4.js 45.4 kB
|
|
69
69
|
├ chunks/main-209ac4974b020af1.js 33.1 kB
|
|
70
|
-
├ chunks/pages/_app-
|
|
71
|
-
├ chunks/webpack-
|
|
70
|
+
├ chunks/pages/_app-9d791333b87e7c18.js 9.9 kB
|
|
71
|
+
├ chunks/webpack-114d9639b5990b7f.js 3.5 kB
|
|
72
72
|
└ css/ee0556daedda6306.css 3.07 kB
|
|
73
73
|
|
|
74
74
|
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
|
|
75
75
|
○ (Static) automatically rendered as static HTML (uses no initial props)
|
|
76
76
|
● (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
|
|
77
77
|
|
|
78
|
-
Done in
|
|
78
|
+
Done in 69.28s.
|
package/.turbo/turbo-lint.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
yarn run v1.22.22
|
|
2
2
|
$ jest
|
|
3
|
-
PASS test/utils/multipleTemplates.test.ts (
|
|
4
|
-
PASS test/server/cms/index.test.ts (
|
|
5
|
-
PASS test/server/index.test.ts (
|
|
3
|
+
PASS test/utils/multipleTemplates.test.ts (36.84 s)
|
|
4
|
+
PASS test/server/cms/index.test.ts (37.45 s)
|
|
5
|
+
PASS test/server/index.test.ts (39.531 s)
|
|
6
6
|
|
|
7
7
|
Test Suites: 3 passed, 3 total
|
|
8
8
|
Tests: 19 passed, 19 total
|
|
9
9
|
Snapshots: 0 total
|
|
10
|
-
Time:
|
|
10
|
+
Time: 40.737 s
|
|
11
11
|
Ran all test suites.
|
|
12
|
-
Done in
|
|
12
|
+
Done in 42.44s.
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.4.0](https://github.com/vtex/faststore/compare/v3.3.0...v3.4.0) (2024-12-19)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- handle RC Events ([#2567](https://github.com/vtex/faststore/issues/2567)) ([486563d](https://github.com/vtex/faststore/commit/486563dd6e15a04686c99bcfaea6f216520255c9))
|
|
11
|
+
|
|
12
|
+
# [3.3.0](https://github.com/vtex/faststore/compare/v3.2.1...v3.3.0) (2024-12-18)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- `Filter` with next/dynamic and lazy import ([#2596](https://github.com/vtex/faststore/issues/2596)) ([73e5496](https://github.com/vtex/faststore/commit/73e54965e656f848c20865cd2760158d634bb0c0))
|
|
17
|
+
|
|
6
18
|
## [3.2.1](https://github.com/vtex/faststore/compare/v3.2.0...v3.2.1) (2024-12-16)
|
|
7
19
|
|
|
8
20
|
**Note:** Version bump only for package @faststore/core
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@faststore/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": "vtex/faststore",
|
|
6
6
|
"browserslist": "supports es6-module and not dead",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"@faststore/components": "^3.1.3",
|
|
48
48
|
"@faststore/graphql-utils": "^3.1.3",
|
|
49
49
|
"@faststore/lighthouse": "^3.1.3",
|
|
50
|
-
"@faststore/sdk": "^3.
|
|
50
|
+
"@faststore/sdk": "^3.4.0",
|
|
51
51
|
"@faststore/ui": "^3.1.4",
|
|
52
52
|
"@graphql-codegen/cli": "5.0.2",
|
|
53
53
|
"@graphql-codegen/client-preset": "4.2.6",
|
|
@@ -128,5 +128,5 @@
|
|
|
128
128
|
"node": "18.19.0",
|
|
129
129
|
"yarn": "1.19.1"
|
|
130
130
|
},
|
|
131
|
-
"gitHead": "
|
|
131
|
+
"gitHead": "49e9dcacf82f062a09309f68e537d032f674b5cc"
|
|
132
132
|
}
|
package/src/Layout.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { PropsWithChildren, ReactElement } from 'react'
|
|
2
2
|
|
|
3
3
|
import { usePageViewEvent } from './sdk/analytics/hooks/usePageViewEvent'
|
|
4
4
|
|
|
5
5
|
function Layout({ children }: PropsWithChildren) {
|
|
6
|
-
usePageViewEvent()
|
|
6
|
+
usePageViewEvent((children as ReactElement)?.props)
|
|
7
7
|
|
|
8
8
|
return <>{children}</>
|
|
9
9
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
FilterFacetRange as UIFilterFacetRange,
|
|
8
8
|
FilterFacets as UIFilterFacets,
|
|
9
9
|
} from '@faststore/ui'
|
|
10
|
+
import { gql } from '@generated/gql'
|
|
10
11
|
import type { Filter_FacetsFragment } from '@generated/graphql'
|
|
11
12
|
import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice'
|
|
12
13
|
import { useFilter } from 'src/sdk/search/useFilter'
|
|
@@ -110,4 +111,37 @@ function FilterDesktop({
|
|
|
110
111
|
)
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
export const fragment = gql(`
|
|
115
|
+
fragment Filter_facets on StoreFacet {
|
|
116
|
+
... on StoreFacetRange {
|
|
117
|
+
key
|
|
118
|
+
label
|
|
119
|
+
|
|
120
|
+
min {
|
|
121
|
+
selected
|
|
122
|
+
absolute
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
max {
|
|
126
|
+
selected
|
|
127
|
+
absolute
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
__typename
|
|
131
|
+
}
|
|
132
|
+
... on StoreFacetBoolean {
|
|
133
|
+
key
|
|
134
|
+
label
|
|
135
|
+
values {
|
|
136
|
+
label
|
|
137
|
+
value
|
|
138
|
+
selected
|
|
139
|
+
quantity
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
__typename
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
`)
|
|
146
|
+
|
|
113
147
|
export default FilterDesktop
|
|
@@ -1,14 +1,43 @@
|
|
|
1
|
+
import dynamic from 'next/dynamic'
|
|
2
|
+
|
|
1
3
|
import { useSearch } from '@faststore/sdk'
|
|
2
|
-
import {
|
|
3
|
-
Filter as UIFilter,
|
|
4
|
-
FilterFacetBoolean as UIFilterFacetBoolean,
|
|
5
|
-
FilterFacetBooleanItem as UIFilterFacetBooleanItem,
|
|
6
|
-
FilterFacetRange as UIFilterFacetRange,
|
|
7
|
-
FilterFacets as UIFilterFacets,
|
|
8
|
-
FilterSlider as UIFilterSlider,
|
|
9
|
-
} from '@faststore/ui'
|
|
10
4
|
import { useFormattedPrice } from 'src/sdk/product/useFormattedPrice'
|
|
11
5
|
|
|
6
|
+
import type {
|
|
7
|
+
FilterFacetBooleanItemProps as UIFilterFacetBooleanItemProps,
|
|
8
|
+
FilterFacetRangeProps as UIFilterFacetRangeProps,
|
|
9
|
+
FilterFacetsProps as UIFilterFacetsProps,
|
|
10
|
+
FilterProps as UIFilterProps,
|
|
11
|
+
FilterSliderProps as UIFilterSliderProps,
|
|
12
|
+
} from '@faststore/ui'
|
|
13
|
+
|
|
14
|
+
const UIFilter = dynamic<{ children: React.ReactNode } & UIFilterProps>(() =>
|
|
15
|
+
/* webpackChunkName: "UIFilter" */
|
|
16
|
+
import('@faststore/ui').then((mod) => mod.Filter)
|
|
17
|
+
)
|
|
18
|
+
const UIFilterFacetBoolean = dynamic<{ children: React.ReactNode }>(() =>
|
|
19
|
+
/* webpackChunkName: "UIFilterFacetBoolean" */
|
|
20
|
+
import('@faststore/ui').then((mod) => mod.FilterFacetBoolean)
|
|
21
|
+
)
|
|
22
|
+
const UIFilterFacetBooleanItem = dynamic<UIFilterFacetBooleanItemProps>(() =>
|
|
23
|
+
/* webpackChunkName: "UIFilterFacetBooleanItem" */
|
|
24
|
+
import('@faststore/ui').then((mod) => mod.FilterFacetBooleanItem)
|
|
25
|
+
)
|
|
26
|
+
const UIFilterFacetRange = dynamic<UIFilterFacetRangeProps>(() =>
|
|
27
|
+
/* webpackChunkName: "UIFilterFacetRange" */
|
|
28
|
+
import('@faststore/ui').then((mod) => mod.FilterFacetRange)
|
|
29
|
+
)
|
|
30
|
+
const UIFilterFacets = dynamic<
|
|
31
|
+
{ children: React.ReactNode } & UIFilterFacetsProps
|
|
32
|
+
>(() =>
|
|
33
|
+
/* webpackChunkName: "UIFilterFacets" */
|
|
34
|
+
import('@faststore/ui').then((mod) => mod.FilterFacets)
|
|
35
|
+
)
|
|
36
|
+
const UIFilterSlider = dynamic<UIFilterSliderProps>(() =>
|
|
37
|
+
/* webpackChunkName: "UIFilterSlider" */
|
|
38
|
+
import('@faststore/ui').then((mod) => mod.FilterSlider)
|
|
39
|
+
)
|
|
40
|
+
|
|
12
41
|
import type { Filter_FacetsFragment } from '@generated/graphql'
|
|
13
42
|
|
|
14
43
|
import type { useFilter } from 'src/sdk/search/useFilter'
|
|
@@ -87,7 +116,7 @@ function FilterSlider({
|
|
|
87
116
|
<UIFilter
|
|
88
117
|
testId={`mobile-${testId}`}
|
|
89
118
|
indicesExpanded={expanded}
|
|
90
|
-
onAccordionChange={(index) =>
|
|
119
|
+
onAccordionChange={(index: number) =>
|
|
91
120
|
dispatch({ type: 'toggleExpanded', payload: index })
|
|
92
121
|
}
|
|
93
122
|
>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from './
|
|
1
|
+
export { default as FilterDesktop } from './FilterDesktop'
|
|
2
2
|
export { default as FilterSlider } from './FilterSlider'
|
|
@@ -1,18 +1,34 @@
|
|
|
1
|
-
import { lazy } from 'react'
|
|
2
1
|
import {
|
|
3
2
|
Button as UIButton,
|
|
3
|
+
Icon as UIIcon,
|
|
4
4
|
LinkButton as UILinkButton,
|
|
5
5
|
Skeleton as UISkeleton,
|
|
6
|
-
Icon as UIIcon,
|
|
7
6
|
} from '@faststore/ui'
|
|
8
7
|
|
|
9
|
-
import
|
|
10
|
-
import FilterDesktop from 'src/components/search/Filter/FilterDesktop'
|
|
11
|
-
import EmptyGallery from './EmptyGallery'
|
|
8
|
+
import dynamic from 'next/dynamic'
|
|
12
9
|
|
|
13
|
-
const
|
|
14
|
-
() =>
|
|
10
|
+
const ProductCard = dynamic(
|
|
11
|
+
() =>
|
|
12
|
+
/* webpackChunkName: "ProductCard" */
|
|
13
|
+
import('src/components/product/ProductCard')
|
|
15
14
|
)
|
|
15
|
+
const EmptyGallery = dynamic(
|
|
16
|
+
() =>
|
|
17
|
+
/* webpackChunkName: "EmptyGallery" */
|
|
18
|
+
import('./EmptyGallery')
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const FilterDesktop = dynamic(
|
|
22
|
+
() =>
|
|
23
|
+
/* webpackChunkName: "FilterDesktop" */
|
|
24
|
+
import('src/components/search/Filter/FilterDesktop')
|
|
25
|
+
)
|
|
26
|
+
const FilterSlider = dynamic(
|
|
27
|
+
() =>
|
|
28
|
+
/* webpackChunkName: "FilterSlider" */
|
|
29
|
+
import('src/components/search/Filter/FilterSlider')
|
|
30
|
+
)
|
|
31
|
+
|
|
16
32
|
export const ProductGalleryDefaultComponents = {
|
|
17
33
|
MobileFilterButton: UIButton,
|
|
18
34
|
FilterIcon: UIIcon,
|
|
@@ -4,11 +4,11 @@ import type { MouseEvent } from 'react'
|
|
|
4
4
|
import { Suspense, lazy } from 'react'
|
|
5
5
|
|
|
6
6
|
import { useUI } from '@faststore/ui'
|
|
7
|
-
import Filter from 'src/components/search/Filter'
|
|
8
7
|
import Sort from 'src/components/search/Sort'
|
|
9
|
-
import FilterSkeleton from 'src/components/skeletons/FilterSkeleton'
|
|
10
8
|
import ProductGridSkeleton from 'src/components/skeletons/ProductGridSkeleton'
|
|
11
9
|
|
|
10
|
+
import dynamic from 'next/dynamic'
|
|
11
|
+
|
|
12
12
|
import { ProductCardProps } from 'src/components/product/ProductCard'
|
|
13
13
|
import { FilterSliderProps } from 'src/components/search/Filter/FilterSlider'
|
|
14
14
|
import { SortProps } from 'src/components/search/Sort/Sort'
|
|
@@ -21,8 +21,18 @@ import {
|
|
|
21
21
|
import { useProductsPrefetch } from 'src/sdk/product/useProductsPrefetch'
|
|
22
22
|
import { useDelayedFacets } from 'src/sdk/search/useDelayedFacets'
|
|
23
23
|
import { useDelayedPagination } from 'src/sdk/search/useDelayedPagination'
|
|
24
|
+
import { useFilter } from 'src/sdk/search/useFilter'
|
|
25
|
+
import useScreenResize from 'src/sdk/ui/useScreenResize'
|
|
24
26
|
|
|
25
27
|
const ProductGalleryPage = lazy(() => import('./ProductGalleryPage'))
|
|
28
|
+
const FilterSkeleton = dynamic(
|
|
29
|
+
() =>
|
|
30
|
+
import(
|
|
31
|
+
/* webpackChunkName: "FilterSkeleton" */
|
|
32
|
+
'src/components/skeletons/FilterSkeleton'
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
|
|
26
36
|
const GalleryPageSkeleton = <ProductGridSkeleton loading />
|
|
27
37
|
|
|
28
38
|
export interface ProductGalleryProps {
|
|
@@ -69,7 +79,7 @@ function ProductGallery({
|
|
|
69
79
|
totalCount,
|
|
70
80
|
searchTermLabel,
|
|
71
81
|
totalCountLabel,
|
|
72
|
-
filter,
|
|
82
|
+
filter: filterCmsData,
|
|
73
83
|
previousPageButton,
|
|
74
84
|
loadMorePageButton,
|
|
75
85
|
sortBySelector,
|
|
@@ -84,20 +94,25 @@ function ProductGallery({
|
|
|
84
94
|
PrevIcon,
|
|
85
95
|
ResultsCountSkeleton,
|
|
86
96
|
SortSkeleton,
|
|
97
|
+
__experimentalFilterDesktop: FilterDesktop,
|
|
98
|
+
__experimentalFilterSlider: FilterSlider,
|
|
87
99
|
} = useOverrideComponents<'ProductGallery'>()
|
|
88
100
|
|
|
89
|
-
const { openFilter } = useUI()
|
|
101
|
+
const { openFilter, filter: displayFilter } = useUI()
|
|
90
102
|
const { pages, addNextPage, addPrevPage, itemsPerPage } = useSearch()
|
|
91
103
|
const context = usePage<SearchPageContext | PLPContext>()
|
|
92
104
|
const data = context?.data
|
|
93
105
|
const facets = useDelayedFacets(data) ?? []
|
|
94
106
|
const { next, prev } = useDelayedPagination(totalCount)
|
|
95
107
|
|
|
108
|
+
const { isDesktop } = useScreenResize()
|
|
109
|
+
|
|
96
110
|
useProductsPrefetch(prev ? prev.cursor : null)
|
|
97
111
|
useProductsPrefetch(next ? next.cursor : null)
|
|
98
112
|
|
|
99
113
|
const hasFacetsLoaded = Boolean(data?.search?.facets)
|
|
100
114
|
const hasProductsLoaded = Boolean(data?.search?.products)
|
|
115
|
+
const filter = useFilter(facets)
|
|
101
116
|
|
|
102
117
|
return (
|
|
103
118
|
<section data-testid="product-gallery" data-fs-product-listing>
|
|
@@ -115,13 +130,32 @@ function ProductGallery({
|
|
|
115
130
|
data-fs-product-listing-content-grid
|
|
116
131
|
data-fs-content="product-gallery"
|
|
117
132
|
>
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
{hasFacetsLoaded
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
133
|
+
{isDesktop && (
|
|
134
|
+
<div data-fs-product-listing-filters>
|
|
135
|
+
<FilterSkeleton loading={!hasFacetsLoaded}>
|
|
136
|
+
{hasFacetsLoaded && facets?.length > 0 && (
|
|
137
|
+
<div className="hidden-mobile">
|
|
138
|
+
<FilterDesktop.Component
|
|
139
|
+
{...FilterDesktop.props}
|
|
140
|
+
{...filter}
|
|
141
|
+
title={filterCmsData?.title}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
)}
|
|
145
|
+
</FilterSkeleton>
|
|
146
|
+
</div>
|
|
147
|
+
)}
|
|
148
|
+
{!isDesktop && displayFilter && (
|
|
149
|
+
<div data-fs-product-listing-filters>
|
|
150
|
+
<FilterSlider.Component
|
|
151
|
+
{...FilterSlider.props}
|
|
152
|
+
{...filter}
|
|
153
|
+
title={filterCmsData?.title}
|
|
154
|
+
clearButtonLabel={filterCmsData?.mobileOnly?.clearButtonLabel}
|
|
155
|
+
applyButtonLabel={filterCmsData?.mobileOnly?.applyButtonLabel}
|
|
156
|
+
/>
|
|
157
|
+
</div>
|
|
158
|
+
)}
|
|
125
159
|
<div data-fs-product-listing-results-count data-count={totalCount}>
|
|
126
160
|
<ResultsCountSkeleton.Component
|
|
127
161
|
data-fs-product-listing-results-count-skeleton
|
|
@@ -168,11 +202,11 @@ function ProductGallery({
|
|
|
168
202
|
height={16}
|
|
169
203
|
{...FilterIcon.props}
|
|
170
204
|
name={
|
|
171
|
-
|
|
205
|
+
filterCmsData?.mobileOnly?.filterButton?.icon?.icon ??
|
|
172
206
|
FilterIcon.props.name
|
|
173
207
|
}
|
|
174
208
|
aria-label={
|
|
175
|
-
|
|
209
|
+
filterCmsData?.mobileOnly?.filterButton?.icon?.alt ??
|
|
176
210
|
FilterIcon.props['aria-label']
|
|
177
211
|
}
|
|
178
212
|
/>
|
|
@@ -183,7 +217,7 @@ function ProductGallery({
|
|
|
183
217
|
// This decision can be reviewed later if needed
|
|
184
218
|
onClick={openFilter}
|
|
185
219
|
>
|
|
186
|
-
{
|
|
220
|
+
{filterCmsData?.mobileOnly?.filterButton?.label}
|
|
187
221
|
</MobileFilterButton.Component>
|
|
188
222
|
)}
|
|
189
223
|
</FilterButtonSkeleton.Component>
|
|
@@ -2,7 +2,7 @@ import type { PageViewEvent } from '@faststore/sdk'
|
|
|
2
2
|
import { useRouter } from 'next/router'
|
|
3
3
|
import { useCallback, useEffect } from 'react'
|
|
4
4
|
|
|
5
|
-
export const usePageViewEvent = () => {
|
|
5
|
+
export const usePageViewEvent = (props?: any) => {
|
|
6
6
|
const sendPageViewEvent = useCallback(() => {
|
|
7
7
|
import('@faststore/sdk').then(({ sendAnalyticsEvent }) => {
|
|
8
8
|
sendAnalyticsEvent<PageViewEvent>({
|
|
@@ -11,10 +11,11 @@ export const usePageViewEvent = () => {
|
|
|
11
11
|
page_title: document.title,
|
|
12
12
|
page_location: location.href,
|
|
13
13
|
send_page_view: true,
|
|
14
|
+
...props,
|
|
14
15
|
},
|
|
15
16
|
})
|
|
16
17
|
})
|
|
17
|
-
}, [])
|
|
18
|
+
}, [props])
|
|
18
19
|
|
|
19
20
|
const router = useRouter()
|
|
20
21
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { AnalyticsEvent } from '@faststore/sdk'
|
|
2
2
|
|
|
3
|
+
import handleRCEvent from './rc'
|
|
3
4
|
import handleSearchEvent from './search'
|
|
4
5
|
|
|
5
6
|
export default function sendEvent(event: AnalyticsEvent) {
|
|
6
7
|
// VTEX RC
|
|
7
|
-
|
|
8
|
+
handleRCEvent(event)
|
|
8
9
|
|
|
9
10
|
// VTEX Intelligent Search
|
|
10
11
|
handleSearchEvent(event)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { AnalyticsEvent, PageViewEvent } from '@faststore/sdk'
|
|
2
|
+
import { ServerProductQueryQuery } from '@generated/graphql'
|
|
3
|
+
import {
|
|
4
|
+
CategoryView,
|
|
5
|
+
DepartmentView,
|
|
6
|
+
HomeView,
|
|
7
|
+
IntelligentSearchQueryEvent,
|
|
8
|
+
InternalSiteSearchView,
|
|
9
|
+
OtherView,
|
|
10
|
+
ProductView,
|
|
11
|
+
SearchEvents,
|
|
12
|
+
} from '../../types'
|
|
13
|
+
|
|
14
|
+
const EventNames = {
|
|
15
|
+
OTHER_VIEW: 'otherView',
|
|
16
|
+
HOME_VIEW: 'homeView',
|
|
17
|
+
CATEGORY_VIEW: 'categoryView',
|
|
18
|
+
DEPARTMENT_VIEW: 'departmentView',
|
|
19
|
+
INTERNAL_SITE_SEARCH_VIEW: 'internalSiteSearchView',
|
|
20
|
+
PRODUCT_VIEW: 'productView',
|
|
21
|
+
} as const
|
|
22
|
+
|
|
23
|
+
type RequestCaptureEventNames = (typeof EventNames)[keyof typeof EventNames]
|
|
24
|
+
type RequestCaptureEvent =
|
|
25
|
+
| HomeView
|
|
26
|
+
| CategoryView
|
|
27
|
+
| DepartmentView
|
|
28
|
+
| InternalSiteSearchView
|
|
29
|
+
| ProductView
|
|
30
|
+
| OtherView
|
|
31
|
+
|
|
32
|
+
const sendEvent = (
|
|
33
|
+
eventName: RequestCaptureEventNames,
|
|
34
|
+
eventParams: RequestCaptureEvent
|
|
35
|
+
) => {
|
|
36
|
+
window?.sendrc?.(eventName, eventParams)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const handleEvent = (event: AnalyticsEvent | SearchEvents) => {
|
|
40
|
+
let eventParams
|
|
41
|
+
switch (event.name) {
|
|
42
|
+
case 'page_view':
|
|
43
|
+
eventParams = (event as PageViewEvent).params
|
|
44
|
+
const pageType = eventParams?.page?.type ?? eventParams?.type
|
|
45
|
+
|
|
46
|
+
switch (pageType) {
|
|
47
|
+
case 'plp':
|
|
48
|
+
if (!eventParams?.page_location?.includes('fuzzy')) {
|
|
49
|
+
// Skip when there is no fuzzy parameters on the URL,
|
|
50
|
+
// otherwise it'll be sent twice (once without fuzzy and once with fuzzy)
|
|
51
|
+
break
|
|
52
|
+
}
|
|
53
|
+
const collection = eventParams?.data?.collection
|
|
54
|
+
const collectionCategoryList =
|
|
55
|
+
collection?.breadcrumbList?.itemListElement
|
|
56
|
+
if (collectionCategoryList.length > 1) {
|
|
57
|
+
sendEvent(EventNames.CATEGORY_VIEW, {
|
|
58
|
+
departmentName: collectionCategoryList[0]?.name,
|
|
59
|
+
categoryId: collection?.id,
|
|
60
|
+
categoryName:
|
|
61
|
+
collectionCategoryList[collectionCategoryList.length - 1]?.name,
|
|
62
|
+
})
|
|
63
|
+
} else {
|
|
64
|
+
sendEvent(EventNames.DEPARTMENT_VIEW, {
|
|
65
|
+
departmentId: collection?.id,
|
|
66
|
+
departmentName: collectionCategoryList[0]?.name,
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
break
|
|
71
|
+
|
|
72
|
+
case 'pdp':
|
|
73
|
+
const product = eventParams?.data
|
|
74
|
+
?.product as ServerProductQueryQuery['product']
|
|
75
|
+
const productCategoryList = product?.breadcrumbList?.itemListElement
|
|
76
|
+
const offers = product?.offers?.offers
|
|
77
|
+
const sellerIds = offers.map((offer) => offer.seller.identifier)
|
|
78
|
+
const skusOutOfStock = offers.filter(
|
|
79
|
+
(offer) => offer.availability === 'https://schema.org/OutOfStock'
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
sendEvent(EventNames.PRODUCT_VIEW, {
|
|
83
|
+
skuStockOutFromProductDetail: skusOutOfStock,
|
|
84
|
+
productId: product?.isVariantOf?.productGroupID,
|
|
85
|
+
productName: product?.isVariantOf?.name,
|
|
86
|
+
productBrandName: product?.brand?.name,
|
|
87
|
+
productDepartmentName: productCategoryList
|
|
88
|
+
? productCategoryList[0]?.name
|
|
89
|
+
: '',
|
|
90
|
+
productCategoryName:
|
|
91
|
+
productCategoryList.length > 1
|
|
92
|
+
? productCategoryList[productCategoryList.length - 2]?.name
|
|
93
|
+
: '',
|
|
94
|
+
productPrice: offers[0]?.price,
|
|
95
|
+
productListPrice: offers[0]?.listPrice,
|
|
96
|
+
sellerId: offers[0]?.seller?.identifier,
|
|
97
|
+
sellerIds: sellerIds.join(','),
|
|
98
|
+
})
|
|
99
|
+
break
|
|
100
|
+
|
|
101
|
+
case 'home':
|
|
102
|
+
sendEvent(EventNames.HOME_VIEW, {})
|
|
103
|
+
break
|
|
104
|
+
|
|
105
|
+
case 'search':
|
|
106
|
+
// This one is skipped because the event related to search view is being
|
|
107
|
+
// sent using the intelligent_search_query event due to its parameters
|
|
108
|
+
break
|
|
109
|
+
|
|
110
|
+
default:
|
|
111
|
+
sendEvent(EventNames.OTHER_VIEW, {})
|
|
112
|
+
}
|
|
113
|
+
break
|
|
114
|
+
|
|
115
|
+
case 'intelligent_search_query':
|
|
116
|
+
eventParams = (event as IntelligentSearchQueryEvent).params
|
|
117
|
+
sendEvent(EventNames.INTERNAL_SITE_SEARCH_VIEW, {
|
|
118
|
+
siteSearchTerm: eventParams.term,
|
|
119
|
+
siteSearchForm: eventParams.url,
|
|
120
|
+
siteSearchResults: eventParams.totalCount,
|
|
121
|
+
})
|
|
122
|
+
break
|
|
123
|
+
|
|
124
|
+
default:
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default handleEvent
|
|
@@ -2,12 +2,7 @@
|
|
|
2
2
|
* More info at: https://developers.vtex.com/docs/api-reference/intelligent-search-events-api-headless
|
|
3
3
|
*/
|
|
4
4
|
import type { AnalyticsEvent } from '@faststore/sdk'
|
|
5
|
-
import type {
|
|
6
|
-
IntelligentSearchAutocompleteClickEvent,
|
|
7
|
-
IntelligentSearchAutocompleteQueryEvent,
|
|
8
|
-
IntelligentSearchQueryEvent,
|
|
9
|
-
SearchSelectItemEvent,
|
|
10
|
-
} from '../../types'
|
|
5
|
+
import type { SearchEvents } from '../../types'
|
|
11
6
|
|
|
12
7
|
import config from '../../../../../discovery.config'
|
|
13
8
|
import { getCookie } from '../../../../utils/getCookie'
|
|
@@ -103,14 +98,7 @@ const isFullTextSearch = (url: URL) =>
|
|
|
103
98
|
typeof url.searchParams.get('q') === 'string' &&
|
|
104
99
|
/^\/s(\/)?$/g.test(url.pathname)
|
|
105
100
|
|
|
106
|
-
const handleEvent = (
|
|
107
|
-
event:
|
|
108
|
-
| AnalyticsEvent
|
|
109
|
-
| SearchSelectItemEvent
|
|
110
|
-
| IntelligentSearchQueryEvent
|
|
111
|
-
| IntelligentSearchAutocompleteQueryEvent
|
|
112
|
-
| IntelligentSearchAutocompleteClickEvent
|
|
113
|
-
) => {
|
|
101
|
+
const handleEvent = (event: AnalyticsEvent | SearchEvents) => {
|
|
114
102
|
switch (event.name) {
|
|
115
103
|
case 'search_select_item': {
|
|
116
104
|
const url = new URL(event.params.url)
|
|
@@ -60,3 +60,58 @@ export interface IntelligentSearchAutocompleteClickEvent {
|
|
|
60
60
|
name: 'intelligent_search_autocomplete_click'
|
|
61
61
|
params: IntelligentSearchAutocompleteClickParams
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
export type SearchEvents =
|
|
65
|
+
| SearchSelectItemEvent
|
|
66
|
+
| IntelligentSearchQueryEvent
|
|
67
|
+
| IntelligentSearchAutocompleteQueryEvent
|
|
68
|
+
| IntelligentSearchAutocompleteClickEvent
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* RC event types
|
|
72
|
+
* Types copied from Request Capture App: https://github.com/vtex/request-capture-app/blob/1becac32c002cb03a57bf36c8a7f9400eab8b933/react/typings/rcevents.d.ts
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
export interface HomeView {}
|
|
76
|
+
|
|
77
|
+
export interface CategoryView {
|
|
78
|
+
departmentId?: string
|
|
79
|
+
departmentName?: string
|
|
80
|
+
categoryId?: string
|
|
81
|
+
categoryName?: string
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface DepartmentView {
|
|
85
|
+
departmentId?: string
|
|
86
|
+
departmentName?: string
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface InternalSiteSearchView {
|
|
90
|
+
siteSearchTerm?: string // e.g.: "areia"
|
|
91
|
+
siteSearchForm?: string // e.g.: "/gatos/ambiente--gatos/caixa-de-areia/areia?PS=20"
|
|
92
|
+
siteSearchCategory?: string // e.g.: "10000283"
|
|
93
|
+
siteSearchResults?: number // e.g.: 26
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
type SkuId = string
|
|
97
|
+
|
|
98
|
+
export interface ProductView {
|
|
99
|
+
skuStockOutFromProductDetail: string[]
|
|
100
|
+
productId: string
|
|
101
|
+
productReferenceId: string
|
|
102
|
+
productEans: string[]
|
|
103
|
+
skuStocks: Record<SkuId, number>
|
|
104
|
+
productName: string
|
|
105
|
+
productBrandId: string
|
|
106
|
+
productBrandName: string
|
|
107
|
+
productDepartmentId: string
|
|
108
|
+
productDepartmentName: string
|
|
109
|
+
productCategoryId: string
|
|
110
|
+
productCategoryName: string
|
|
111
|
+
productListPrice: number
|
|
112
|
+
productPrice: number
|
|
113
|
+
sellerId: string
|
|
114
|
+
sellerIds: string // e.g.: "00443713,04412311,1"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface OtherView {}
|