@faststore/core 3.98.0-dev.1 → 3.98.0-dev.10
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 +124 -123
- 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/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 +167 -163
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/{5796.js → 1027.js} +1 -1
- package/.next/server/chunks/1197.js +1 -0
- package/.next/server/chunks/{3483.js → 1313.js} +1 -1
- package/.next/server/chunks/1419.js +1 -0
- package/.next/server/chunks/1576.js +1 -0
- package/.next/server/chunks/{7275.js → 1588.js} +1 -1
- package/.next/server/chunks/1741.js +3 -0
- package/.next/server/chunks/221.js +1 -0
- package/.next/server/chunks/2259.js +9 -0
- package/.next/server/chunks/2513.js +1 -0
- package/.next/server/chunks/2955.js +1 -0
- package/.next/server/chunks/3114.js +1 -0
- package/.next/server/chunks/3327.js +1 -0
- package/.next/server/chunks/3488.js +1 -0
- package/.next/server/chunks/{1917.js → 3513.js} +1 -1
- package/.next/server/chunks/3683.js +1 -0
- package/.next/server/chunks/{8563.js → 3724.js} +1 -1
- package/.next/server/chunks/3977.js +1 -0
- package/.next/server/chunks/426.js +1 -0
- package/.next/server/chunks/4573.js +1 -0
- package/.next/server/chunks/4681.js +1 -0
- package/.next/server/chunks/5133.js +3 -0
- package/.next/server/chunks/5212.js +7 -0
- package/.next/server/chunks/5608.js +1 -0
- package/.next/server/chunks/5628.js +12 -0
- package/.next/server/chunks/{1607.js → 5764.js} +1 -1
- package/.next/server/chunks/{9740.js → 6259.js} +1 -1
- package/.next/server/chunks/6698.js +1 -1
- package/.next/server/chunks/689.js +1 -0
- package/.next/server/chunks/6952.js +1 -0
- package/.next/server/chunks/7121.js +1 -0
- package/.next/server/chunks/7371.js +1 -1
- package/.next/server/chunks/7417.js +1 -0
- package/.next/server/chunks/{1280.js → 7722.js} +1 -1
- package/.next/server/chunks/7796.js +1 -0
- package/.next/server/chunks/7956.js +1 -0
- package/.next/server/chunks/{6804.js → 7976.js} +3 -3
- package/.next/server/chunks/{9985.js → 8146.js} +1 -1
- package/.next/server/chunks/8290.js +1 -0
- package/.next/server/chunks/8376.js +13 -0
- package/.next/server/chunks/8466.js +6 -0
- package/.next/server/chunks/8569.js +1 -1
- package/.next/server/chunks/8659.js +1 -0
- package/.next/server/chunks/8741.js +1 -0
- package/.next/server/chunks/8971.js +493 -0
- package/.next/server/chunks/9088.js +1 -1
- package/.next/server/chunks/9237.js +1 -1
- package/.next/server/chunks/9374.js +13 -0
- package/.next/server/chunks/{8068.js → 9425.js} +1 -1
- package/.next/server/chunks/{UINavbarSlider.js → 9984.js} +1 -1
- package/.next/server/chunks/9986.js +1 -0
- package/.next/server/chunks/ButtonSignIn.js +1 -1
- package/.next/server/chunks/FilterSkeleton.js +1 -1
- package/.next/server/chunks/ScrollToTopButton.js +1 -1
- package/.next/server/chunks/UIBannerText.js +1 -1
- package/.next/server/chunks/UISKUMatrixSidebar.js +1 -1
- package/.next/server/functions-config-manifest.json +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 +1 -1
- package/.next/server/pages/_app.js.nft.json +1 -1
- package/.next/server/pages/_document.js +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +1 -1
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/pages/api/fs/logout.js +1 -1
- package/.next/server/pages/api/fs/logout.js.nft.json +1 -1
- package/.next/server/pages/api/graphql.js +3 -3
- package/.next/server/pages/api/graphql.js.nft.json +1 -1
- package/.next/server/pages/api/health/live.js +1 -1
- package/.next/server/pages/api/health/live.js.nft.json +1 -1
- package/.next/server/pages/api/health/ready.js +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/pvt/account/403.js +1 -1
- package/.next/server/pages/pvt/account/403.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/404.js +1 -1
- package/.next/server/pages/pvt/account/404.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/[...unknown].js +1 -1
- package/.next/server/pages/pvt/account/[...unknown].js.nft.json +1 -1
- package/.next/server/pages/pvt/account/orders/[id].js +1 -1
- package/.next/server/pages/pvt/account/orders/[id].js.nft.json +1 -1
- package/.next/server/pages/pvt/account/orders.js +1 -1
- package/.next/server/pages/pvt/account/orders.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/profile.js +1 -1
- package/.next/server/pages/pvt/account/profile.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/security.js +1 -1
- package/.next/server/pages/pvt/account/security.js.nft.json +1 -1
- package/.next/server/pages/pvt/account/user-details.js +1 -1
- package/.next/server/pages/pvt/account/user-details.js.nft.json +1 -1
- package/.next/server/pages/pvt/account.js +1 -1
- package/.next/server/pages/pvt/account.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/Xu5Fn6_Qwp_x6LicEI8BU/_buildManifest.js +1 -0
- package/.next/static/chunks/{5796.4351370494d8b8b6.js → 1027.f17a7c96c17ce487.js} +1 -1
- package/.next/static/chunks/1313.bba028de90630608.js +1 -0
- package/.next/static/chunks/1756.89b7f413bb26ba74.js +1 -0
- package/.next/static/chunks/{8325.dabe9aa22eaadeed.js → 1911.fb72de1df3c3715c.js} +1 -1
- package/.next/static/chunks/2221-f8edfdaa4839bdf0.js +2 -0
- package/.next/static/chunks/2564.273fd8b0db75b1c4.js +1 -0
- package/.next/static/chunks/2811.cf089090a8b79215.js +1 -0
- package/.next/static/chunks/346.2840f007e6d1054c.js +1 -0
- package/.next/static/chunks/3496.bcb4d219501a8b6b.js +1 -0
- package/.next/static/chunks/3753-74460a0793c0a75c.js +8 -0
- package/.next/static/chunks/3802.1e0df8a20802da16.js +1 -0
- package/.next/static/chunks/3883-ebdbb60b50a90c59.js +28 -0
- package/.next/static/chunks/4436.9b2b6e1c3f79424d.js +1 -0
- package/.next/static/chunks/4681.318feb830c746e3b.js +1 -0
- package/.next/static/chunks/484.9fdcaa9ffd8dac08.js +1 -0
- package/.next/static/chunks/6218.e8ba8bf8602ec880.js +1 -0
- package/.next/static/chunks/{6393.e4b26fee060438d6.js → 6393.f5f13a004beeef40.js} +1 -1
- package/.next/static/chunks/6656-efc464f20ffeaa51.js +1 -0
- package/.next/static/chunks/6797-ff5656c8624c4265.js +1 -0
- package/.next/static/chunks/6943.6bc97e925b54493d.js +1 -0
- package/.next/static/chunks/7417.55a6e20779dd3702.js +1 -0
- package/.next/static/chunks/7534.ee76e63d58ddd222.js +1 -0
- package/.next/static/chunks/7796.a30626656a270831.js +1 -0
- package/.next/static/chunks/9105.354374e349da85cb.js +1 -0
- package/.next/static/chunks/9222.04daf7868c957e52.js +1 -0
- package/.next/static/chunks/{9237.7555603703f81bf7.js → 9237.2d7e1a4978875414.js} +1 -1
- package/.next/static/chunks/9399.199f217093e4af1e.js +1 -0
- package/.next/static/chunks/{8068.43663fb64762f7b8.js → 9425.9d8b3da847111f21.js} +1 -1
- package/.next/static/chunks/9701.f9a0bfffba8807dc.js +1 -0
- package/.next/static/chunks/BannerNewsletter.b5770016d20acfd2.js +1 -0
- package/.next/static/chunks/{BannerText.4061ccfc191e6b96.js → BannerText.5ba50fbe683158ec.js} +1 -1
- package/.next/static/chunks/{ButtonSignIn.f6e210eaca873e48.js → ButtonSignIn.639d8dfc65ded368.js} +1 -1
- package/.next/static/chunks/CartItem.3c2ceb3a4ee542bc.js +1 -0
- package/.next/static/chunks/CartSidebar.89b0dd6237c025ec.js +1 -0
- package/.next/static/chunks/{EmptyCart.320e2f94a0d5e6b1.js → EmptyCart.aa60d42ae8eb5264.js} +1 -1
- package/.next/static/chunks/{FilterSkeleton.7ab99e28f92341c9.js → FilterSkeleton.8f1b651c40e06f0b.js} +1 -1
- package/.next/static/chunks/Footer.cd83c4dc0252494a.js +1 -0
- package/.next/static/chunks/Gift.4c97f836f82d5ebe.js +1 -0
- package/.next/static/chunks/Newsletter.bdec43379ca9191a.js +1 -0
- package/.next/static/chunks/OrderSummary.994b7314f2d004af.js +1 -0
- package/.next/static/chunks/PreviewTag.696854f6690e1b9e.js +1 -0
- package/.next/static/chunks/ProductShelf.fe1f19bc68859695.js +1 -0
- package/.next/static/chunks/ProductTiles.2c63ae178a75d5b6.js +1 -0
- package/.next/static/chunks/{RegionModal.a7be32d2d7832ba4.js → RegionModal.fbbdd54ee2422522.js} +1 -1
- package/.next/static/chunks/RegionSlider.49e558b340a5506a.js +1 -0
- package/.next/static/chunks/{ScrollToTopButton.c15431f2e8bb93ef.js → ScrollToTopButton.55e3a1233d04b8eb.js} +1 -1
- package/.next/static/chunks/ShoppingAssistant.8772fe90bd678202.js +1 -0
- package/.next/static/chunks/Toast.f083d9966a9a181e.js +1 -0
- package/.next/static/chunks/UISKUMatrixSidebar.01f8f5222dcdf80f.js +1 -0
- package/.next/static/chunks/main-edeb2c6a5c48bb3f.js +1 -0
- package/.next/static/chunks/pages/404-1e8f91fa1bca3ab8.js +1 -0
- package/.next/static/chunks/pages/500-f21feacbb9810e94.js +1 -0
- package/.next/static/chunks/pages/[...slug]-400781188d59cfd6.js +1 -0
- package/.next/static/chunks/pages/[slug]/p-f324b592d1c566b9.js +1 -0
- package/.next/static/chunks/pages/_app-735c745509e1e8d6.js +1 -0
- package/.next/static/chunks/pages/{_error-2b0148be56a716e9.js → _error-464097ff69347627.js} +1 -1
- package/.next/static/chunks/pages/checkout-6076b4baf0ca1aa6.js +1 -0
- package/.next/static/chunks/pages/index-3266ece2e885bb3a.js +1 -0
- package/.next/static/chunks/pages/login-add3b376f68ce39a.js +1 -0
- package/.next/static/chunks/pages/pvt/account/403-d44b70591d2c86dc.js +1 -0
- package/.next/static/chunks/pages/pvt/account/404-646fb609f579101e.js +1 -0
- package/.next/static/chunks/pages/pvt/account/[...unknown]-3fb3963ca3d77c0b.js +1 -0
- package/.next/static/chunks/pages/pvt/account/orders/[id]-cda2266c9693d552.js +1 -0
- package/.next/static/chunks/pages/pvt/account/orders-ec545a2679db206e.js +1 -0
- package/.next/static/chunks/pages/pvt/account/profile-27164b37098c553f.js +1 -0
- package/.next/static/chunks/pages/pvt/account/security-4bd3e75771a120ec.js +1 -0
- package/.next/static/chunks/pages/pvt/account/user-details-a48a44dfdc07c1e9.js +1 -0
- package/.next/static/chunks/pages/pvt/account-5a6dcae3b380b672.js +1 -0
- package/.next/static/chunks/pages/s-0fe527a651dd5989.js +1 -0
- package/.next/static/chunks/webpack-d3e4f545845241c4.js +1 -0
- package/.next/static/css/094ad5cc00c74e64.css +1 -0
- package/.next/static/css/{b684b347c5cc6514.css → 1154064b68a7f35e.css} +1 -1
- package/.next/static/css/1b7e34d448a42825.css +1 -0
- package/.next/static/css/23857075311e4d06.css +1 -0
- package/.next/static/css/482e6fa149885bc2.css +1 -0
- package/.next/static/css/4b2af1aaeb961465.css +1 -0
- package/.next/static/css/{837662922091162f.css → 52ab64b6a2b14e3e.css} +1 -1
- package/.next/static/css/5cd37b7508dd5190.css +1 -0
- package/.next/static/css/72f154a00f1cf621.css +1 -0
- package/.next/static/css/8a513f4b536b0ab0.css +1 -0
- package/.next/static/css/9b4c21dcd3bc4a17.css +1 -0
- package/.next/static/css/d0930b8076866831.css +1 -0
- package/.next/static/css/e028eb9f46d42611.css +1 -0
- package/.next/static/css/e68c313e4ce2fd1b.css +1 -0
- package/.next/static/css/f16438bcf4508fb3.css +1 -0
- package/.next/trace +142 -140
- package/.turbo/turbo-build.log +46 -66
- package/.turbo/turbo-test.log +7 -7
- package/@generated/gql.ts +22 -14
- package/@generated/graphql.ts +148 -55
- package/@generated/persisted-documents.json +5 -4
- package/@generated/schema.graphql +4 -0
- package/CHANGELOG.md +56 -4
- package/cms/faststore/base.jsonc +3 -3
- package/cms/faststore/components/cms_component__productshelf.jsonc +2 -2
- package/cms/faststore/components/cms_component__producttiles.jsonc +2 -2
- package/cms/faststore/schema.json +2510 -2482
- package/cms/faststore/sections.json +485 -4
- package/cypress/tsconfig.json +7 -0
- package/discovery.config.default.js +2 -0
- package/jest.config.js +3 -0
- package/next.config.js +4 -0
- package/package.json +5 -4
- package/public/icons.svg +62 -0
- package/src/components/ThirdPartyScripts/index.ts +1 -0
- package/src/components/ThirdPartyScripts/useShoppingAssistant.tsx +30 -0
- package/src/components/account/MyAccountDrawer/OrganizationDrawer/OrganizationDrawer.tsx +27 -18
- package/src/components/account/MyAccountDrawer/OrganizationDrawer/useReloadAfterLogoutReturn.ts +75 -0
- package/src/components/cms/global/Components.ts +8 -0
- package/src/components/product/ProductGrid/ProductGrid.tsx +26 -1
- package/src/components/search/SearchDropdown/SearchDropdown.tsx +11 -2
- package/src/components/search/SearchInput/SearchInput.tsx +492 -5
- package/src/components/sections/Navbar/Navbar.tsx +67 -0
- package/src/components/sections/Navbar/section.module.scss +3 -0
- package/src/components/sections/ProductDetails/ProductDetails.tsx +1 -0
- package/src/components/sections/ShoppingAssistant/ShoppingAssistant.tsx +24 -0
- package/src/components/sections/ShoppingAssistant/index.ts +1 -0
- package/src/components/sections/ShoppingAssistant/section.module.scss +5 -0
- package/src/components/templates/ProductListingPage/ProductListing.tsx +1 -1
- package/src/components/ui/ProductGallery/ProductGalleryPage.tsx +17 -0
- package/src/pages/[slug]/p.tsx +2 -0
- package/src/pages/_app.tsx +2 -0
- package/src/sdk/graphql/request.ts +1 -1
- package/src/sdk/graphql/useQuery.ts +23 -6
- package/src/sdk/product/convertProductToQuickOrder.ts +85 -0
- package/src/sdk/product/useBulkProductsQuery.ts +128 -0
- package/src/sdk/product/usePageProductsQuery.ts +11 -9
- package/src/sdk/search/useSuggestions.ts +1 -0
- package/src/styles/global/index.scss +2 -1
- package/src/utils/cookieCacheBusting.ts +35 -41
- package/src/utils/utilities.ts +62 -0
- package/test/tsconfig.json +7 -0
- package/test/utils/cookieCacheBusting.test.ts +54 -47
- package/.next/server/chunks/1554.js +0 -1
- package/.next/server/chunks/1780.js +0 -1
- package/.next/server/chunks/2249.js +0 -1
- package/.next/server/chunks/2430.js +0 -1
- package/.next/server/chunks/2445.js +0 -12
- package/.next/server/chunks/2570.js +0 -1
- package/.next/server/chunks/294.js +0 -1
- package/.next/server/chunks/3029.js +0 -1
- package/.next/server/chunks/3836.js +0 -1
- package/.next/server/chunks/3890.js +0 -492
- package/.next/server/chunks/3945.js +0 -1
- package/.next/server/chunks/3951.js +0 -7
- package/.next/server/chunks/4194.js +0 -1
- package/.next/server/chunks/4365.js +0 -1
- package/.next/server/chunks/4803.js +0 -1
- package/.next/server/chunks/4913.js +0 -13
- package/.next/server/chunks/5683.js +0 -1
- package/.next/server/chunks/5723.js +0 -13
- package/.next/server/chunks/6789.js +0 -1
- package/.next/server/chunks/6886.js +0 -1
- package/.next/server/chunks/7098.js +0 -9
- package/.next/server/chunks/7692.js +0 -1
- package/.next/server/chunks/772.js +0 -6
- package/.next/server/chunks/7799.js +0 -1
- package/.next/server/chunks/83.js +0 -1
- package/.next/server/chunks/8307.js +0 -1
- package/.next/server/chunks/8482.js +0 -1
- package/.next/server/chunks/8598.js +0 -1
- package/.next/server/chunks/8687.js +0 -1
- package/.next/server/chunks/870.js +0 -1
- package/.next/server/chunks/9117.js +0 -1
- package/.next/server/chunks/948.js +0 -2
- package/.next/server/chunks/9563.js +0 -3
- package/.next/server/chunks/9853.js +0 -1
- package/.next/server/chunks/9990.js +0 -1
- package/.next/static/Q4xA-lP9ZZhP1GXzClxiR/_buildManifest.js +0 -1
- package/.next/static/chunks/1208-9118a8f14ecf05c8.js +0 -8
- package/.next/static/chunks/1841.a1b15f2c88e02d32.js +0 -1
- package/.next/static/chunks/2284.dffe7b0e5a5bfb4a.js +0 -1
- package/.next/static/chunks/2500.d6beb5af6ee00a9e.js +0 -1
- package/.next/static/chunks/2851.e68ed3c8d27a032a.js +0 -1
- package/.next/static/chunks/3155.7bc4c730a79d9ecb.js +0 -1
- package/.next/static/chunks/3399.3e1f685c992c345b.js +0 -1
- package/.next/static/chunks/3483.ef53d632a763da3f.js +0 -1
- package/.next/static/chunks/349.235b18ceb82aa256.js +0 -1
- package/.next/static/chunks/3836.612763339fc4c64c.js +0 -1
- package/.next/static/chunks/4803.9822f0b7e469b933.js +0 -1
- package/.next/static/chunks/5859.3bc094416cffd966.js +0 -1
- package/.next/static/chunks/6031-b0b111f48a7d504d.js +0 -28
- package/.next/static/chunks/6700.a72869377e81146c.js +0 -1
- package/.next/static/chunks/6789.960162355435a81d.js +0 -1
- package/.next/static/chunks/7191-5ede6e7ef625ea77.js +0 -1
- package/.next/static/chunks/7522-9010743f5d7e8aca.js +0 -1
- package/.next/static/chunks/7692.8d5bf4560341a2f6.js +0 -1
- package/.next/static/chunks/83.98ce246c274ee7e4.js +0 -1
- package/.next/static/chunks/9173-ab3c4d9d8f978c4b.js +0 -1
- package/.next/static/chunks/9399.48251a278809f7d3.js +0 -1
- package/.next/static/chunks/941.3e2782ab9c490eb0.js +0 -1
- package/.next/static/chunks/9465.e09b81f7e6195587.js +0 -1
- package/.next/static/chunks/9701.b0e8741551995fbb.js +0 -1
- package/.next/static/chunks/9909.787576b171184aa5.js +0 -1
- package/.next/static/chunks/BannerNewsletter.90d4a98c15a35cea.js +0 -1
- package/.next/static/chunks/CartItem.092df07db9e8b271.js +0 -1
- package/.next/static/chunks/CartSidebar.f0c16e2bc6f96e9e.js +0 -1
- package/.next/static/chunks/Footer.63a7682a81a96f8e.js +0 -1
- package/.next/static/chunks/Gift.08db4da8c89cacf1.js +0 -1
- package/.next/static/chunks/Newsletter.dbf35a8ea6d2067e.js +0 -1
- package/.next/static/chunks/OrderSummary.f9adad5622605046.js +0 -1
- package/.next/static/chunks/PreviewTag.f4f0c8710a7bcad9.js +0 -1
- package/.next/static/chunks/ProductShelf.7ebce1c763b4508e.js +0 -1
- package/.next/static/chunks/ProductTiles.18f55314e61957f4.js +0 -1
- package/.next/static/chunks/RegionSlider.b4dd4e7c0483966d.js +0 -1
- package/.next/static/chunks/Toast.2e9b26159af29889.js +0 -1
- package/.next/static/chunks/UISKUMatrixSidebar.87ba393b7d738e99.js +0 -1
- package/.next/static/chunks/main-ec03882c4375091d.js +0 -1
- package/.next/static/chunks/pages/404-4b3f1e22c77f849a.js +0 -1
- package/.next/static/chunks/pages/500-bb2de0c11524b2b8.js +0 -1
- package/.next/static/chunks/pages/[...slug]-3579b3b8b8309552.js +0 -1
- package/.next/static/chunks/pages/[slug]/p-7ac98274c47b0ff4.js +0 -1
- package/.next/static/chunks/pages/_app-1595678557980d65.js +0 -1
- package/.next/static/chunks/pages/checkout-dc07d72b3514c83d.js +0 -1
- package/.next/static/chunks/pages/index-1f8bf0fb351b90f4.js +0 -1
- package/.next/static/chunks/pages/login-e97ef92769456bf6.js +0 -1
- package/.next/static/chunks/pages/pvt/account/403-91597100f8956385.js +0 -1
- package/.next/static/chunks/pages/pvt/account/404-c68124bed7cb7c48.js +0 -1
- package/.next/static/chunks/pages/pvt/account/[...unknown]-f80f645594d2740c.js +0 -1
- package/.next/static/chunks/pages/pvt/account/orders/[id]-e03ebb0393ac92a2.js +0 -1
- package/.next/static/chunks/pages/pvt/account/orders-12a215899ae6f3eb.js +0 -1
- package/.next/static/chunks/pages/pvt/account/profile-b6cdbf02d4682544.js +0 -1
- package/.next/static/chunks/pages/pvt/account/security-e6289a40e745d3c4.js +0 -1
- package/.next/static/chunks/pages/pvt/account/user-details-fba1822e52e7de26.js +0 -1
- package/.next/static/chunks/pages/pvt/account-65fefcc699344bdb.js +0 -1
- package/.next/static/chunks/pages/s-41cffb20de1d2617.js +0 -1
- package/.next/static/chunks/webpack-345c083b2f1f8bb9.js +0 -1
- package/.next/static/css/05c399956ff24b77.css +0 -1
- package/.next/static/css/08d03445f1797608.css +0 -1
- package/.next/static/css/0f070d03aacd9cc5.css +0 -1
- package/.next/static/css/0fae3d432331aae9.css +0 -1
- package/.next/static/css/0fc6b2ff69142c6a.css +0 -1
- package/.next/static/css/31380ebc6e671486.css +0 -1
- package/.next/static/css/40a294d0a24ad01d.css +0 -1
- package/.next/static/css/47f1b4e8de15d314.css +0 -1
- package/.next/static/css/973dd40d4773e8cd.css +0 -1
- package/.next/static/css/9d403a1bee48c9fc.css +0 -1
- package/.next/static/css/a6a4ebbe01adbbad.css +0 -1
- /package/.next/static/{Q4xA-lP9ZZhP1GXzClxiR → Xu5Fn6_Qwp_x6LicEI8BU}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useRef } from 'react'
|
|
2
|
+
|
|
3
|
+
import { useShoppingAssistant } from 'src/components/ThirdPartyScripts'
|
|
4
|
+
|
|
5
|
+
import Section from '../Section'
|
|
6
|
+
|
|
7
|
+
import styles from './section.module.scss'
|
|
8
|
+
|
|
9
|
+
const ShoppingAssistant = () => {
|
|
10
|
+
const scriptContainerRef = useRef<HTMLDivElement>(null)
|
|
11
|
+
useShoppingAssistant(scriptContainerRef)
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<Section
|
|
15
|
+
className={`${styles.section} section-shopping-assistant layout__section`}
|
|
16
|
+
>
|
|
17
|
+
<div ref={scriptContainerRef} aria-hidden="true" hidden />
|
|
18
|
+
</Section>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
ShoppingAssistant.$componentKey = 'ShoppingAssistant'
|
|
23
|
+
|
|
24
|
+
export default ShoppingAssistant
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './ShoppingAssistant'
|
|
@@ -73,7 +73,7 @@ export default function ProductListing({
|
|
|
73
73
|
itemsPerPage,
|
|
74
74
|
})
|
|
75
75
|
|
|
76
|
-
const initialPages = { search: server?.search }
|
|
76
|
+
const initialPages = { search: { ...server?.search, searchId: '' } }
|
|
77
77
|
const { pages, useGalleryPage } = useCreateUseGalleryPage({
|
|
78
78
|
initialPages,
|
|
79
79
|
serverManyProductsVariables,
|
|
@@ -18,6 +18,20 @@ interface Props {
|
|
|
18
18
|
compareLabel?: string
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
function buildExtraProductProps(
|
|
22
|
+
product: Record<string, string>,
|
|
23
|
+
index: number,
|
|
24
|
+
searchId: string
|
|
25
|
+
) {
|
|
26
|
+
return {
|
|
27
|
+
'data-af-element': 'search-result',
|
|
28
|
+
'data-af-onclick': product && !!product.productId,
|
|
29
|
+
'data-af-search-id': searchId,
|
|
30
|
+
'data-af-product-position': Number(index ?? 0) + 1, // Product position in Search Analytics starts with 1
|
|
31
|
+
'data-af-product-id': product && product.productId,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
21
35
|
function ProductGalleryPage({
|
|
22
36
|
page,
|
|
23
37
|
title,
|
|
@@ -30,6 +44,7 @@ function ProductGalleryPage({
|
|
|
30
44
|
const { data } = useGalleryPage(page)
|
|
31
45
|
|
|
32
46
|
const products = data?.search?.products?.edges ?? []
|
|
47
|
+
const searchId = data?.search?.searchId
|
|
33
48
|
|
|
34
49
|
return (
|
|
35
50
|
<Sentinel
|
|
@@ -47,6 +62,8 @@ function ProductGalleryPage({
|
|
|
47
62
|
productCard={productCard}
|
|
48
63
|
firstPage={firstPage}
|
|
49
64
|
title={title}
|
|
65
|
+
searchId={searchId}
|
|
66
|
+
buildExtraProductProps={searchId && buildExtraProductProps}
|
|
50
67
|
/>
|
|
51
68
|
</Sentinel>
|
|
52
69
|
)
|
package/src/pages/[slug]/p.tsx
CHANGED
|
@@ -208,6 +208,7 @@ function Page({
|
|
|
208
208
|
brand={product.brand.name}
|
|
209
209
|
sku={product.sku}
|
|
210
210
|
gtin={product.gtin}
|
|
211
|
+
mpn={product.mpn}
|
|
211
212
|
releaseDate={product.releaseDate}
|
|
212
213
|
images={product.image.map((img) => img.url)} // Somehow, Google does not understand this valid Schema.org schema, so we need to do conversions
|
|
213
214
|
offers={offers}
|
|
@@ -256,6 +257,7 @@ const query = gql(`
|
|
|
256
257
|
|
|
257
258
|
sku
|
|
258
259
|
gtin
|
|
260
|
+
mpn
|
|
259
261
|
name
|
|
260
262
|
description
|
|
261
263
|
releaseDate
|
package/src/pages/_app.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import { useRouter } from 'next/router'
|
|
|
6
6
|
import { useSearch } from '@faststore/sdk'
|
|
7
7
|
import { UIProvider } from '@faststore/ui'
|
|
8
8
|
|
|
9
|
+
import { useReloadAfterLogoutReturn } from 'src/components/account/MyAccountDrawer/OrganizationDrawer/useReloadAfterLogoutReturn'
|
|
9
10
|
import ThirdPartyScripts from 'src/components/ThirdPartyScripts'
|
|
10
11
|
import Layout from 'src/Layout'
|
|
11
12
|
import AnalyticsHandler from 'src/sdk/analytics'
|
|
@@ -24,6 +25,7 @@ import { ITEMS_PER_PAGE } from 'src/constants'
|
|
|
24
25
|
|
|
25
26
|
function App({ Component, pageProps }: AppProps) {
|
|
26
27
|
useGeolocation()
|
|
28
|
+
useReloadAfterLogoutReturn()
|
|
27
29
|
storeConfig.experimental?.scrollRestoration && useScrollRestoration()
|
|
28
30
|
const router = useRouter()
|
|
29
31
|
const { start: startGlobalSearchState } = useSearch()
|
|
@@ -29,7 +29,7 @@ export const request = async <Query = unknown, Variables = unknown>(
|
|
|
29
29
|
variables: Variables,
|
|
30
30
|
options?: RequestOptions
|
|
31
31
|
) => {
|
|
32
|
-
// Get cache busting value based
|
|
32
|
+
// Get cache busting value based person?.id from session
|
|
33
33
|
const value = getClientCacheBustingValue()
|
|
34
34
|
|
|
35
35
|
const { data, errors } = await baseRequest<Variables, Query>('/api/graphql', {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import useSWR from 'swr'
|
|
2
1
|
import type { SWRConfiguration } from 'swr'
|
|
2
|
+
import useSWR from 'swr'
|
|
3
|
+
|
|
4
|
+
import { getClientCacheBustingValue } from 'src/utils/cookieCacheBusting'
|
|
3
5
|
|
|
4
|
-
import { request } from './request'
|
|
5
6
|
import type { Operation, RequestOptions } from './request'
|
|
7
|
+
import { request } from './request'
|
|
6
8
|
|
|
7
9
|
export type QueryOptions = SWRConfiguration &
|
|
8
10
|
RequestOptions & { doNotRun?: boolean }
|
|
@@ -12,6 +14,19 @@ export const getKey = <Variables>(
|
|
|
12
14
|
variables: Variables
|
|
13
15
|
) => `${operationName}::${JSON.stringify(variables)}`
|
|
14
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Returns a suffix for the cache key based on auth state (logged-in vs anonymous).
|
|
19
|
+
* This ensures SWR keeps separate cache entries for logged-in and logged-out users,
|
|
20
|
+
* avoiding stale product data (e.g. prices, availability) when switching session state.
|
|
21
|
+
*/
|
|
22
|
+
const getSessionCacheKeySuffix = (): string => {
|
|
23
|
+
if (typeof window === 'undefined') {
|
|
24
|
+
return ''
|
|
25
|
+
}
|
|
26
|
+
const value = getClientCacheBustingValue()
|
|
27
|
+
return value ?? ''
|
|
28
|
+
}
|
|
29
|
+
|
|
15
30
|
export const DEFAULT_OPTIONS = {
|
|
16
31
|
errorRetryCount: 3,
|
|
17
32
|
refreshWhenHidden: false,
|
|
@@ -27,10 +42,12 @@ export const useQuery = <Data, Variables = Record<string, unknown>>(
|
|
|
27
42
|
options?: QueryOptions
|
|
28
43
|
) =>
|
|
29
44
|
useSWR<Data>(
|
|
30
|
-
() =>
|
|
31
|
-
options?.doNotRun
|
|
32
|
-
|
|
33
|
-
|
|
45
|
+
() => {
|
|
46
|
+
if (options?.doNotRun) return null
|
|
47
|
+
const baseKey = getKey(operation['__meta__']['operationName'], variables)
|
|
48
|
+
const sessionSuffix = getSessionCacheKeySuffix()
|
|
49
|
+
return `${baseKey}::${sessionSuffix}`
|
|
50
|
+
},
|
|
34
51
|
{
|
|
35
52
|
fetcher: () => {
|
|
36
53
|
return new Promise((resolve) => {
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { Product } from '@faststore/ui'
|
|
2
|
+
import type { ProductDetailsFragment_ProductFragment } from '@generated/graphql'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Converts a product from the API to the format expected by QuickOrderDrawer
|
|
6
|
+
*/
|
|
7
|
+
export const convertProductToQuickOrder = (
|
|
8
|
+
product: ProductDetailsFragment_ProductFragment,
|
|
9
|
+
requestedQuantity: number
|
|
10
|
+
): Product | null => {
|
|
11
|
+
if (!product || !product.offers || !product.offers.offers.length) {
|
|
12
|
+
return null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const offer = product.offers.offers[0]
|
|
16
|
+
|
|
17
|
+
// Determine availability based on the offer's availability field
|
|
18
|
+
// Availability can be 'https://schema.org/InStock' or 'https://schema.org/OutOfStock'
|
|
19
|
+
const isOutOfStock = offer.availability === 'https://schema.org/OutOfStock'
|
|
20
|
+
const isInStock = offer.availability === 'https://schema.org/InStock'
|
|
21
|
+
|
|
22
|
+
// Get inventory quantity from the offer
|
|
23
|
+
// If quantity is not provided, we'll use a default high value when InStock
|
|
24
|
+
// This handles cases where the API doesn't return quantity but marks it as InStock
|
|
25
|
+
const offerQuantity = (offer as { quantity?: number | null }).quantity
|
|
26
|
+
const inventory =
|
|
27
|
+
offerQuantity != null
|
|
28
|
+
? offerQuantity
|
|
29
|
+
: isInStock
|
|
30
|
+
? 999999 // Default to high inventory when InStock but quantity not provided
|
|
31
|
+
: 0
|
|
32
|
+
|
|
33
|
+
// Product is available if it's in stock
|
|
34
|
+
// If quantity is provided, we also check it, but availability field takes precedence
|
|
35
|
+
const availability = isInStock ? 'available' : 'outOfStock'
|
|
36
|
+
|
|
37
|
+
// Determine selectedCount and quantityUpdated based on availability and inventory
|
|
38
|
+
let selectedCount: number
|
|
39
|
+
let quantityUpdated: boolean
|
|
40
|
+
const normalizedRequestedQuantity =
|
|
41
|
+
Number.isFinite(requestedQuantity) && requestedQuantity > 0
|
|
42
|
+
? Math.floor(requestedQuantity)
|
|
43
|
+
: 1
|
|
44
|
+
|
|
45
|
+
if (isOutOfStock) {
|
|
46
|
+
// Out of stock: set quantity to 0
|
|
47
|
+
selectedCount = 0
|
|
48
|
+
quantityUpdated = true
|
|
49
|
+
} else if (inventory === 0) {
|
|
50
|
+
// Inventory is 0 but marked as InStock (edge case): set quantity to 0
|
|
51
|
+
selectedCount = 0
|
|
52
|
+
quantityUpdated = true
|
|
53
|
+
} else if (offerQuantity != null && normalizedRequestedQuantity > inventory) {
|
|
54
|
+
// Quantity is provided and requested quantity exceeds inventory: cap at inventory
|
|
55
|
+
selectedCount = inventory
|
|
56
|
+
quantityUpdated = true
|
|
57
|
+
} else {
|
|
58
|
+
// Requested quantity is within inventory (or quantity not provided): use requested quantity
|
|
59
|
+
selectedCount = normalizedRequestedQuantity
|
|
60
|
+
quantityUpdated = normalizedRequestedQuantity !== requestedQuantity
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Get the variant name from allVariantProducts that matches this product's SKU
|
|
64
|
+
// This ensures we use the correct variant name instead of the product name
|
|
65
|
+
const variantProduct =
|
|
66
|
+
product.isVariantOf?.skuVariants?.allVariantProducts?.find(
|
|
67
|
+
(variant) =>
|
|
68
|
+
variant.productID === product.id || variant.productID === product.sku
|
|
69
|
+
)
|
|
70
|
+
const productName = variantProduct?.name ?? product.name
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
id: product.sku,
|
|
74
|
+
name: productName,
|
|
75
|
+
price: offer.price,
|
|
76
|
+
quantityUpdated,
|
|
77
|
+
image: {
|
|
78
|
+
url: product.image[0]?.url ?? '',
|
|
79
|
+
alternateName: product.image[0]?.alternateName || product.name,
|
|
80
|
+
},
|
|
81
|
+
inventory,
|
|
82
|
+
availability: availability as 'available' | 'outOfStock',
|
|
83
|
+
selectedCount,
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import { gql } from '@generated'
|
|
4
|
+
import type {
|
|
5
|
+
ClientProductQueryQuery,
|
|
6
|
+
ClientProductQueryQueryVariables,
|
|
7
|
+
} from '@generated/graphql'
|
|
8
|
+
|
|
9
|
+
import { request } from '../graphql/request'
|
|
10
|
+
import { useSession } from '../session'
|
|
11
|
+
|
|
12
|
+
// Use the same query as useProductQuery for individual products
|
|
13
|
+
const query = gql(`
|
|
14
|
+
query ClientProductQuery($locator: [IStoreSelectedFacet!]!) {
|
|
15
|
+
...ClientProduct
|
|
16
|
+
product(locator: $locator) {
|
|
17
|
+
...ProductDetailsFragment_product
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`)
|
|
21
|
+
|
|
22
|
+
export interface BulkProductData {
|
|
23
|
+
sku: string
|
|
24
|
+
product?: ClientProductQueryQuery['product']
|
|
25
|
+
error?: Error
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Batch size to avoid overwhelming the server
|
|
29
|
+
const BATCH_SIZE = 10
|
|
30
|
+
const BATCH_DELAY_MS = 100
|
|
31
|
+
|
|
32
|
+
export const useBulkProductsQuery = (skus: string[]) => {
|
|
33
|
+
const { channel, locale } = useSession()
|
|
34
|
+
const [products, setProducts] = useState<BulkProductData[]>([])
|
|
35
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
36
|
+
const [error, setError] = useState<Error | null>(null)
|
|
37
|
+
|
|
38
|
+
// Create a stable key for the SKUs array to use as a dependency
|
|
39
|
+
const skusKey = useMemo(() => {
|
|
40
|
+
return skus.join(',')
|
|
41
|
+
}, [skus])
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (skus.length === 0) {
|
|
45
|
+
setProducts([])
|
|
46
|
+
setIsLoading(false)
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const fetchProducts = async () => {
|
|
51
|
+
setIsLoading(true)
|
|
52
|
+
setError(null)
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
if (!channel) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`useBulkProductsQuery: 'channel' from session is an empty string.`
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const results: BulkProductData[] = []
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < skus.length; i += BATCH_SIZE) {
|
|
64
|
+
const batch = skus.slice(i, i + BATCH_SIZE)
|
|
65
|
+
|
|
66
|
+
const batchPromises = batch.map(
|
|
67
|
+
async (sku): Promise<BulkProductData> => {
|
|
68
|
+
try {
|
|
69
|
+
const variables: ClientProductQueryQueryVariables = {
|
|
70
|
+
locator: [
|
|
71
|
+
{ key: 'id', value: sku },
|
|
72
|
+
{ key: 'channel', value: channel },
|
|
73
|
+
{ key: 'locale', value: locale },
|
|
74
|
+
],
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Use POST method to avoid URL length issues with GET
|
|
78
|
+
const data = await request<
|
|
79
|
+
ClientProductQueryQuery,
|
|
80
|
+
ClientProductQueryQueryVariables
|
|
81
|
+
>(query, variables, {
|
|
82
|
+
fetchOptions: {
|
|
83
|
+
method: 'POST',
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
sku,
|
|
89
|
+
product: data.product,
|
|
90
|
+
}
|
|
91
|
+
} catch (err) {
|
|
92
|
+
console.error(`Failed to fetch product ${sku}:`, err)
|
|
93
|
+
return {
|
|
94
|
+
sku,
|
|
95
|
+
error:
|
|
96
|
+
err instanceof Error
|
|
97
|
+
? err
|
|
98
|
+
: new Error(`Failed to fetch product: ${sku}`),
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
const batchResults = await Promise.all(batchPromises)
|
|
105
|
+
results.push(...batchResults)
|
|
106
|
+
|
|
107
|
+
// Add a small delay between batches to avoid rate limiting
|
|
108
|
+
if (i + BATCH_SIZE < skus.length) {
|
|
109
|
+
await new Promise((resolve) => setTimeout(resolve, BATCH_DELAY_MS))
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
setProducts(results)
|
|
114
|
+
} catch (err) {
|
|
115
|
+
setError(
|
|
116
|
+
err instanceof Error ? err : new Error('Failed to fetch products')
|
|
117
|
+
)
|
|
118
|
+
setProducts([])
|
|
119
|
+
} finally {
|
|
120
|
+
setIsLoading(false)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
fetchProducts()
|
|
125
|
+
}, [skusKey, channel, locale, skus.length])
|
|
126
|
+
|
|
127
|
+
return { products, isLoading, error }
|
|
128
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useSearch } from '@faststore/sdk'
|
|
2
2
|
import { gql } from '@generated'
|
|
3
3
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
ClientManyProductsQueryWithSearchIdQuery,
|
|
5
|
+
ClientManyProductsQueryWithSearchIdQueryVariables,
|
|
6
6
|
} from '@generated/graphql'
|
|
7
7
|
import deepEquals from 'fast-deep-equal'
|
|
8
8
|
import {
|
|
@@ -34,7 +34,7 @@ export const useGalleryPage = (page: number) => {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export const query = gql(`
|
|
37
|
-
query
|
|
37
|
+
query ClientManyProductsQueryWithSearchId(
|
|
38
38
|
$first: Int!
|
|
39
39
|
$after: String
|
|
40
40
|
$sort: StoreSort!
|
|
@@ -61,6 +61,7 @@ export const query = gql(`
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
+
searchId
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
`)
|
|
@@ -68,8 +69,8 @@ export const query = gql(`
|
|
|
68
69
|
const getKey = (object: any) => JSON.stringify(object)
|
|
69
70
|
|
|
70
71
|
interface UseCreateUseGalleryPageProps {
|
|
71
|
-
initialPages:
|
|
72
|
-
serverManyProductsVariables:
|
|
72
|
+
initialPages: ClientManyProductsQueryWithSearchIdQuery
|
|
73
|
+
serverManyProductsVariables: ClientManyProductsQueryWithSearchIdQueryVariables
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
/**
|
|
@@ -84,9 +85,10 @@ export const useCreateUseGalleryPage = (
|
|
|
84
85
|
: []
|
|
85
86
|
|
|
86
87
|
const [pages, setPages] =
|
|
87
|
-
useState<
|
|
88
|
+
useState<ClientManyProductsQueryWithSearchIdQuery[]>(initialPages)
|
|
88
89
|
// We create pagesRef as a mirror of the pages state so we don't have to add pages as a dependency of the useGalleryPage hook
|
|
89
|
-
const pagesRef =
|
|
90
|
+
const pagesRef =
|
|
91
|
+
useRef<ClientManyProductsQueryWithSearchIdQuery[]>(initialPages)
|
|
90
92
|
const pagesCache = useRef<string[]>(initialVariables)
|
|
91
93
|
|
|
92
94
|
const useGalleryPage = useCallback(function useGalleryPage(page: number) {
|
|
@@ -116,8 +118,8 @@ export const useCreateUseGalleryPage = (
|
|
|
116
118
|
const shouldFetch = !hasSameVariables || shouldFetchFirstPage
|
|
117
119
|
|
|
118
120
|
const { data } = useQuery<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
ClientManyProductsQueryWithSearchIdQuery,
|
|
122
|
+
ClientManyProductsQueryWithSearchIdQueryVariables
|
|
121
123
|
>(query, localizedVariables, {
|
|
122
124
|
fallbackData: null,
|
|
123
125
|
suspense: true,
|
|
@@ -11,4 +11,5 @@
|
|
|
11
11
|
@import "src/components/sections/Section/section.scss";
|
|
12
12
|
|
|
13
13
|
// Importing this component because is being used outside the context of the Section
|
|
14
|
-
@import "@faststore/ui/src/components/
|
|
14
|
+
@import "@faststore/ui/src/components/organisms/QuickOrderDrawer/styles.scss";
|
|
15
|
+
@import "@faststore/ui/src/components/organisms/SlideOver/styles.scss";
|
|
@@ -1,59 +1,49 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { sessionStore } from 'src/sdk/session'
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const STORAGE_KEY_PERSON_ID = 'faststore_person_id'
|
|
4
4
|
export const STORAGE_KEY_CACHE_BUST_LAST_VALUE =
|
|
5
5
|
'faststore_cache_bust_last_value'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Gets
|
|
9
|
-
*
|
|
10
|
-
* so we only monitor VtexIdclientAutCookie_<account>
|
|
8
|
+
* Gets person?.id from session (via ValidateSession).
|
|
9
|
+
* Reads session store directly since auth cookies are httpOnly and inaccessible via JavaScript.
|
|
11
10
|
*/
|
|
12
|
-
const
|
|
13
|
-
if (typeof
|
|
11
|
+
const getPersonId = (): string | null => {
|
|
12
|
+
if (typeof window === 'undefined') {
|
|
14
13
|
return null
|
|
15
14
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const authCookieName = `VtexIdclientAutCookie_${account}`
|
|
19
|
-
const cookies = document.cookie.split(';').map((cookie) => cookie.trim())
|
|
20
|
-
const authCookie = cookies.find((c) => c.startsWith(`${authCookieName}=`))
|
|
21
|
-
|
|
22
|
-
if (!authCookie) {
|
|
23
|
-
return null
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return authCookie.split('=').slice(1).join('=')
|
|
15
|
+
const session = sessionStore.read() ?? sessionStore.readInitial()
|
|
16
|
+
return session?.person?.id ?? null
|
|
27
17
|
}
|
|
28
18
|
|
|
29
19
|
/**
|
|
30
|
-
* Gets the stored
|
|
20
|
+
* Gets the stored person id from sessionStorage (client-side only)
|
|
31
21
|
*/
|
|
32
|
-
const
|
|
22
|
+
const getStoredPersonId = (): string | null => {
|
|
33
23
|
if (typeof sessionStorage === 'undefined') {
|
|
34
24
|
return null
|
|
35
25
|
}
|
|
36
26
|
|
|
37
27
|
try {
|
|
38
|
-
return sessionStorage.getItem(
|
|
28
|
+
return sessionStorage.getItem(STORAGE_KEY_PERSON_ID)
|
|
39
29
|
} catch {
|
|
40
30
|
return null
|
|
41
31
|
}
|
|
42
32
|
}
|
|
43
33
|
|
|
44
34
|
/**
|
|
45
|
-
* Stores the
|
|
35
|
+
* Stores the person id in sessionStorage (client-side only)
|
|
46
36
|
*/
|
|
47
|
-
const
|
|
37
|
+
const storePersonId = (value: string | null): void => {
|
|
48
38
|
if (typeof sessionStorage === 'undefined') {
|
|
49
39
|
return
|
|
50
40
|
}
|
|
51
41
|
|
|
52
42
|
try {
|
|
53
43
|
if (value === null) {
|
|
54
|
-
sessionStorage.removeItem(
|
|
44
|
+
sessionStorage.removeItem(STORAGE_KEY_PERSON_ID)
|
|
55
45
|
} else {
|
|
56
|
-
sessionStorage.setItem(
|
|
46
|
+
sessionStorage.setItem(STORAGE_KEY_PERSON_ID, value)
|
|
57
47
|
}
|
|
58
48
|
} catch {
|
|
59
49
|
// Ignore storage errors
|
|
@@ -93,13 +83,13 @@ const storeLastValue = (value: string): void => {
|
|
|
93
83
|
/**
|
|
94
84
|
* Clears all cache busting related data from sessionStorage (client-side only)
|
|
95
85
|
*/
|
|
96
|
-
const
|
|
86
|
+
const clearCacheBustingStorage = (): void => {
|
|
97
87
|
if (typeof sessionStorage === 'undefined') {
|
|
98
88
|
return
|
|
99
89
|
}
|
|
100
90
|
|
|
101
91
|
try {
|
|
102
|
-
sessionStorage.removeItem(
|
|
92
|
+
sessionStorage.removeItem(STORAGE_KEY_PERSON_ID)
|
|
103
93
|
sessionStorage.removeItem(STORAGE_KEY_CACHE_BUST_LAST_VALUE)
|
|
104
94
|
} catch {
|
|
105
95
|
// Ignore storage errors
|
|
@@ -107,28 +97,31 @@ const clearStorage = (): void => {
|
|
|
107
97
|
}
|
|
108
98
|
|
|
109
99
|
/**
|
|
110
|
-
* Gets cache busting value for client-side based on auth
|
|
100
|
+
* Gets cache busting value for client-side based on auth state changes.
|
|
101
|
+
* Uses person?.id from session (via useSession/ValidateSession) since auth cookies
|
|
102
|
+
* are now httpOnly and cannot be accessed via JavaScript.
|
|
111
103
|
*/
|
|
112
104
|
export const getClientCacheBustingValue = (): string | null => {
|
|
113
|
-
const
|
|
105
|
+
const currentPersonId = getPersonId()
|
|
114
106
|
|
|
115
|
-
// Guard clause: if
|
|
116
|
-
if (
|
|
117
|
-
|
|
107
|
+
// Guard clause: if user is not logged in (no person?.id), clear storage and don't proceed with cache busting logic
|
|
108
|
+
if (currentPersonId === null) {
|
|
109
|
+
clearCacheBustingStorage()
|
|
118
110
|
return null
|
|
119
111
|
}
|
|
120
112
|
|
|
121
|
-
const
|
|
113
|
+
const storedPersonId = getStoredPersonId()
|
|
122
114
|
|
|
123
|
-
// If
|
|
124
|
-
if (
|
|
125
|
-
|
|
115
|
+
// If person changed (login/logout or different user), update stored value and return new value
|
|
116
|
+
if (currentPersonId !== storedPersonId) {
|
|
117
|
+
storePersonId(currentPersonId)
|
|
126
118
|
const timestamp = Date.now().toString()
|
|
127
|
-
|
|
128
|
-
|
|
119
|
+
const value = `${timestamp}::${currentPersonId}`
|
|
120
|
+
storeLastValue(value)
|
|
121
|
+
return value
|
|
129
122
|
}
|
|
130
123
|
|
|
131
|
-
//
|
|
124
|
+
// Person hasn't changed, return last value or create one if it doesn't exist
|
|
132
125
|
const lastValue = getLastValue()
|
|
133
126
|
if (lastValue) {
|
|
134
127
|
return lastValue
|
|
@@ -136,6 +129,7 @@ export const getClientCacheBustingValue = (): string | null => {
|
|
|
136
129
|
|
|
137
130
|
// Fallback: if no last value, create one
|
|
138
131
|
const timestamp = Date.now().toString()
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
const value = `${timestamp}::${currentPersonId}`
|
|
133
|
+
storeLastValue(value)
|
|
134
|
+
return value
|
|
141
135
|
}
|