@faststore/core 3.42.0 → 3.44.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 +55 -55
- 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 +65 -65
- package/.next/routes-manifest.json +1 -1
- package/.next/server/chunks/1506.js +1 -1
- package/.next/server/chunks/2443.js +1 -0
- package/.next/server/chunks/2524.js +1 -0
- package/.next/server/chunks/4289.js +2 -362
- package/.next/server/chunks/4559.js +361 -0
- package/.next/server/chunks/4725.js +1 -0
- package/.next/server/chunks/4746.js +1 -1
- package/.next/server/chunks/5474.js +6 -0
- package/.next/server/chunks/5607.js +1 -0
- package/.next/server/chunks/563.js +1 -1
- package/.next/server/chunks/6594.js +1 -1
- package/.next/server/chunks/674.js +1 -1
- package/.next/server/chunks/6968.js +10 -0
- package/.next/server/chunks/7986.js +6 -1
- package/.next/server/chunks/804.js +1 -0
- package/.next/server/chunks/831.js +1 -1
- package/.next/server/chunks/8562.js +1 -1
- package/.next/server/chunks/8646.js +1 -1
- package/.next/server/chunks/ButtonSignIn.js +1 -1
- package/.next/server/chunks/UIBannerText.js +1 -1
- package/.next/server/chunks/UISKUMatrixSidebar.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 +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/account/profile.js +1 -1
- package/.next/server/pages/account/profile.js.nft.json +1 -1
- package/.next/server/pages/account.js +1 -1
- package/.next/server/pages/account.js.nft.json +1 -1
- package/.next/server/pages/api/graphql.js +2 -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/500.html +2 -2
- package/.next/server/pages/en-US/checkout.html +2 -2
- package/.next/server/pages/en-US/login.html +2 -2
- package/.next/server/pages/en-US/s.html +2 -2
- package/.next/server/pages/en-US.html +2 -2
- 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/static/U_9W0qMyv_4RQSLFdrtHC/_buildManifest.js +1 -0
- package/.next/static/chunks/{1153.ed17e19083f51bdb.js → 1153.8f0ac867c4ddce90.js} +1 -1
- package/.next/static/chunks/1173.ca14a5bc4e1264f4.js +1 -0
- package/.next/static/chunks/1418-e86227bcf9a5d486.js +28 -0
- package/.next/static/chunks/1552.8751332da83cadc5.js +1 -0
- package/.next/static/chunks/{6076.d80e37e35892bafc.js → 3684.3e6f435506c2c7c9.js} +1 -1
- package/.next/static/chunks/417.edbb75ab2f55482f.js +1 -0
- package/.next/static/chunks/{4349-6fc936580b772e67.js → 4349-87a956a73b97519c.js} +1 -1
- package/.next/static/chunks/{4625-9a273e78866c389b.js → 4625-553d20c86b0ca577.js} +1 -1
- package/.next/static/chunks/{4746.19eddeaeb33ea820.js → 4746.2e16ec0663a3873f.js} +1 -1
- package/.next/static/chunks/{4774.907a71a04126d57c.js → 4774.8e70c01dcd0ed4b3.js} +1 -1
- package/.next/static/chunks/{4865.3e2ae9feb511c870.js → 4865.4017be0f8e7c8cf0.js} +1 -1
- package/.next/static/chunks/5836.c5c244a8cbfa7f7d.js +1 -0
- package/.next/static/chunks/630.13d3dd939b789798.js +6 -0
- package/.next/static/chunks/6335-6eb4ff84af184b88.js +1 -0
- package/.next/static/chunks/6536.d5260107222db13c.js +1 -0
- package/.next/static/chunks/{7195.e88924bd232c58b7.js → 7195.fd4cacc0bef1a233.js} +1 -1
- package/.next/static/chunks/7498-72289e704e7c7056.js +1 -0
- package/.next/static/chunks/7959.7c721505286572c0.js +1 -0
- package/.next/static/chunks/9.89f24163370f3a22.js +1 -0
- package/.next/static/chunks/BannerNewsletter.8982f42e60ed8828.js +1 -0
- package/.next/static/chunks/{ButtonSignIn.df0e3ce490436fe2.js → ButtonSignIn.bff8dc7b2133806c.js} +1 -1
- package/.next/static/chunks/CartItem.f2493be7c504f22f.js +1 -0
- package/.next/static/chunks/{CartSidebar.26d3e39bf93a368f.js → CartSidebar.aa9e43be37034654.js} +1 -1
- package/.next/static/chunks/{Gift.affb75f8f7bcb6db.js → Gift.375356d6a74e2693.js} +1 -1
- package/.next/static/chunks/Newsletter.9db4df2d4fb33227.js +1 -0
- package/.next/static/chunks/OrderSummary.e6e0a3af3c224b4e.js +1 -0
- package/.next/static/chunks/ProductShelf.9cea36116836c161.js +1 -0
- package/.next/static/chunks/ProductTiles.059a4a6360e1d4ea.js +1 -0
- package/.next/static/chunks/RegionModal.4594b707a1092551.js +1 -0
- package/.next/static/chunks/UIBannerText.45cf608e46cde628.js +1 -0
- package/.next/static/chunks/UIButton.3186f933c0ecfb31.js +1 -0
- package/.next/static/chunks/UISKUMatrixSidebar.9ac3980a60cfc358.js +1 -0
- package/.next/static/chunks/UIToast.221eb10681d2f642.js +1 -0
- package/.next/static/chunks/pages/{404-8e61ea158e7b314c.js → 404-6300c433469b7262.js} +1 -1
- package/.next/static/chunks/pages/{500-68f51177e64de6e7.js → 500-2d1dd344c8a8827f.js} +1 -1
- package/.next/static/chunks/pages/[...slug]-c1a62d58f5940747.js +1 -0
- package/.next/static/chunks/pages/[slug]/p-555dc09a5e78260e.js +1 -0
- package/.next/static/chunks/pages/_app-929466ed763a6d46.js +1 -0
- package/.next/static/chunks/pages/account/{profile-1fdb500de8f12b3a.js → profile-23b2e9fbbd95a30b.js} +1 -1
- package/.next/static/chunks/pages/{checkout-0dfe0dc9cee443ba.js → checkout-93b647fc45454d97.js} +1 -1
- package/.next/static/chunks/pages/{index-d36123e232b889d8.js → index-07bc320fc045538c.js} +1 -1
- package/.next/static/chunks/pages/{login-b59ea5561defc0d4.js → login-2454f1cd309c27d2.js} +1 -1
- package/.next/static/chunks/pages/{s-6120de2f57d674fc.js → s-9901e6857f517b8b.js} +1 -1
- package/.next/static/chunks/webpack-c2eed1e0b727b3ee.js +1 -0
- package/.next/static/css/b8945ac5f5327c34.css +1 -0
- package/.next/static/css/{f03f8973f7c72071.css → dbbb10bf2f162a58.css} +1 -1
- package/.next/trace +113 -109
- package/.turbo/turbo-build.log +25 -25
- package/.turbo/turbo-test.log +5 -5
- package/@generated/gql.ts +18 -2
- package/@generated/graphql.ts +58 -1
- package/@generated/persisted-documents.json +3 -1
- package/@generated/schema.graphql +14 -0
- package/CHANGELOG.md +12 -0
- package/cms/faststore/sections.json +110 -1
- package/discovery.config.default.js +12 -0
- package/package.json +7 -6
- package/src/Layout.tsx +2 -0
- package/src/components/cms/GlobalSections.tsx +13 -9
- package/src/components/cms/global/Components.ts +2 -0
- package/src/components/region/RegionBar/RegionBar.tsx +35 -2
- package/src/components/region/RegionButton/RegionButton.tsx +41 -6
- package/src/components/region/RegionModal/RegionModal.tsx +46 -34
- package/src/components/region/RegionModal/useRegion.ts +79 -0
- package/src/components/region/RegionModal/useRegionModal.ts +44 -0
- package/src/components/region/RegionPopover/RegionPopover.tsx +174 -0
- package/src/components/region/RegionPopover/index.ts +1 -0
- package/src/components/region/RegionPopover/section.module.scss +9 -0
- package/src/components/search/SearchInput/SearchInput.tsx +2 -2
- package/src/components/sections/Navbar/section.module.scss +3 -0
- package/src/components/sections/RegionBar/RegionBar.tsx +8 -3
- package/src/components/templates/LandingPage/LandingPage.tsx +22 -18
- package/src/components/templates/ProductListingPage/ProductListing.tsx +6 -1
- package/src/constants.ts +1 -0
- 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 +16 -6
- package/src/pages/_app.tsx +4 -2
- 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/error/MissingContentError/MissingContentError.ts +6 -4
- package/src/sdk/error/MultipleContentError/MultipleContentError.ts +6 -4
- package/src/sdk/geolocation/useGeolocation.ts +42 -0
- package/src/sdk/product/index.ts +21 -0
- package/src/sdk/profile/index.ts +31 -0
- package/src/sdk/session/index.ts +37 -0
- package/src/sdk/ui/useOnClickOutside.ts +3 -38
- 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/utils/utilities.ts +9 -1
- package/test/server/index.test.ts +1 -0
- package/.next/server/chunks/3105.js +0 -6
- package/.next/server/chunks/3779.js +0 -1
- package/.next/server/chunks/4444.js +0 -6
- package/.next/server/chunks/6026.js +0 -9
- package/.next/server/chunks/6030.js +0 -1
- package/.next/server/chunks/7337.js +0 -1
- package/.next/server/chunks/7675.js +0 -1
- package/.next/server/chunks/9594.js +0 -1
- package/.next/static/Ra_8xXVEVCNHcT2KePSUO/_buildManifest.js +0 -1
- package/.next/static/chunks/1036.27f5244aaf7d0915.js +0 -1
- package/.next/static/chunks/1173.5e86a9295010b785.js +0 -1
- package/.next/static/chunks/1552.e7cece605fc2e1cd.js +0 -1
- package/.next/static/chunks/3684.ba7a2a994988063b.js +0 -1
- package/.next/static/chunks/417.c39c1c5e5ef57b4a.js +0 -1
- package/.next/static/chunks/485.a35fab0c7c75a11b.js +0 -1
- package/.next/static/chunks/6167-ecb49640dcb9d566.js +0 -28
- package/.next/static/chunks/6335-5870fc075bf96b86.js +0 -1
- package/.next/static/chunks/6536.cd75ac69c241a35c.js +0 -1
- package/.next/static/chunks/7498-415859c993f5002b.js +0 -1
- package/.next/static/chunks/7959.9d31abae51a7e419.js +0 -1
- package/.next/static/chunks/9.e42e9b7463b94493.js +0 -1
- package/.next/static/chunks/BannerNewsletter.06b2b9724aa3c3ea.js +0 -1
- package/.next/static/chunks/CartItem.44cc90c698a69889.js +0 -1
- package/.next/static/chunks/Newsletter.d775e641d99322e6.js +0 -1
- package/.next/static/chunks/OrderSummary.8f34504b20564fec.js +0 -1
- package/.next/static/chunks/ProductShelf.0b5a71a93bca3148.js +0 -1
- package/.next/static/chunks/ProductTiles.a75612c0bcf990d6.js +0 -1
- package/.next/static/chunks/RegionModal.68b05bfd591d27fc.js +0 -1
- package/.next/static/chunks/UIBannerText.5ee380812ac3772c.js +0 -1
- package/.next/static/chunks/UIButton.c7a3273ac6ee5da5.js +0 -1
- package/.next/static/chunks/UISKUMatrixSidebar.c68540bda6d40e13.js +0 -1
- package/.next/static/chunks/UIToast.85ae30e3e8cc5ec7.js +0 -1
- package/.next/static/chunks/pages/[...slug]-f4fd6c8d7dc53f8f.js +0 -1
- package/.next/static/chunks/pages/[slug]/p-3b513ae37c648620.js +0 -1
- package/.next/static/chunks/pages/_app-0f16b6b5d7dfab2a.js +0 -1
- package/.next/static/chunks/webpack-d72e5eb27bf80195.js +0 -1
- package/.next/static/css/31fb64e064998460.css +0 -1
- /package/.next/static/{Ra_8xXVEVCNHcT2KePSUO → U_9W0qMyv_4RQSLFdrtHC}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Section } from '@vtex/client-cms'
|
|
2
2
|
import storeConfig from 'discovery.config'
|
|
3
|
-
import {
|
|
3
|
+
import type { PageContentType } from 'src/server/cms'
|
|
4
|
+
import { contentService } from 'src/server/content/service'
|
|
5
|
+
import type { PreviewData } from 'src/server/content/types'
|
|
4
6
|
|
|
5
7
|
export const GLOBAL_SECTIONS_CONTENT_TYPE = 'globalSections'
|
|
6
8
|
export const GLOBAL_SECTIONS_HEADER_CONTENT_TYPE = 'globalHeaderSections'
|
|
@@ -11,7 +13,7 @@ export type GlobalSectionsData = {
|
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export const getGlobalSectionsByType = async (
|
|
14
|
-
previewData:
|
|
16
|
+
previewData: PreviewData,
|
|
15
17
|
contentType: string
|
|
16
18
|
): Promise<GlobalSectionsData> => {
|
|
17
19
|
if (storeConfig.cms.data) {
|
|
@@ -19,26 +21,28 @@ export const getGlobalSectionsByType = async (
|
|
|
19
21
|
const page = cmsData[contentType][0]
|
|
20
22
|
|
|
21
23
|
if (page) {
|
|
22
|
-
const pageData =
|
|
23
|
-
contentType
|
|
24
|
+
const pageData = contentService.getSingleContent<PageContentType>({
|
|
25
|
+
contentType,
|
|
26
|
+
previewData,
|
|
24
27
|
documentId: page.documentId,
|
|
25
28
|
versionId: page.versionId,
|
|
29
|
+
releaseId: page.releaseId,
|
|
26
30
|
})
|
|
27
31
|
|
|
28
32
|
return pageData
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
const pageData =
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
const pageData = contentService.getSingleContent<PageContentType>({
|
|
37
|
+
contentType,
|
|
38
|
+
previewData,
|
|
35
39
|
})
|
|
36
40
|
|
|
37
41
|
return pageData
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
export const getGlobalSectionsData = (
|
|
41
|
-
previewData:
|
|
45
|
+
previewData: PreviewData
|
|
42
46
|
): Promise<GlobalSectionsData>[] => {
|
|
43
47
|
const globalSections = getGlobalSectionsByType(
|
|
44
48
|
previewData,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dynamic from 'next/dynamic'
|
|
2
2
|
import type { ComponentType } from 'react'
|
|
3
3
|
|
|
4
|
+
import RegionPopover from 'src/components/region/RegionPopover'
|
|
4
5
|
import { OverriddenDefaultAlert as Alert } from 'src/components/sections/Alert/OverriddenDefaultAlert'
|
|
5
6
|
import { OverriddenDefaultNavbar as Navbar } from 'src/components/sections/Navbar/OverriddenDefaultNavbar'
|
|
6
7
|
import { OverriddenDefaultRegionBar as RegionBar } from 'src/components/sections/RegionBar/OverriddenDefaultRegionBar'
|
|
@@ -32,6 +33,7 @@ const COMPONENTS: Record<string, ComponentType<any>> = {
|
|
|
32
33
|
Alert,
|
|
33
34
|
Navbar,
|
|
34
35
|
RegionBar,
|
|
36
|
+
RegionPopover,
|
|
35
37
|
CartSidebar, // out of viewport
|
|
36
38
|
RegionModal, // out of viewport
|
|
37
39
|
Footer, // out of viewport
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { RegionBarProps as UIRegionBarProps } from '@faststore/ui'
|
|
2
|
+
import { useEffect, useRef } from 'react'
|
|
2
3
|
|
|
3
4
|
import { useUI } from '@faststore/ui'
|
|
4
5
|
import { useSession } from 'src/sdk/session'
|
|
5
6
|
|
|
7
|
+
import { deliveryPromise, session as initialSession } from 'discovery.config'
|
|
6
8
|
import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext'
|
|
9
|
+
import { textToTitleCase } from 'src/utils/utilities'
|
|
10
|
+
|
|
11
|
+
import { useRegionModal } from '../RegionModal/useRegionModal'
|
|
7
12
|
|
|
8
13
|
export interface RegionBarProps {
|
|
9
14
|
/**
|
|
@@ -43,8 +48,34 @@ function RegionBar({
|
|
|
43
48
|
ButtonIcon,
|
|
44
49
|
} = useOverrideComponents<'RegionBar'>()
|
|
45
50
|
|
|
46
|
-
const { openModal } = useUI()
|
|
47
|
-
const { postalCode } = useSession()
|
|
51
|
+
const { openModal, openPopover } = useUI()
|
|
52
|
+
const { city, postalCode } = useSession()
|
|
53
|
+
const { isValidationComplete } = useRegionModal()
|
|
54
|
+
const regionBarRef = useRef<HTMLDivElement>(null)
|
|
55
|
+
|
|
56
|
+
const defaultPostalCode =
|
|
57
|
+
!!initialSession?.postalCode && postalCode === initialSession.postalCode
|
|
58
|
+
|
|
59
|
+
// If location is not mandatory, and default zipCode is provided or if the user has not set a zipCode, show the popover.
|
|
60
|
+
const displayRegionPopover =
|
|
61
|
+
defaultPostalCode || (!postalCode && !deliveryPromise.mandatory)
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (!deliveryPromise.enabled) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!isValidationComplete) {
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (isValidationComplete && displayRegionPopover && regionBarRef.current) {
|
|
73
|
+
openPopover({
|
|
74
|
+
isOpen: true,
|
|
75
|
+
triggerRef: regionBarRef,
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
}, [isValidationComplete])
|
|
48
79
|
|
|
49
80
|
return (
|
|
50
81
|
<RegionBarWrapper.Component
|
|
@@ -69,7 +100,9 @@ function RegionBar({
|
|
|
69
100
|
// This decision can be reviewed later if needed
|
|
70
101
|
onButtonClick={openModal}
|
|
71
102
|
postalCode={postalCode}
|
|
103
|
+
city={textToTitleCase(city ?? '')}
|
|
72
104
|
{...otherProps}
|
|
105
|
+
ref={regionBarRef}
|
|
73
106
|
/>
|
|
74
107
|
)
|
|
75
108
|
}
|
|
@@ -1,21 +1,56 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
2
|
|
|
3
|
-
import { Icon, useUI } from '@faststore/ui'
|
|
3
|
+
import { Button as UIButton, Icon as UIIcon, useUI } from '@faststore/ui'
|
|
4
|
+
import { deliveryPromise, session as initialSession } from 'discovery.config'
|
|
4
5
|
import { useSession } from 'src/sdk/session'
|
|
6
|
+
import { textToTitleCase } from 'src/utils/utilities'
|
|
7
|
+
|
|
8
|
+
import { useRegionModal } from '../RegionModal/useRegionModal'
|
|
5
9
|
|
|
6
10
|
function RegionButton({ icon, label }: { icon: string; label: string }) {
|
|
7
|
-
const { openModal } = useUI()
|
|
8
|
-
const { postalCode } = useSession()
|
|
11
|
+
const { openModal, openPopover } = useUI()
|
|
12
|
+
const { city, postalCode } = useSession()
|
|
13
|
+
const { isValidationComplete } = useRegionModal()
|
|
14
|
+
const regionButtonRef = useRef<HTMLButtonElement>(null)
|
|
15
|
+
|
|
16
|
+
const defaultPostalCode =
|
|
17
|
+
!!initialSession?.postalCode && postalCode === initialSession.postalCode
|
|
18
|
+
|
|
19
|
+
// If location is not mandatory, and default zipCode is provided or if the user has not set a zipCode, show the popover.
|
|
20
|
+
const displayRegionPopover =
|
|
21
|
+
defaultPostalCode || (!postalCode && !deliveryPromise.mandatory)
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!deliveryPromise.enabled) {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!isValidationComplete) {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (
|
|
33
|
+
isValidationComplete &&
|
|
34
|
+
displayRegionPopover &&
|
|
35
|
+
regionButtonRef.current
|
|
36
|
+
) {
|
|
37
|
+
openPopover({
|
|
38
|
+
isOpen: true,
|
|
39
|
+
triggerRef: regionButtonRef,
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}, [isValidationComplete])
|
|
9
43
|
|
|
10
44
|
return (
|
|
11
45
|
<UIButton
|
|
12
46
|
variant="tertiary"
|
|
13
47
|
size="small"
|
|
14
|
-
icon={<
|
|
48
|
+
icon={<UIIcon name={icon} width={18} height={18} weight="bold" />}
|
|
15
49
|
iconPosition="left"
|
|
16
50
|
onClick={openModal}
|
|
51
|
+
ref={regionButtonRef}
|
|
17
52
|
>
|
|
18
|
-
{postalCode
|
|
53
|
+
{city && postalCode ? `${textToTitleCase(city)}, ${postalCode}` : label}
|
|
19
54
|
</UIButton>
|
|
20
55
|
)
|
|
21
56
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
Icon,
|
|
3
|
-
type RegionModalProps as UIRegionModalProps,
|
|
4
|
-
useUI,
|
|
5
|
-
} from '@faststore/ui'
|
|
1
|
+
import dynamic from 'next/dynamic'
|
|
6
2
|
import { useRef, useState } from 'react'
|
|
7
3
|
|
|
8
|
-
import {
|
|
4
|
+
import type { RegionModalProps as UIRegionModalProps } from '@faststore/ui'
|
|
5
|
+
import { Icon, useUI } from '@faststore/ui'
|
|
6
|
+
|
|
7
|
+
import { deliveryPromise } from 'discovery.config'
|
|
8
|
+
import { useSession } from 'src/sdk/session'
|
|
9
|
+
|
|
10
|
+
import useRegion from './useRegion'
|
|
9
11
|
|
|
10
|
-
import dynamic from 'next/dynamic'
|
|
11
12
|
import styles from './section.module.scss'
|
|
12
13
|
|
|
13
14
|
const UIRegionModal = dynamic<UIRegionModalProps>(
|
|
@@ -17,7 +18,6 @@ const UIRegionModal = dynamic<UIRegionModalProps>(
|
|
|
17
18
|
),
|
|
18
19
|
{ ssr: false }
|
|
19
20
|
)
|
|
20
|
-
|
|
21
21
|
interface RegionModalProps {
|
|
22
22
|
title?: UIRegionModalProps['title']
|
|
23
23
|
description?: UIRegionModalProps['description']
|
|
@@ -25,6 +25,8 @@ interface RegionModalProps {
|
|
|
25
25
|
inputField?: {
|
|
26
26
|
label?: UIRegionModalProps['inputLabel']
|
|
27
27
|
errorMessage?: UIRegionModalProps['errorMessage']
|
|
28
|
+
noProductsAvailableErrorMessage?: UIRegionModalProps['errorMessage']
|
|
29
|
+
buttonActionText?: UIRegionModalProps['inputButtonActionText']
|
|
28
30
|
}
|
|
29
31
|
idkPostalCodeLink?: {
|
|
30
32
|
text?: string
|
|
@@ -40,7 +42,12 @@ function RegionModal({
|
|
|
40
42
|
title,
|
|
41
43
|
description,
|
|
42
44
|
closeButtonAriaLabel,
|
|
43
|
-
inputField: {
|
|
45
|
+
inputField: {
|
|
46
|
+
label: inputFieldLabel,
|
|
47
|
+
errorMessage: inputFieldErrorMessage,
|
|
48
|
+
noProductsAvailableErrorMessage: inputFieldNoProductsAvailableErrorMessage,
|
|
49
|
+
buttonActionText: inputButtonActionText,
|
|
50
|
+
},
|
|
44
51
|
idkPostalCodeLink: {
|
|
45
52
|
text: idkPostalCodeLinkText,
|
|
46
53
|
to: idkPostalCodeLinkTo,
|
|
@@ -49,35 +56,33 @@ function RegionModal({
|
|
|
49
56
|
}: RegionModalProps) {
|
|
50
57
|
const inputRef = useRef<HTMLInputElement>(null)
|
|
51
58
|
const { isValidating, ...session } = useSession()
|
|
52
|
-
const
|
|
59
|
+
const { modal: displayModal, closeModal } = useUI()
|
|
60
|
+
|
|
53
61
|
const [input, setInput] = useState<string>('')
|
|
54
|
-
const { modal: displayModal } = useUI()
|
|
55
62
|
|
|
56
|
-
const
|
|
57
|
-
const postalCode = inputRef.current?.value
|
|
63
|
+
const { loading, setRegion, regionError, setRegionError } = useRegion()
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
const handleSubmit = async () => {
|
|
66
|
+
if (isValidating) {
|
|
60
67
|
return
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
} catch (error) {
|
|
75
|
-
setErrorMessage(inputFieldErrorMessage)
|
|
76
|
-
}
|
|
70
|
+
await setRegion({
|
|
71
|
+
session,
|
|
72
|
+
onSuccess: () => {
|
|
73
|
+
setInput('')
|
|
74
|
+
closeModal()
|
|
75
|
+
},
|
|
76
|
+
postalCode: input,
|
|
77
|
+
errorMessage: inputFieldErrorMessage,
|
|
78
|
+
noProductsAvailableErrorMessage:
|
|
79
|
+
inputFieldNoProductsAvailableErrorMessage,
|
|
80
|
+
})
|
|
77
81
|
}
|
|
78
82
|
|
|
83
|
+
const isDismissible = !!(!deliveryPromise?.mandatory || session.postalCode)
|
|
79
84
|
const idkPostalCodeLinkProps: UIRegionModalProps['idkPostalCodeLinkProps'] = {
|
|
80
|
-
href: idkPostalCodeLinkTo
|
|
85
|
+
href: idkPostalCodeLinkTo,
|
|
81
86
|
children: (
|
|
82
87
|
<>
|
|
83
88
|
{idkPostalCodeLinkText}
|
|
@@ -106,15 +111,22 @@ function RegionModal({
|
|
|
106
111
|
inputRef={inputRef}
|
|
107
112
|
inputValue={input}
|
|
108
113
|
inputLabel={inputFieldLabel}
|
|
109
|
-
errorMessage={
|
|
110
|
-
idkPostalCodeLinkProps={
|
|
114
|
+
errorMessage={regionError}
|
|
115
|
+
idkPostalCodeLinkProps={
|
|
116
|
+
idkPostalCodeLinkTo ? idkPostalCodeLinkProps : null
|
|
117
|
+
}
|
|
111
118
|
onInput={(e) => {
|
|
112
|
-
|
|
119
|
+
regionError !== '' && setRegionError('')
|
|
113
120
|
setInput(e.currentTarget.value)
|
|
114
121
|
}}
|
|
115
122
|
onSubmit={handleSubmit}
|
|
116
|
-
fadeOutOnSubmit={
|
|
117
|
-
onClear={() =>
|
|
123
|
+
fadeOutOnSubmit={false}
|
|
124
|
+
onClear={() => {
|
|
125
|
+
setInput('')
|
|
126
|
+
setRegionError('')
|
|
127
|
+
}}
|
|
128
|
+
inputButtonActionText={loading ? '...' : inputButtonActionText}
|
|
129
|
+
dismissible={isDismissible}
|
|
118
130
|
/>
|
|
119
131
|
)}
|
|
120
132
|
</>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
import type { Session } from '@faststore/sdk'
|
|
4
|
+
import { sessionStore, validateSession } from 'src/sdk/session'
|
|
5
|
+
import { getProductCount } from 'src/sdk/product'
|
|
6
|
+
import { deliveryPromise } from 'discovery.config'
|
|
7
|
+
|
|
8
|
+
type SetRegionProps = {
|
|
9
|
+
session: Session
|
|
10
|
+
postalCode: string | undefined
|
|
11
|
+
onSuccess?: () => void
|
|
12
|
+
errorMessage: string
|
|
13
|
+
noProductsAvailableErrorMessage?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type UseRegionValues = {
|
|
17
|
+
loading: boolean
|
|
18
|
+
regionError: string
|
|
19
|
+
setRegion: (props: SetRegionProps) => Promise<void>
|
|
20
|
+
setRegionError: (value: string) => void
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default function useRegion(): UseRegionValues {
|
|
24
|
+
const [loading, setLoading] = useState<boolean>(false)
|
|
25
|
+
const [regionError, setRegionError] = useState<string>('')
|
|
26
|
+
|
|
27
|
+
const setRegion = async ({
|
|
28
|
+
postalCode,
|
|
29
|
+
errorMessage,
|
|
30
|
+
session,
|
|
31
|
+
onSuccess,
|
|
32
|
+
noProductsAvailableErrorMessage,
|
|
33
|
+
}: SetRegionProps) => {
|
|
34
|
+
if (typeof postalCode !== 'string') {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
setLoading(true)
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const newSession = {
|
|
42
|
+
...session,
|
|
43
|
+
postalCode,
|
|
44
|
+
geoCoordinates: null, // Revalidate geo coordinates in API when users set a new postal code
|
|
45
|
+
} as Session
|
|
46
|
+
|
|
47
|
+
const validatedSession = await validateSession(newSession)
|
|
48
|
+
|
|
49
|
+
if (deliveryPromise.enabled) {
|
|
50
|
+
// Check product availability for specific postal code
|
|
51
|
+
const productCount = await getProductCount()
|
|
52
|
+
if (productCount === 0) {
|
|
53
|
+
const errorFallback = `There are no products available for ${postalCode}.`
|
|
54
|
+
const noProductsAvailableError =
|
|
55
|
+
noProductsAvailableErrorMessage?.replace(/%s/g, () => postalCode)
|
|
56
|
+
|
|
57
|
+
setRegionError(noProductsAvailableError ?? errorFallback)
|
|
58
|
+
setLoading(false)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
sessionStore.set(validatedSession ?? newSession)
|
|
64
|
+
setRegionError('')
|
|
65
|
+
onSuccess?.() // Execute the post-validation action (close modal, etc.)
|
|
66
|
+
} catch (error) {
|
|
67
|
+
setRegionError(errorMessage)
|
|
68
|
+
} finally {
|
|
69
|
+
setLoading(false) // Reset loading to false when validation is complete
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
loading,
|
|
75
|
+
setRegion,
|
|
76
|
+
regionError,
|
|
77
|
+
setRegionError,
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useUI } from '@faststore/ui'
|
|
2
|
+
import { deliveryPromise } from 'discovery.config'
|
|
3
|
+
import { useEffect, useRef, useState } from 'react'
|
|
4
|
+
import { sessionStore, useSession } from 'src/sdk/session'
|
|
5
|
+
|
|
6
|
+
export function useRegionModal() {
|
|
7
|
+
const { openModal: displayRegionModal } = useUI()
|
|
8
|
+
const { isValidating } = useSession()
|
|
9
|
+
|
|
10
|
+
// Ref to track the previous value of isValidating
|
|
11
|
+
const prevIsValidating = useRef(isValidating)
|
|
12
|
+
|
|
13
|
+
// State to track if validation is complete
|
|
14
|
+
const [isValidationComplete, setValidationComplete] = useState(false)
|
|
15
|
+
|
|
16
|
+
const openRegionModal = () => {
|
|
17
|
+
const { postalCode } = sessionStore.read()
|
|
18
|
+
if (!postalCode) {
|
|
19
|
+
displayRegionModal()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Effect to handle when isValidating changes from true to false
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!deliveryPromise.enabled) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check if validation has completed (isValidating changed from true to false)
|
|
30
|
+
if (prevIsValidating.current && !isValidating) {
|
|
31
|
+
setValidationComplete(true)
|
|
32
|
+
|
|
33
|
+
// If the postal code is not set and is mandatory, open the region modal
|
|
34
|
+
if (deliveryPromise.mandatory) {
|
|
35
|
+
openRegionModal()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Update the previous value of isValidating
|
|
40
|
+
prevIsValidating.current = isValidating
|
|
41
|
+
}, [openRegionModal])
|
|
42
|
+
|
|
43
|
+
return { openRegionModal, isValidationComplete }
|
|
44
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { PopoverProps as UIPopoverProps } from '@faststore/ui'
|
|
2
|
+
import {
|
|
3
|
+
Icon as UIIcon,
|
|
4
|
+
InputField as UIInputField,
|
|
5
|
+
Link as UILink,
|
|
6
|
+
Popover as UIPopover,
|
|
7
|
+
useUI,
|
|
8
|
+
} from '@faststore/ui'
|
|
9
|
+
import { useRef, useState } from 'react'
|
|
10
|
+
|
|
11
|
+
import useRegion from '../RegionModal/useRegion'
|
|
12
|
+
|
|
13
|
+
import { sessionStore, useSession } from 'src/sdk/session'
|
|
14
|
+
import { textToTitleCase } from 'src/utils/utilities'
|
|
15
|
+
import styles from './section.module.scss'
|
|
16
|
+
|
|
17
|
+
interface RegionPopoverProps {
|
|
18
|
+
title?: UIPopoverProps['title']
|
|
19
|
+
closeButtonAriaLabel?: UIPopoverProps['closeButtonAriaLabel']
|
|
20
|
+
inputField?: {
|
|
21
|
+
label?: string
|
|
22
|
+
errorMessage?: string
|
|
23
|
+
noProductsAvailableErrorMessage?: string
|
|
24
|
+
buttonActionText?: string
|
|
25
|
+
}
|
|
26
|
+
idkPostalCodeLink?: {
|
|
27
|
+
text?: string
|
|
28
|
+
to?: string
|
|
29
|
+
icon?: {
|
|
30
|
+
icon?: string
|
|
31
|
+
alt?: string
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
textBeforeLocation?: string
|
|
35
|
+
textAfterLocation?: string
|
|
36
|
+
description?: string
|
|
37
|
+
triggerRef?: UIPopoverProps['triggerRef']
|
|
38
|
+
onDismiss: UIPopoverProps['onDismiss']
|
|
39
|
+
offsetTop?: UIPopoverProps['offsetTop']
|
|
40
|
+
offsetLeft?: UIPopoverProps['offsetLeft']
|
|
41
|
+
placement?: UIPopoverProps['placement']
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function RegionPopover({
|
|
45
|
+
title = 'Set your location',
|
|
46
|
+
closeButtonAriaLabel,
|
|
47
|
+
inputField: {
|
|
48
|
+
label: inputFieldLabel,
|
|
49
|
+
errorMessage: inputFieldErrorMessage,
|
|
50
|
+
noProductsAvailableErrorMessage: inputFieldNoProductsAvailableErrorMessage,
|
|
51
|
+
buttonActionText: inputButtonActionText,
|
|
52
|
+
},
|
|
53
|
+
idkPostalCodeLink: {
|
|
54
|
+
text: idkPostalCodeLinkText,
|
|
55
|
+
to: idkPostalCodeLinkTo,
|
|
56
|
+
icon: { icon: idkPostalCodeLinkIcon, alt: idkPostalCodeLinkIconAlt },
|
|
57
|
+
},
|
|
58
|
+
textBeforeLocation = 'Your current location is:',
|
|
59
|
+
textAfterLocation = 'Use the field below to change it.',
|
|
60
|
+
description = 'Offers and availability vary by location.',
|
|
61
|
+
triggerRef,
|
|
62
|
+
offsetTop = 6,
|
|
63
|
+
offsetLeft,
|
|
64
|
+
placement = 'bottom-start',
|
|
65
|
+
}: RegionPopoverProps) {
|
|
66
|
+
const inputRef = useRef<HTMLInputElement>(null)
|
|
67
|
+
const { isValidating, ...session } = useSession()
|
|
68
|
+
const { popover: displayPopover, closePopover } = useUI()
|
|
69
|
+
const { city, postalCode } = sessionStore.read()
|
|
70
|
+
const location = city ? `${textToTitleCase(city)}, ${postalCode}` : postalCode
|
|
71
|
+
|
|
72
|
+
const [input, setInput] = useState<string>('')
|
|
73
|
+
|
|
74
|
+
const { loading, setRegion, regionError, setRegionError } = useRegion()
|
|
75
|
+
|
|
76
|
+
const handleSubmit = async () => {
|
|
77
|
+
if (isValidating) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await setRegion({
|
|
82
|
+
session,
|
|
83
|
+
onSuccess: () => {
|
|
84
|
+
setInput('')
|
|
85
|
+
closePopover()
|
|
86
|
+
},
|
|
87
|
+
postalCode: input,
|
|
88
|
+
errorMessage: inputFieldErrorMessage,
|
|
89
|
+
noProductsAvailableErrorMessage:
|
|
90
|
+
inputFieldNoProductsAvailableErrorMessage,
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const idkPostalCodeLinkProps = {
|
|
95
|
+
href: idkPostalCodeLinkTo,
|
|
96
|
+
children: (
|
|
97
|
+
<>
|
|
98
|
+
{idkPostalCodeLinkText}
|
|
99
|
+
{!!idkPostalCodeLinkIcon && (
|
|
100
|
+
<UIIcon
|
|
101
|
+
name={idkPostalCodeLinkIcon}
|
|
102
|
+
aria-label={idkPostalCodeLinkIconAlt}
|
|
103
|
+
width={20}
|
|
104
|
+
height={20}
|
|
105
|
+
/>
|
|
106
|
+
)}
|
|
107
|
+
</>
|
|
108
|
+
),
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const RegionPopoverContent = (
|
|
112
|
+
<>
|
|
113
|
+
<span data-fs-region-popover-description>
|
|
114
|
+
{postalCode ? (
|
|
115
|
+
<>
|
|
116
|
+
{textBeforeLocation} <span>{location}</span>. {textAfterLocation}
|
|
117
|
+
</>
|
|
118
|
+
) : (
|
|
119
|
+
<>{description}</>
|
|
120
|
+
)}
|
|
121
|
+
</span>
|
|
122
|
+
<UIInputField
|
|
123
|
+
data-fs-region-popover-input
|
|
124
|
+
id="region-popover-input-postal-code"
|
|
125
|
+
inputRef={inputRef}
|
|
126
|
+
label={inputFieldLabel}
|
|
127
|
+
actionable
|
|
128
|
+
value={input}
|
|
129
|
+
onInput={(e) => {
|
|
130
|
+
regionError !== '' && setRegionError('')
|
|
131
|
+
setInput(e.currentTarget.value)
|
|
132
|
+
}}
|
|
133
|
+
onSubmit={handleSubmit}
|
|
134
|
+
onClear={() => {
|
|
135
|
+
setInput('')
|
|
136
|
+
setRegionError('')
|
|
137
|
+
}}
|
|
138
|
+
buttonActionText={loading ? '...' : inputButtonActionText}
|
|
139
|
+
error={regionError}
|
|
140
|
+
/>
|
|
141
|
+
{idkPostalCodeLinkTo && (
|
|
142
|
+
<UILink data-fs-region-popover-link {...idkPostalCodeLinkProps} />
|
|
143
|
+
)}
|
|
144
|
+
</>
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<>
|
|
149
|
+
{displayPopover.isOpen && (
|
|
150
|
+
<div className={`${styles.section} section-region-popover`}>
|
|
151
|
+
<UIPopover
|
|
152
|
+
data-fs-region-popover
|
|
153
|
+
title={title}
|
|
154
|
+
isOpen={displayPopover.isOpen}
|
|
155
|
+
content={RegionPopoverContent}
|
|
156
|
+
placement={placement}
|
|
157
|
+
dismissible
|
|
158
|
+
triggerRef={triggerRef}
|
|
159
|
+
offsetTop={offsetTop}
|
|
160
|
+
offsetLeft={offsetLeft}
|
|
161
|
+
closeButtonAriaLabel={closeButtonAriaLabel}
|
|
162
|
+
onEntered={() => {
|
|
163
|
+
if (!postalCode && inputRef.current) {
|
|
164
|
+
inputRef.current.focus()
|
|
165
|
+
}
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
168
|
+
</div>
|
|
169
|
+
)}
|
|
170
|
+
</>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export default RegionPopover
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './RegionPopover'
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
.section {
|
|
2
|
+
@import "@faststore/ui/src/components/atoms/Icon/styles.scss";
|
|
3
|
+
@import "@faststore/ui/src/components/atoms/Input/styles.scss";
|
|
4
|
+
@import "@faststore/ui/src/components/atoms/Button/styles.scss";
|
|
5
|
+
@import "@faststore/ui/src/components/atoms/Link/styles.scss";
|
|
6
|
+
@import "@faststore/ui/src/components/molecules/InputField/styles.scss";
|
|
7
|
+
@import "@faststore/ui/src/components/molecules/Popover/styles.scss";
|
|
8
|
+
@import "@faststore/ui/src/components/organisms/RegionPopover/styles.scss";
|
|
9
|
+
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
Icon as UIIcon,
|
|
19
19
|
IconButton as UIIconButton,
|
|
20
20
|
SearchInput as UISearchInput,
|
|
21
|
+
useOnClickOutside,
|
|
21
22
|
} from '@faststore/ui'
|
|
22
23
|
|
|
23
24
|
import type {
|
|
@@ -27,10 +28,9 @@ import type {
|
|
|
27
28
|
|
|
28
29
|
import type { SearchProviderContextValue } from '@faststore/ui'
|
|
29
30
|
|
|
31
|
+
import type { NavbarProps } from 'src/components/sections/Navbar'
|
|
30
32
|
import useSearchHistory from 'src/sdk/search/useSearchHistory'
|
|
31
33
|
import useSuggestions from 'src/sdk/search/useSuggestions'
|
|
32
|
-
import useOnClickOutside from 'src/sdk/ui/useOnClickOutside'
|
|
33
|
-
import type { NavbarProps } from 'src/components/sections/Navbar'
|
|
34
34
|
|
|
35
35
|
import { formatSearchPath } from 'src/sdk/search/formatSearchPath'
|
|
36
36
|
|
|
@@ -14,10 +14,13 @@
|
|
|
14
14
|
@import "@faststore/ui/src/components/atoms/Logo/styles.scss";
|
|
15
15
|
@import "@faststore/ui/src/components/atoms/Overlay/styles.scss";
|
|
16
16
|
@import "@faststore/ui/src/components/atoms/Price/styles.scss";
|
|
17
|
+
@import "@faststore/ui/src/components/molecules/InputField/styles.scss";
|
|
17
18
|
@import "@faststore/ui/src/components/molecules/LinkButton/styles.scss";
|
|
18
19
|
@import "@faststore/ui/src/components/molecules/QuantitySelector/styles.scss";
|
|
19
20
|
@import "@faststore/ui/src/components/molecules/NavbarLinks/styles.scss";
|
|
21
|
+
@import "@faststore/ui/src/components/molecules/Popover/styles.scss";
|
|
20
22
|
@import "@faststore/ui/src/components/molecules/ProductPrice/styles.scss";
|
|
23
|
+
@import "@faststore/ui/src/components/organisms/RegionPopover/styles.scss";
|
|
21
24
|
@import "@faststore/ui/src/components/molecules/SearchAutoComplete/styles.scss";
|
|
22
25
|
@import "@faststore/ui/src/components/molecules/SearchDropdown/styles.scss";
|
|
23
26
|
@import "@faststore/ui/src/components/molecules/SearchHistory/styles.scss";
|