@faststore/core 2.0.130-alpha.0 → 2.0.133-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/.turbo/turbo-build.log +16 -15
  2. package/CHANGELOG.md +12 -0
  3. package/cms/faststore/sections.json +1 -1
  4. package/lighthouserc.js +1 -0
  5. package/next.config.js +2 -0
  6. package/package.json +4 -4
  7. package/src/components/cms/GlobalSections.tsx +4 -3
  8. package/src/components/common/Footer/Footer.tsx +23 -118
  9. package/src/components/common/Footer/FooterLinks.tsx +23 -97
  10. package/src/components/common/Footer/FooterSocial.tsx +42 -0
  11. package/src/components/common/Footer/index.ts +6 -1
  12. package/src/components/common/Toast/Toast.tsx +5 -3
  13. package/src/components/common/Toast/section.module.scss +7 -0
  14. package/src/components/product/ProductCard/ProductCard.tsx +13 -7
  15. package/src/components/product/ProductGrid/ProductGrid.tsx +5 -0
  16. package/src/components/region/RegionButton/RegionButton.tsx +2 -2
  17. package/src/components/sections/BannerNewsletter/BannerNewsletter.tsx +1 -0
  18. package/src/components/sections/BannerNewsletter/section.module.scss +1 -0
  19. package/src/components/sections/EmptyState/EmptyState.tsx +28 -0
  20. package/src/components/sections/EmptyState/index.ts +2 -0
  21. package/src/components/sections/EmptyState/section.module.scss +8 -0
  22. package/src/components/sections/Footer/Footer.tsx +87 -0
  23. package/src/components/sections/Footer/index.ts +1 -0
  24. package/src/components/{common → sections}/Footer/section.module.scss +1 -0
  25. package/src/components/sections/Hero/Hero.tsx +0 -1
  26. package/src/components/sections/Incentives/Incentives.tsx +19 -0
  27. package/src/components/sections/Incentives/index.ts +1 -0
  28. package/src/components/sections/ProductDetails/section.module.scss +1 -0
  29. package/src/components/sections/ProductGallery/section.module.scss +1 -0
  30. package/src/components/sections/ProductShelf/ProductShelf.tsx +12 -4
  31. package/src/components/sections/ProductTiles/ProductTiles.tsx +21 -0
  32. package/src/components/ui/Button/ButtonSignIn/ButtonSignIn.tsx +1 -1
  33. package/src/components/ui/Image/Image.tsx +7 -18
  34. package/src/components/ui/Image/loader.ts +16 -0
  35. package/src/components/ui/ImageGallery/ImageGallery.tsx +7 -14
  36. package/src/components/ui/Incentives/Incentives.tsx +11 -7
  37. package/src/components/ui/Incentives/index.ts +1 -1
  38. package/src/components/ui/SkuSelector/Selectors.tsx +4 -17
  39. package/src/pages/404.tsx +5 -4
  40. package/src/pages/500.tsx +19 -5
  41. package/src/pages/[...slug].tsx +0 -1
  42. package/src/pages/index.tsx +2 -2
  43. package/src/pages/login.tsx +5 -3
  44. package/src/utils/utilities.ts +13 -0
  45. package/src/components/common/Footer/FooterFlags.tsx +0 -26
  46. package/src/components/sections/IncentivesHeader/IncentivesHeader.tsx +0 -24
  47. package/src/components/sections/IncentivesHeader/index.ts +0 -1
  48. package/src/components/ui/Image/thumborUrlBuilder.ts +0 -103
  49. package/src/components/ui/Image/useImage.ts +0 -46
  50. package/src/components/ui/Incentives/incentivesMock.ts +0 -27
  51. /package/src/components/sections/{IncentivesHeader → Incentives}/section.module.scss +0 -0
@@ -0,0 +1,28 @@
1
+ import { ReactNode } from 'react'
2
+ import type { PropsWithChildren } from 'react'
3
+
4
+ import Section from '../Section'
5
+ import styles from './section.module.scss'
6
+
7
+ import { EmptyState as UIEmptyState } from '@faststore/ui'
8
+
9
+ export interface EmptyStateProps {
10
+ title: string
11
+ titleIcon?: ReactNode
12
+ }
13
+
14
+ function EmptyState({
15
+ title,
16
+ titleIcon,
17
+ children,
18
+ }: PropsWithChildren<EmptyStateProps>) {
19
+ return (
20
+ <Section className={`${styles.section} section-empty-state`}>
21
+ <UIEmptyState title={title} titleIcon={titleIcon} bkgColor="light">
22
+ {children}
23
+ </UIEmptyState>
24
+ </Section>
25
+ )
26
+ }
27
+
28
+ export default EmptyState
@@ -0,0 +1,2 @@
1
+ export { default } from './EmptyState'
2
+ export type { EmptyStateProps } from './EmptyState'
@@ -0,0 +1,8 @@
1
+ /* stylelint-disable no-invalid-position-at-import-rule */
2
+ @import "@faststore/ui/src/styles/base/utilities.scss";
3
+
4
+ .section {
5
+ @import "@faststore/ui/src/components/atoms/Icon/styles.scss";
6
+ @import "@faststore/ui/src/components/atoms/Loader/styles.scss";
7
+ @import "@faststore/ui/src/components/organisms/EmptyState/styles.scss";
8
+ }
@@ -0,0 +1,87 @@
1
+ import { PaymentMethods as UIPaymentMethods } from '@faststore/ui'
2
+ import type { PaymentMethodsProps as UIPaymentMethodProps } from '@faststore/ui'
3
+
4
+ import Section from '../Section'
5
+
6
+ import UIFooter, {
7
+ FooterLinks,
8
+ FooterSocial,
9
+ FooterInfo as UIFooterInfo,
10
+ FooterNavigation as UIFooterNavigation,
11
+ } from '../../common/Footer'
12
+ import type { FooterLinksProps, FooterSocialProps } from '../../common/Footer'
13
+
14
+ import { Image } from '../../ui/Image'
15
+ import UIIncentives from '../../ui/Incentives'
16
+ import type { Incentive } from '../../ui/Incentives'
17
+
18
+ import styles from './section.module.scss'
19
+
20
+ export type FooterProps = {
21
+ incentives: Incentive[]
22
+ footerLinks: FooterLinksProps['links']
23
+ footerSocial: {
24
+ title?: FooterSocialProps['title']
25
+ socialLinks: FooterSocialProps['links']
26
+ }
27
+ logo: {
28
+ src: string
29
+ alt: string
30
+ }
31
+ copyrightInfo: string
32
+ acceptedPaymentMethods: {
33
+ showPaymentMethods: boolean
34
+ title?: string
35
+ paymentMethods?: UIPaymentMethodProps['flagList']
36
+ }
37
+ }
38
+
39
+ const Footer = ({
40
+ incentives,
41
+ footerLinks,
42
+ footerSocial,
43
+ footerSocial: { title: footerSocialTitle },
44
+ logo: { src: logoSrc, alt: logoAlt },
45
+ copyrightInfo,
46
+ acceptedPaymentMethods: {
47
+ showPaymentMethods,
48
+ title: acceptedPaymentMethodsTitle,
49
+ paymentMethods,
50
+ },
51
+ }: FooterProps) => {
52
+ return (
53
+ <Section className={`${styles.section} section-footer`}>
54
+ <UIFooter>
55
+ <UIIncentives incentives={incentives} />
56
+ <UIFooterNavigation>
57
+ <FooterLinks links={footerLinks} />
58
+ <FooterSocial
59
+ title={footerSocialTitle}
60
+ links={footerSocial.socialLinks}
61
+ />
62
+ </UIFooterNavigation>
63
+ <UIFooterInfo>
64
+ <Image
65
+ data-fs-footer-logo
66
+ loading="lazy"
67
+ src={logoSrc}
68
+ alt={logoAlt}
69
+ width={112}
70
+ height={119}
71
+ />
72
+ {showPaymentMethods && (
73
+ <UIPaymentMethods
74
+ flagList={paymentMethods}
75
+ title={<p>{acceptedPaymentMethodsTitle}</p>}
76
+ />
77
+ )}
78
+ <div data-fs-footer-copyright className="text__legend">
79
+ <p>{copyrightInfo}</p>
80
+ </div>
81
+ </UIFooterInfo>
82
+ </UIFooter>
83
+ </Section>
84
+ )
85
+ }
86
+
87
+ export default Footer
@@ -0,0 +1 @@
1
+ export { default } from './Footer'
@@ -2,6 +2,7 @@
2
2
  @import "@faststore/ui/src/styles/base/utilities.scss";
3
3
 
4
4
  .section {
5
+ @import "@faststore/ui/src/components/atoms/Button/styles.scss";
5
6
  @import "@faststore/ui/src/components/atoms/Link/styles.scss";
6
7
  @import "@faststore/ui/src/components/atoms/List/styles.scss";
7
8
  @import "@faststore/ui/src/components/atoms/Logo/styles.scss";
@@ -41,7 +41,6 @@ const Hero = ({
41
41
  <UIHeroImage data-fs-hero-image>
42
42
  <Image
43
43
  loading="eager"
44
- priority
45
44
  src={image.src}
46
45
  alt={image.alt}
47
46
  width={360}
@@ -0,0 +1,19 @@
1
+ import UIIncentives from 'src/components/ui/Incentives/Incentives'
2
+ import type { Incentive } from 'src/components/ui/Incentives'
3
+
4
+ import Section from '../Section'
5
+ import styles from './section.module.scss'
6
+
7
+ interface Props {
8
+ incentives: Incentive[]
9
+ }
10
+
11
+ function Incentives({ incentives }: Props) {
12
+ return (
13
+ <Section className={`${styles.section} section-incentives`}>
14
+ <UIIncentives incentives={incentives} colored />
15
+ </Section>
16
+ )
17
+ }
18
+
19
+ export default Incentives
@@ -0,0 +1 @@
1
+ export { default } from './Incentives'
@@ -10,6 +10,7 @@
10
10
  @import "@faststore/ui/src/components/atoms/Badge/styles.scss";
11
11
  @import "@faststore/ui/src/components/atoms/Button/styles.scss";
12
12
  @import "@faststore/ui/src/components/atoms/Input/styles.scss";
13
+ @import "@faststore/ui/src/components/atoms/Price/styles.scss";
13
14
  @import "@faststore/ui/src/components/molecules/Accordion/styles.scss";
14
15
  @import "@faststore/ui/src/components/molecules/Breadcrumb/styles.scss";
15
16
  @import "@faststore/ui/src/components/molecules/BuyButton/styles.scss";
@@ -16,6 +16,7 @@
16
16
  @import "@faststore/ui/src/components/molecules/Accordion/styles.scss";
17
17
  @import "@faststore/ui/src/components/molecules/DiscountBadge/styles.scss";
18
18
  @import "@faststore/ui/src/components/molecules/InputField/styles.scss";
19
+ @import "@faststore/ui/src/components/molecules/LinkButton/styles.scss";
19
20
  @import "@faststore/ui/src/components/molecules/ProductCard/styles.scss";
20
21
  @import "@faststore/ui/src/components/molecules/ProductCardSkeleton/styles";
21
22
  @import "@faststore/ui/src/components/molecules/SelectField/styles.scss";
@@ -1,4 +1,4 @@
1
- import { useEffect, useRef } from 'react'
1
+ import { useEffect, useId, useRef } from 'react'
2
2
  import { useInView } from 'react-intersection-observer'
3
3
 
4
4
  import { ProductShelf as UIProductShelf } from '@faststore/ui'
@@ -7,11 +7,12 @@ import type { ProductsQueryQueryVariables } from '@generated/graphql'
7
7
  import ProductShelfSkeleton from 'src/components/skeletons/ProductShelfSkeleton'
8
8
  import { useViewItemListEvent } from 'src/sdk/analytics/hooks/useViewItemListEvent'
9
9
  import { useProductsQuery } from 'src/sdk/product/useProductsQuery'
10
+ import { textToKebabCase } from 'src/utils/utilities'
10
11
 
12
+ import Carousel from '../../ui/Carousel'
13
+ import Section from '../Section'
11
14
  import { Components } from './Overrides'
12
15
  const { ProductCard } = Components
13
- import Section from '../Section'
14
- import Carousel from '../../ui/Carousel'
15
16
 
16
17
  import styles from './section.module.scss'
17
18
 
@@ -25,6 +26,8 @@ function ProductShelf({
25
26
  withDivisor = false,
26
27
  ...variables
27
28
  }: ProductShelfProps) {
29
+ const titleId = textToKebabCase(title)
30
+ const id = useId()
28
31
  const viewedOnce = useRef(false)
29
32
  const { ref, inView } = useInView()
30
33
  const products = useProductsQuery(variables)
@@ -63,7 +66,7 @@ function ProductShelf({
63
66
  loading={products === undefined}
64
67
  >
65
68
  <UIProductShelf>
66
- <Carousel>
69
+ <Carousel id={titleId || id}>
67
70
  {productEdges.map((product, idx) => (
68
71
  <ProductCard
69
72
  bordered
@@ -71,6 +74,11 @@ function ProductShelf({
71
74
  product={product.node}
72
75
  index={idx + 1}
73
76
  aspectRatio={aspectRatio}
77
+ imgProps={{
78
+ width: 216,
79
+ height: 216,
80
+ sizes: '(max-width: 768px) 42vw, 30vw',
81
+ }}
74
82
  />
75
83
  ))}
76
84
  </Carousel>
@@ -33,6 +33,26 @@ const getRatio = (products: number, idx: number) => {
33
33
  return 3 / 4
34
34
  }
35
35
 
36
+ const getSizes = (products: number, idx: number) => {
37
+ const expandsFirstTile =
38
+ products === NUMBER_ITEMS_TO_EXPAND_FIRST && idx === 0
39
+
40
+ const expandsFirstTwoTile =
41
+ products === NUMBER_ITEMS_TO_EXPAND_FIRST_TWO && (idx === 0 || idx === 1)
42
+
43
+ if (expandsFirstTile || expandsFirstTwoTile) {
44
+ return {
45
+ width: 594,
46
+ height: 364,
47
+ }
48
+ }
49
+
50
+ return {
51
+ width: 284,
52
+ height: 364,
53
+ }
54
+ }
55
+
36
56
  const ProductTiles = ({ title, ...variables }: ProductTilesProps) => {
37
57
  const viewedOnce = useRef(false)
38
58
  const { ref, inView } = useInView()
@@ -75,6 +95,7 @@ const ProductTiles = ({ title, ...variables }: ProductTilesProps) => {
75
95
  index={idx + 1}
76
96
  variant="wide"
77
97
  aspectRatio={getRatio(productEdges.length, idx)}
98
+ imgProps={getSizes(productEdges.length, idx)}
78
99
  />
79
100
  </Tile>
80
101
  ))}
@@ -18,7 +18,7 @@ const ButtonSignIn = () => {
18
18
  icon={<Icon name="User" width={18} height={18} weight="bold" />}
19
19
  iconPosition="left"
20
20
  >
21
- <span>{person?.id ? 'My Account' : 'Sign In'}</span>
21
+ {person?.id ? 'My Account' : 'Sign In'}
22
22
  </LinkButton>
23
23
  )
24
24
  }
@@ -1,29 +1,18 @@
1
1
  import { memo } from 'react'
2
2
 
3
3
  import NextImage, { ImageProps } from 'next/future/image'
4
- import { ThumborOptions } from './thumborUrlBuilder'
5
- import { useImage } from './useImage'
4
+ import loader from './loader'
6
5
 
7
- // Next loader function does not handle all props as height and options,
8
- // so we use the useImage hook to handle the custom thumbor loader (VTEX CDN) along with unoptimized prop
6
+ // Next loader function does not handle all props as height and options
7
+ // so we use a custom loader to handle images using thumbor server with VTEX CDN
9
8
  // https://nextjs.org/docs/api-reference/next/image#loader
10
- function Image({ src, width, height, quality, ...otherProps }: ImageProps) {
11
- const { src: thumborSrc, alt } = useImage({
12
- src: String(src),
13
- width: Number(width),
14
- height: Number(height),
15
- options: quality ? ({ filters: { quality } } as ThumborOptions) : undefined,
16
- ...otherProps,
17
- })
18
-
9
+ function Image({ loading = 'lazy', ...otherProps }: ImageProps) {
19
10
  return (
20
11
  <NextImage
21
12
  data-fs-image
22
- unoptimized
23
- src={thumborSrc}
24
- width={width}
25
- height={height}
26
- alt={alt}
13
+ loader={loader}
14
+ loading={loading}
15
+ priority={loading === 'eager'}
27
16
  {...otherProps}
28
17
  />
29
18
  )
@@ -0,0 +1,16 @@
1
+ import storeConfig from 'faststore.config'
2
+ const THUMBOR_SERVER = `https://${storeConfig.api.storeId}.vtexassets.com`
3
+
4
+ export default function customImageLoader({ src, width, quality }) {
5
+ const preSizeComponents = [THUMBOR_SERVER, 'unsafe']
6
+
7
+ // proportional to the width, enter a height of 0,
8
+ const height = 0
9
+ const finalSize = `${width}x${height}`
10
+
11
+ const postSizeComponents: string[] = ['center', 'middle']
12
+ quality && postSizeComponents.push(`filters:quality(${quality || 80})`)
13
+ postSizeComponents.push(encodeURIComponent(src))
14
+
15
+ return [...preSizeComponents, finalSize, ...postSizeComponents].join('/')
16
+ }
@@ -1,21 +1,15 @@
1
- import { useEffect, useState } from 'react'
2
1
  import {
3
- ImageGallery as UIImageGallery,
4
2
  ImageElementData,
5
3
  ImageZoom,
4
+ ImageGallery as UIImageGallery,
6
5
  } from '@faststore/ui'
6
+ import { useEffect, useState } from 'react'
7
7
 
8
- import { Image } from 'src/components/ui/Image'
9
8
  import { useRouter } from 'next/router'
9
+ import { Image } from 'src/components/ui/Image'
10
10
 
11
11
  const ImageComponent = ({ url, alternateName }) => (
12
- <Image
13
- src={url}
14
- alt={alternateName}
15
- sizes="(max-width: 72px) 25vw, 30vw"
16
- width={72}
17
- height={72}
18
- />
12
+ <Image src={url} alt={alternateName} width={68} height={68} />
19
13
  )
20
14
 
21
15
  export interface ImageGalleryProps {
@@ -41,11 +35,10 @@ const ImageGallery = ({ images, ...otherProps }: ImageGalleryProps) => {
41
35
  <Image
42
36
  src={currentImage.url}
43
37
  alt={currentImage.alternateName}
44
- sizes="(max-width: 804px) 25vw, 30vw"
45
- width={804}
46
- height={804 * (3 / 4)}
38
+ sizes="(max-width: 768px) 25vw, 30vw"
39
+ width={691}
40
+ height={691 * (3 / 4)}
47
41
  loading="eager"
48
- priority
49
42
  />
50
43
  </ImageZoom>
51
44
  </UIImageGallery>
@@ -1,10 +1,15 @@
1
- import { Icon, Incentive as UIIncentive, List as UIList } from '@faststore/ui'
1
+ import {
2
+ Icon as UIIcon,
3
+ List as UIList,
4
+ Incentive as UIIncentive,
5
+ } from '@faststore/ui'
2
6
 
3
- interface Incentive {
7
+ export type Incentive = {
4
8
  icon: string
5
- title?: string
9
+ title: string
6
10
  firstLineText: string
7
11
  secondLineText?: string
12
+ alt?: string
8
13
  }
9
14
 
10
15
  export interface IncentivesProps {
@@ -34,16 +39,15 @@ function Incentives({
34
39
  {incentives.map((incentive, index) => (
35
40
  <li key={String(index)}>
36
41
  <UIIncentive>
37
- <Icon
42
+ <UIIcon
38
43
  data-fs-incentive-icon
44
+ aria-label={incentive.alt}
39
45
  name={incentive.icon}
40
46
  width={32}
41
47
  height={32}
42
48
  />
43
49
  <div data-fs-incentive-content>
44
- {incentive.title && (
45
- <p data-fs-incentive-title>{incentive.title}</p>
46
- )}
50
+ <p data-fs-incentive-title>{incentive.title}</p>
47
51
  <span data-fs-incentive-description>
48
52
  {incentive.firstLineText}
49
53
  </span>
@@ -1,2 +1,2 @@
1
1
  export { default } from './Incentives'
2
- export type { IncentivesProps } from './Incentives'
2
+ export type { IncentivesProps, Incentive } from './Incentives'
@@ -1,12 +1,8 @@
1
- import { HTMLAttributes, useCallback, useMemo } from 'react'
1
+ import { HTMLAttributes } from 'react'
2
2
 
3
- import { Image } from '../Image'
4
- import {
5
- SkuSelector as UISkuSelector,
6
- SkuSelectorProps,
7
- SkuOption,
8
- } from '@faststore/ui'
3
+ import { SkuSelectorProps, SkuSelector as UISkuSelector } from '@faststore/ui'
9
4
  import NextLink from 'next/link'
5
+ import { Image } from '../Image'
10
6
 
11
7
  export type SkuVariantsByName = Record<
12
8
  string,
@@ -32,16 +28,7 @@ const ImageComponent: SkuSelectorProps['ImageComponent'] = ({
32
28
  src,
33
29
  alt,
34
30
  ...otherProps
35
- }) => (
36
- <Image
37
- src={src}
38
- alt={alt}
39
- width={20}
40
- height={20}
41
- loading="lazy"
42
- {...otherProps}
43
- />
44
- )
31
+ }) => <Image src={src} alt={alt} width={34} height={34} {...otherProps} />
45
32
 
46
33
  function Selectors({
47
34
  slugsMap,
package/src/pages/404.tsx CHANGED
@@ -1,6 +1,5 @@
1
1
  import { NextSeo } from 'next-seo'
2
2
  import { useRouter } from 'next/router'
3
- import { EmptyState as UIEmptyState, Icon as UIIcon } from '@faststore/ui'
4
3
  import GlobalSections, {
5
4
  GlobalSectionsData,
6
5
  getGlobalSectionsData,
@@ -8,6 +7,9 @@ import GlobalSections, {
8
7
  import { GetStaticProps } from 'next'
9
8
  import { Locator } from '@vtex/client-cms'
10
9
 
10
+ import { Icon as UIIcon } from '@faststore/ui'
11
+ import EmptyState from 'src/components/sections/EmptyState'
12
+
11
13
  const useErrorState = () => {
12
14
  const router = useRouter()
13
15
  const { from } = router.query
@@ -29,7 +31,7 @@ function Page({ globalSections }: Props) {
29
31
  <GlobalSections {...globalSections}>
30
32
  <NextSeo noindex nofollow />
31
33
 
32
- <UIEmptyState
34
+ <EmptyState
33
35
  title="Not Found: 404"
34
36
  titleIcon={
35
37
  <UIIcon
@@ -39,10 +41,9 @@ function Page({ globalSections }: Props) {
39
41
  weight="thin"
40
42
  />
41
43
  }
42
- bkgColor="light"
43
44
  >
44
45
  <p>This app could not find url {fromUrl}</p>
45
- </UIEmptyState>
46
+ </EmptyState>
46
47
  </GlobalSections>
47
48
  )
48
49
  }
package/src/pages/500.tsx CHANGED
@@ -7,6 +7,9 @@ import GlobalSections, {
7
7
  getGlobalSectionsData,
8
8
  } from 'src/components/cms/GlobalSections'
9
9
 
10
+ import { Icon as UIIcon } from '@faststore/ui'
11
+ import EmptyState from 'src/components/sections/EmptyState'
12
+
10
13
  type Props = {
11
14
  globalSections: GlobalSectionsData
12
15
  }
@@ -28,12 +31,23 @@ function Page({ globalSections }: Props) {
28
31
  <GlobalSections {...globalSections}>
29
32
  <NextSeo noindex nofollow />
30
33
 
31
- <h1>500</h1>
32
- <h2>Internal Server Error</h2>
34
+ <EmptyState
35
+ title="500"
36
+ titleIcon={
37
+ <UIIcon
38
+ name="CircleWavyWarning"
39
+ width={56}
40
+ height={56}
41
+ weight="thin"
42
+ />
43
+ }
44
+ >
45
+ <h2>Internal Server Error</h2>
33
46
 
34
- <div>
35
- The server errored with id {errorId} when visiting page {fromUrl}
36
- </div>
47
+ <div>
48
+ The server errored with id {errorId} when visiting page {fromUrl}
49
+ </div>
50
+ </EmptyState>
37
51
  </GlobalSections>
38
52
  )
39
53
  }
@@ -11,7 +11,6 @@ import { BreadcrumbJsonLd, NextSeo } from 'next-seo'
11
11
  import { useRouter } from 'next/router'
12
12
  import { useMemo } from 'react'
13
13
 
14
- import { Icon } from '@faststore/ui'
15
14
  import type {
16
15
  ServerCollectionPageQueryQuery,
17
16
  ServerCollectionPageQueryQueryVariables,
@@ -6,7 +6,7 @@ import type { ComponentType } from 'react'
6
6
  import RenderSections from 'src/components/cms/RenderSections'
7
7
  import BannerText from 'src/components/sections/BannerText'
8
8
  import Hero from 'src/components/sections/Hero'
9
- import IncentivesHeader from 'src/components/sections/IncentivesHeader/IncentivesHeader'
9
+ import Incentives from 'src/components/sections/Incentives'
10
10
  import Newsletter from 'src/components/sections/Newsletter'
11
11
  import ProductShelf from 'src/components/sections/ProductShelf'
12
12
  import ProductTiles from 'src/components/sections/ProductTiles'
@@ -24,7 +24,7 @@ import GlobalSections, {
24
24
  /* A list of components that can be used in the CMS. */
25
25
  const COMPONENTS: Record<string, ComponentType<any>> = {
26
26
  Hero,
27
- IncentivesHeader,
27
+ Incentives,
28
28
  ProductShelf,
29
29
  ProductTiles,
30
30
  BannerText,
@@ -1,6 +1,5 @@
1
1
  import { useEffect } from 'react'
2
2
  import { NextSeo } from 'next-seo'
3
- import { EmptyState as UIEmptyState, Loader as UILoader } from '@faststore/ui'
4
3
 
5
4
  import storeConfig from '../../faststore.config'
6
5
  import GlobalSections, {
@@ -10,6 +9,9 @@ import GlobalSections, {
10
9
  import { GetStaticProps } from 'next'
11
10
  import { Locator } from '@vtex/client-cms'
12
11
 
12
+ import { Loader as UILoader } from '@faststore/ui'
13
+ import EmptyState from 'src/components/sections/EmptyState'
14
+
13
15
  type Props = {
14
16
  globalSections: GlobalSectionsData
15
17
  }
@@ -23,9 +25,9 @@ function Page({ globalSections }: Props) {
23
25
  <GlobalSections {...globalSections}>
24
26
  <NextSeo noindex nofollow />
25
27
 
26
- <UIEmptyState title="Loading" bkgColor="light">
28
+ <EmptyState title="Loading">
27
29
  <UILoader />
28
- </UIEmptyState>
30
+ </EmptyState>
29
31
  </GlobalSections>
30
32
  )
31
33
  }
@@ -0,0 +1,13 @@
1
+ //Input "Example Text!". Output: example-text
2
+ export function textToKebabCase(text: string): string {
3
+ // Replace spaces and special characters with hyphens
4
+ let kebabCase = text.replace(/[^\w\s]/gi, '-')
5
+
6
+ // Remove whitespace
7
+ kebabCase = kebabCase.replace(/\s+/g, '-')
8
+
9
+ // Convert to lowercase
10
+ kebabCase = kebabCase.toLowerCase()
11
+
12
+ return kebabCase ?? ''
13
+ }
@@ -1,26 +0,0 @@
1
- import { Icon } from '@faststore/ui'
2
-
3
- const FooterFlags = [
4
- { image: <Icon width={32} height={22.5} name="Visa" />, text: 'Visa' },
5
- {
6
- image: <Icon width={32} height={22.5} name="Diners" />,
7
- text: 'Diners Club',
8
- },
9
- {
10
- image: <Icon width={32} height={22.5} name="Mastercard" />,
11
- text: 'Mastercard',
12
- },
13
- { image: <Icon width={32} height={22.5} name="EloCard" />, text: 'Elo Card' },
14
- { image: <Icon width={32} height={22.5} name="PayPal" />, text: 'PayPal' },
15
- { image: <Icon width={32} height={22.5} name="Stripe" />, text: 'Stripe' },
16
- {
17
- image: <Icon width={32} height={22.5} name="GooglePay" />,
18
- text: 'GooglePay',
19
- },
20
- {
21
- image: <Icon width={32} height={22.5} name="ApplePay" />,
22
- text: 'ApplePay',
23
- },
24
- ]
25
-
26
- export default FooterFlags
@@ -1,24 +0,0 @@
1
- import Incentives from 'src/components/ui/Incentives/Incentives'
2
- import Section from '../Section'
3
- import styles from './section.module.scss'
4
-
5
- interface Incentive {
6
- icon: string
7
- title?: string
8
- firstLineText: string
9
- secondLineText?: string
10
- }
11
-
12
- interface Props {
13
- incentives: Incentive[]
14
- }
15
-
16
- function IncentivesHeader({ incentives }: Props) {
17
- return (
18
- <Section className={`${styles.section} section-incentives-header`}>
19
- <Incentives incentives={incentives} colored />
20
- </Section>
21
- )
22
- }
23
-
24
- export default IncentivesHeader