[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreImage/Image.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { ImgHTMLAttributes, Fragment } from 'react'
import useCssHandles from '../CssHandles/useCssHandles'
import { injectIntl, WrappedComponentProps, defineMessages } from 'react-intl'
import formatIOMessage from '../NativeTypes/formatIOMessage'

export interface ImageProps extends ImgHTMLAttributes<HTMLImageElement>, WrappedComponentProps {
  maxWidth?: string | number
  maxHeight?: string | number
  minWidth?: string | number
  minHeight?: string | number
  blockClass?: string
  link?: {
    url: string
    noFollow: boolean
    openNewTab: boolean
    title: string
  }
}

const CSS_HANDLES = ['imageElement', 'imageElementLink'] as const

const Image: StorefrontFunctionComponent<ImageProps> = ({
  src,
  alt = '',
  maxWidth,
  maxHeight,
  minWidth,
  minHeight,
  width,
  height,
  srcSet = '',
  sizes = '',
  link,
  intl,
}) => {
  const handles = useCssHandles(CSS_HANDLES, {
    migrationFrom: 'vtex.store-components@3.x',
  })
  const imageDimensions = {
    minWidth,
    minHeight,
    maxWidth,
    maxHeight,
    width,
    height,
  }

  const formattedSrc = formatIOMessage({ id: src, intl })
  const formattedAlt = formatIOMessage({ id: alt, intl })

  const imgElement = (
    <img
      src={formattedSrc}
      srcSet={srcSet}
      sizes={sizes}
      alt={formattedAlt}
      style={imageDimensions}
      className={handles.imageElement}
    />
  )

  return link ? (
    <a
      href={formatIOMessage({ id: link.url, intl })}
      rel={link.noFollow ? 'nofollow' : ''}
      target={link.openNewTab ? '_blank' : ''}
      title={formatIOMessage({ id: link.title, intl })}
      className={handles.imageElementLink}>
      {imgElement}
    </a>
  ) : (
    <Fragment>{imgElement}</Fragment>
  )
}

const messages = defineMessages({
  title: {
    defaultMessage: '',
    id: 'admin/editor.store-image.title',
  },
  description: {
    defaultMessage: '',
    id: 'admin/editor.store-image.description',
  },
  blockClassTitle: {
    defaultMessage: '',
    id: 'admin/editor.store-image.blockClass.title',
  },
  blockClassDescription: {
    defaultMessage: '',
    id: 'admin/editor.store-image.blockClass.description',
  },
})

Image.schema = {
  title: messages.title.id,
  description: messages.description.id,
  type: 'object',
  properties: {
    blockClass: {
      title: messages.blockClassTitle.id,
      description: messages.blockClassDescription.id,
      type: 'string',
      isLayout: true,
    },
  },
}

export default injectIntl(Image)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreImage/ImageSlider.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'
import SliderLayout from '../SliderLayout/SliderLayout'
import useDevice from '../DeviceDetector/useDevice'
import formatIOMessage from '../NativeTypes/formatIOMessage'

import Image from './Image'

interface Image {
  link?: {
    url: string
    noFollow: boolean
    openNewTab: boolean
    title: string
  }
  image: string
  mobileImage: string
  description: string
}

interface SliderConfig {
  itemsPerPage: {
    desktop: number
    tablet: number
    phone: number
  }
  showNavigationArrows: 'mobileOnly' | 'desktopOnly' | 'always' | 'never'
  showPaginationDots: 'mobileOnly' | 'desktopOnly' | 'always' | 'never'
  usePagination: boolean
  infinite: boolean
}

interface Props {
  images: Image[]
  height: number
  sliderLayoutConfig: SliderConfig
}

function getImageUrl(isMobile: boolean, image: string, mobileImage: string) {
  return !!mobileImage && isMobile ? mobileImage : image
}

const ImageSlider: StorefrontFunctionComponent<Props & WrappedComponentProps> = ({
  images,
  height,
  sliderLayoutConfig = {
    itemsPerPage: {
      desktop: 1,
      tablet: 1,
      phone: 1,
    },
    infinite: true,
    showNavigationArrows: 'always',
    showPaginationDots: 'always',
    usePagination: true,
  },
  intl,
}) => {
  const { isMobile } = useDevice()

  return (
    <SliderLayout {...sliderLayoutConfig} totalItems={images.length}>
      {images.map(({ link, image, mobileImage, description }, idx) => {
        const imageUrl = getImageUrl(
          isMobile,
          formatIOMessage({ id: image, intl }),
          formatIOMessage({ id: mobileImage, intl })
        )
        const imageAltDescription = formatIOMessage({ id: description, intl })
        const imageLink = link && {
          ...link,
          url: formatIOMessage({ id: link.url, intl }),
          title: formatIOMessage({ id: link.title, intl }),
        }

        return (
          <Image
            key={idx}
            src={imageUrl}
            alt={imageAltDescription}
            link={imageLink}
            maxHeight={height}
            width="100%"
          />
        )
      })}
    </SliderLayout>
  )
}

const messages = defineMessages({
  title: { id: 'admin/editor.image-slider.title', defaultMessage: '' },
  description: {
    id: 'admin/editor.image-slider.description',
    defaultMessage: '',
  },
  imagesImageTitle: {
    id: 'admin/editor.image-list.images.image.title',
    defaultMessage: '',
  },
  imagesMobileImageTitle: {
    id: 'admin/editor.image-list.images.mobileImage.title',
    defaultMessage: '',
  },
  imagesImageDescription: {
    id: 'admin/editor.image-list.images.description.title',
    defaultMessage: '',
  },
  imagesImageLinkUrl: {
    id: 'admin/editor.image-list.images.link.url.title',
    defaultMessage: '',
  },
  imagesImageLinkOpenNewTab: {
    id: 'admin/editor.image-list.images.link.openNewTab.title',
    defaultMessage: '',
  },
  imagesImageLinkNoFollow: {
    id: 'admin/editor.image-list.images.link.noFollow.title',
    defaultMessage: '',
  },
  imagesImageLinkTitle: {
    id: 'admin/editor.image-list.images.link.title.title',
    defaultMessage: '',
  },
  imagesTitle: {
    id: 'admin/editor.image-list.images.title',
    defaultMessage: '',
  },
  heightTitle: {
    id: 'admin/editor.image-list.height.title',
    defaultMessage: '',
  },
  sliderTitle: {
    id: 'admin/editor.image-slider.slider.title',
    defaultMessage: '',
  },
  sliderInfinite: {
    id: 'admin/editor.image-slider.slider.infinite',
    defaultMessage: '',
  },
  sliderShowNavigation: {
    id: 'admin/editor.image-slider.slider.showNavigation',
    defaultMessage: '',
  },
  sliderShowPaginationDots: {
    id: 'admin/editor.image-slider.slider.showPaginationDots',
    defaultMessage: '',
  },
  sliderUsePagination: {
    id: 'admin/editor.image-slider.slider.usePagination',
    defaultMessage: '',
  },
})

ImageSlider.schema = {
  title: messages.title.id,
  description: messages.description.id,
  type: 'object',
  properties: {
    height: {
      default: 420,
      enum: [420, 440],
      isLayout: true,
      title: messages.heightTitle.id,
      type: 'number',
    },
    sliderLayoutConfig: {
      title: messages.sliderTitle.id,
      properties: {
        infinite: {
          default: true,
          title: messages.sliderInfinite.id,
          type: 'boolean',
        },
        showNavigationArrows: {
          default: 'always',
          enum: ['mobileOnly', 'desktopOnly', 'always', 'never'],
          title: messages.sliderShowNavigation.id,
          type: 'string',
        },
        showPaginationDots: {
          default: 'always',
          enum: ['mobileOnly', 'desktopOnly', 'always', 'never'],
          title: messages.sliderShowPaginationDots.id,
          type: 'string',
        },
        usePagination: {
          default: true,
          title: messages.sliderUsePagination.id,
          type: 'boolean',
        },
      },
      type: 'object',
    },
  },
}

export default injectIntl(ImageSlider)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ProductSpecificationBadges/index.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import useProduct from '../ProductContext/useProduct'
import BaseSpecificationBadges from './components/BaseSpecificationBadges'

const ProductSpecificationBadges: StorefrontFunctionComponent<BaseProps> = ({
  specificationGroupName,
  visibleWhen,
  specificationsOptions,
  specificationName,
  displayValue,
  orientation
}) => {
  const { product } = useProduct() as any
  return (
    <BaseSpecificationBadges
      product={product}
      orientation={orientation}
      specificationGroupName={specificationGroupName}
      visibleWhen={visibleWhen}
      specificationsOptions={specificationsOptions}
      specificationName={specificationName}
      displayValue={displayValue}
    />
  )
}

ProductSpecificationBadges.schema = {
  ...BaseSpecificationBadges.schema,
  title: 'admin/editor.product-specification-badges.title',
  description: 'admin/editor.product-specification-badges.description',
}

export default ProductSpecificationBadges

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ProductSpecificationBadges/BaseSpecificationBadges.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import BaseSpecificationBadges from './components/BaseSpecificationBadges'

export default BaseSpecificationBadges

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ListContext/useListContext.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useContext } from 'react'
import { ListContext } from './ListContextProvider'

const useListContext = () => {
  return useContext(ListContext)
}

export default useListContext

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ListContext/ListContextProvider.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useMemo, FC } from 'react'

export interface ListContextProps {
  list: JSX.Element[]
}

export const ListContext = React.createContext<ListContextProps>({
  list: [],
})
ListContext.displayName = 'ListContext'

const ListContextProvider: FC<ListContextProps> = ({ list = [], children }) => {
  const value = useMemo(() => ({ list }), [list])
  return <ListContext.Provider value={value}>{children}</ListContext.Provider>
}
ListContextProvider.displayName = 'ListContextProvider'

export default ListContextProvider

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ListContext/package.json from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "lint": "tsc --noEmit && eslint --quiet --fix --ext ts,tsx .",
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "apollo-client": "^2.6.3",
    "ramda": "^0.26.1",
    "react": "^16.8.6",
    "react-apollo": "^2.5.8",
    "react-dom": "^16.8.6",
    "react-intl": "^2.9.0"
  },
  "devDependencies": {
    "@types/graphql": "^14.2.2",
    "@types/ramda": "^0.26.33",
    "@types/react": "^16.8.22",
    "@types/react-intl": "^2.3.18",
    "@vtex/test-tools": "^0.3.2",
    "@vtex/tsconfig": "^0.2.0",
    "eslint": "^6.4.0",
    "eslint-config-vtex": "^11.0.0",
    "eslint-config-vtex-react": "^5.0.1",
    "prettier": "^1.18.2",
    "prop-types": "^15.7.2",
    "typescript": "3.5.2"
  },
  "version": "0.1.1"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/OrderItems/OrderItems.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable react-hooks/exhaustive-deps */
import React, {
  createContext,
  FC,
  useCallback,
  useContext,
  useMemo,
  useRef,
} from 'react'
import { useMutation } from 'react-apollo'
import OrderQueue from '../OrderManager/OrderQueue'
import OrderFormOrder from '../OrderManager/OrderForm'
import { loader } from 'graphql.macro'

const {
  QueueStatus,
  useOrderQueue,
  useQueueStatus,
} = OrderQueue

const UpdateItems = loader('../CheckoutResources/mutations/updateItems.graphql')

const { useOrderForm } = OrderFormOrder

const AVAILABLE = 'available'
const TASK_CANCELLED = 'TASK_CANCELLED'

enum Totalizers {
  SUBTOTAL = 'Items',
  DISCOUNT = 'Discounts',
}

interface Context {
  updateQuantity: (props: Partial<Item>) => void
  removeItem: (props: Partial<Item>) => void
}

interface CancellablePromiseLike<T> extends Promise<T> {
  cancel: () => void
}

interface EnqueuedTask {
  promise?: CancellablePromiseLike<any>
  variables?: any
}

const OrderItemsContext = createContext<Context | undefined>(undefined)

const noop = async (_: Partial<Item>) => {}

const maybeUpdateTotalizers = (
  totalizers: Totalizer[],
  value: number,
  oldItem: Item,
  newItem: Item
) => {
  if (oldItem.availability !== AVAILABLE) {
    return {}
  }

  const oldPrice = oldItem.price * oldItem.quantity
  const newPrice = newItem.price * newItem.quantity
  const subtotalDifference = newPrice - oldPrice

  const oldDiscount = (oldItem.sellingPrice - oldItem.price) * oldItem.quantity
  const newDiscount = (newItem.sellingPrice - newItem.price) * newItem.quantity
  const discountDifference = newDiscount - oldDiscount

  const newTotalizers = totalizers.map((totalizer: Totalizer) => {
    switch (totalizer.id) {
      case Totalizers.SUBTOTAL:
        return { ...totalizer, value: totalizer.value + subtotalDifference }
      case Totalizers.DISCOUNT:
        return { ...totalizer, value: totalizer.value + discountDifference }
      default:
        return totalizer
    }
  })
  const newValue = value + subtotalDifference + discountDifference

  return { totalizers: newTotalizers, value: newValue }
}

const enqueueTask = ({
  task,
  enqueue,
  queueStatusRef,
  setOrderForm,
  taskId,
}: {
  task: () => Promise<any>
  enqueue: (task: any, id?: string) => CancellablePromiseLike<any>
  queueStatusRef: React.MutableRefObject<any>
  setOrderForm: (orderForm: Partial<OrderForm>) => void
  taskId?: string
}) => {
  const promise = enqueue(task, taskId)
  const cancelPromise = promise.cancel
  const newPromise = promise
    .then((newOrderForm: OrderForm) => {
      if (queueStatusRef.current === QueueStatus.FULFILLED) {
        setOrderForm(newOrderForm)
      }
    })
    .catch((error: any) => {
      if (!error || error.code !== TASK_CANCELLED) {
        throw error
      }
    }) as CancellablePromiseLike<void>

  newPromise.cancel = cancelPromise
  return newPromise
}

export const OrderItemsProvider: FC = ({ children }) => {
  const { enqueue, listen, isWaiting } = useOrderQueue()
  const { loading, orderForm, setOrderForm } = useOrderForm()

  const [updateItems] = useMutation(UpdateItems)

  const queueStatusRef = useQueueStatus(listen)
  const lastUpdateTaskRef = useRef({
    promise: undefined,
    variables: undefined,
  } as EnqueuedTask)

  if (!orderForm) {
    throw new Error('Unable to fetch order form.')
  }

  const { items, totalizers, value: orderFormValue } = orderForm

  const itemIds = useCallback(
    (props: Partial<Item>) => {
      let index = props.index
      let uniqueId = props.uniqueId

      if (index) {
        uniqueId = items[index].uniqueId as string
      } else if (uniqueId) {
        index = items.findIndex(
          (item: Item) => item.uniqueId === props.uniqueId
        ) as number
      } else {
        throw new Error(
          'Either index or uniqueId must be provided when updating an item'
        )
      }

      return { index, uniqueId }
    },
    [items]
  )

  const updateOrderForm = useCallback(
    (index: number, props: Partial<Item>) => {
      const newItem = { ...items[index], ...props }

      const updatedList = [
        ...items.slice(0, index),
        ...(props.quantity === 0 ? [] : [newItem]),
        ...items.slice(index + 1),
      ]

      setOrderForm({
        ...maybeUpdateTotalizers(
          totalizers,
          orderFormValue,
          items[index],
          newItem
        ),
        items: updatedList,
      })
    },
    [items, totalizers, orderFormValue, setOrderForm]
  )

  const mutationTask = useCallback(
    (items: Partial<Item>[]) => async () => {
      const {
        data: { updateItems: newOrderForm },
      } = await updateItems({
        variables: {
          orderItems: items,
        },
      })

      return newOrderForm
    },
    [updateItems]
  )

  const updateQuantity = useCallback(
    async (props: Partial<Item>) => {
      const { index, uniqueId } = itemIds(props)
      updateOrderForm(index, { quantity: props.quantity })
      const taskId = 'OrderItems-updateQuantity'
      let items = [{ uniqueId, quantity: props.quantity }]

      if (lastUpdateTaskRef.current.promise && isWaiting(taskId)) {
        lastUpdateTaskRef.current.promise.cancel()
        items = [
          ...lastUpdateTaskRef.current.variables.filter(
            (item: Pick<Item, 'uniqueId'>) => item.uniqueId !== uniqueId
          ),
          ...items,
        ]
      }

      lastUpdateTaskRef.current.promise = enqueueTask({
        task: mutationTask(items),
        enqueue: enqueue as any,
        queueStatusRef,
        setOrderForm,
        taskId,
      })
      lastUpdateTaskRef.current.variables = items
    },
    [enqueue, itemIds, mutationTask, setOrderForm, updateOrderForm]
  )

  const removeItem = useCallback(
    (props: Partial<Item>) => updateQuantity({ ...props, quantity: 0 }),
    [updateQuantity]
  )

  const value = useMemo(
    () =>
      loading
        ? {
            updateQuantity: noop,
            removeItem: noop,
          }
        : { updateQuantity, removeItem },
    [loading, updateQuantity, removeItem]
  )

  return (
    <OrderItemsContext.Provider value={value}>
      {children}
    </OrderItemsContext.Provider>
  )
}

export const useOrderItems = () => {
  const context = useContext(OrderItemsContext)
  if (context === undefined) {
    throw new Error('useOrderItems must be used within a OrderItemsProvider')
  }

  return context
}

export default { OrderItemsProvider, useOrderItems }

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/CssHandles/applyModifiers.ts from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```typescript
const validateModifier = (modifier: string) => {
  if (typeof modifier !== 'string') {
    console.error(
      `Invalid modifier type on \`cssHandles.applyModifier\`. All modifiers should be strings, found "${modifier}" `
    )
    return false
  }

  /* This is not an error, so doesn't log any message, but should
   * invalidate the current modifier and not include it*/
  if (modifier === '') {
    return false
  }

  if (/[^A-z0-9-]/.test(modifier)) {
    console.error(
      `Invalid modifier on \`cssHandles.applyModifier\`. Modifiers should contain only letters, numbers or -`
    )
    return false
  }

  return true
}

const applyModifiers = (handles: string, modifier: string | string[]) => {
  const normalizedModifiers =
    typeof modifier === 'string' ? [modifier] : modifier
  if (!Array.isArray(normalizedModifiers)) {
    console.error(
      'Invalid modifier type on `cssHandles.applyModifier`. Please use either a string or an array of strings'
    )
    return handles
  }

  const splitHandles = handles?.split(' ')

  const modifiedHandles = normalizedModifiers
    .map(currentModifier => {
      const isValid = validateModifier(currentModifier)

      if (!isValid) {
        return ''
      }

      return splitHandles
        ?.map(handle => `${handle}--${currentModifier}`)
        .join(' ')
        .trim()
    })
    .filter(l => l?.length > 0)
    .join(' ')
    .trim()

  return splitHandles
    ?.concat(modifiedHandles)
    .join(' ')
    .trim()
}

export default applyModifiers

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/CssHandles/package.json from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "lint": "tsc --noEmit && eslint --quiet --fix --ext ts,tsx .",
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "apollo-client": "^2.6.3",
    "react": "^16.10.1",
    "react-apollo": "^2.5.8",
    "react-dom": "^16.8.6",
    "react-intl": "^2.9.0"
  },
  "devDependencies": {
    "@types/graphql": "^14.2.2",
    "@types/react": "^16.9.4",
    "@types/react-intl": "^2.3.18",
    "@vtex/test-tools": "^0.3.2",
    "@vtex/tsconfig": "^0.2.0",
    "eslint": "5.x",
    "eslint-config-vtex-react": "^5.0.1",
    "prettier": "^1.18.2",
    "prop-types": "^15.7.2",
    "typescript": "3.5.2"
  },
  "version": "0.4.1"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/CssHandles/withCssHandles.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import useCssHandles from './useCssHandles'
import { ComponentType } from 'react'

const withCssHandles = <T extends CssHandlesInput, ComponentProps>(
  handles: T,
  options?: CssHandlesOptions
) => (
  Component: ComponentType<ComponentProps & { cssHandles: CssHandles<T> }>
) => {
  const EnhancedComponent = (props: ComponentProps) => {
    const cssHandles = useCssHandles(handles, options)

    return <Component cssHandles={cssHandles} {...props} />
  }

  const displayName = Component.displayName || Component.name || 'Component'
  EnhancedComponent.displayName = `withCssHandles(${displayName})`

  return EnhancedComponent
}

export default withCssHandles

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/CssHandles/useCssHandles.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useMemo } from 'react'
import { useExtension } from './hooks/useExtension'
import applyModifiers from './applyModifiers'

/** Verifies if the handle contains only letters and numbers, and does not begin with a number  */
const validateCssHandle = (handle: string) => !/^\d|[^A-z0-9]/.test(handle)

const parseComponentName = (componentName: string) => {
  /* Matches until the first `.` or `@`.
   * Used to split something like `vtex.style-guide@2.0.1` into
   * `vtex`, `style-guide`, and `2`. */
  const splitAppName = /[^@.]+/g

  /* regex.exec is stateful, this is why running the command 3 times
   * provides 3 different results. Yeah I know.
   * There exists a `String.matchAll()` function but it's not
   * supported on Safari */
  const [vendor] = splitAppName.exec(componentName) || [null]
  const [name] = splitAppName.exec(componentName) || [null]
  const [major] = splitAppName.exec(componentName) || [null]

  return { vendor, name, major }
}

const normalizeComponentName = (componentName: string) => {
  const { vendor, name, major } = parseComponentName(componentName)

  return vendor && name && major && `${vendor}-${name}-${major}-x`
}

const generateCssHandles = <T extends CssHandlesInput>(
  namespace: string,
  handles: T,
  modifiers?: string | string[]
) => {
  return handles.reduce<Record<string, string>>((acc, handle) => {
    const isValid = !!namespace && validateCssHandle(handle)
    const transformedHandle = `${namespace}-${handle}`
    acc[handle] = isValid
      ? modifiers
        ? applyModifiers(transformedHandle, modifiers)
        : transformedHandle
      : ''

    if (!isValid) {
      console.error(
        `Invalid CSS handle "${handle}". It should only contain letters or numbers, and should start with a letter.`
      )
    }

    return acc
  }, {}) as CssHandles<T>
}

/**
 * Useful for creating CSS handles without creating a CSS file with empty
 * declarations.
 * Receives an array of strings (e.g. ['foo', 'bar']) and returns an
 * object with generated css class names, e.g.
 * { foo: 'vendor-appname-1-x-foo', bar: 'vendor-appname-1-x-bar' }.
 */
const useCssHandles = <T extends CssHandlesInput>(
  handles: T,
  options: CssHandlesOptions = {}
): CssHandles<T> => {
  const extension = useExtension()

  const { props = {}, component = '' } = extension || {}
  const blockClass = props.cssHandle || props.blockClass || options.blockClass

  const values = useMemo<CssHandles<T>>(() => {
    const { migrationFrom } = options
    const normalizedComponent = normalizeComponentName(component)

    const namespaces = normalizedComponent ? [normalizedComponent] : []
    if (migrationFrom) {
      const migrations = Array.isArray(migrationFrom)
        ? migrationFrom
        : [migrationFrom]

      const normalizedMigrations = migrations
        .map(normalizeComponentName)
        .filter(
          current => !!current && current !== normalizedComponent
        ) as string[]

      namespaces.push(...normalizedMigrations)
    }

    return namespaces
      .map(component => generateCssHandles(component, handles, blockClass))
      .reduce<CssHandles<T>>(
        (acc: null | CssHandles<T>, cur: CssHandles<T>) => {
          if (!acc) {
            return cur
          }
          Object.keys(cur).forEach((key: ValueOf<T>) => {
            acc[key] = `${acc[key]} ${cur[key]}`
          })
          return acc
        },
        undefined as any
      )
  }, [blockClass, component, handles, options])

  return values || {} as any
}

export default useCssHandles

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/RichText/index.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent, memo, useEffect, useState, useRef, useMemo } from 'react'
import { injectIntl, WrappedComponentProps } from 'react-intl'
import marked, { Renderer } from 'marked'
import { values, last, test } from 'ramda'
import escapeHtml from 'escape-html'
import insane from 'insane'
import useCssHandles from '../CssHandles/useCssHandles'

import formatIOMessage from '../NativeTypes/formatIOMessage'

//@ts-ignore
import styles from './styles/index.css'

import {
  textPositionTypes,
  textAlignmentTypes,
  textPositionValues,
  textAlignmentValues,
} from './typings/SchemaTypes'

const CSS_HANDLES = [
  'container',
  'paragraph',
  'strong',
  'italic',
  'heading',
  'link',
  'table',
  'tableHead',
  'tableBody',
  'headingLevel1',
  'headingLevel2',
  'headingLevel3',
  'headingLevel4',
  'headingLevel5',
  'headingLevel6',
  'list',
  'listOrdered',
  'listItem',
  'image'
] as const

const justifyTokens = {
  [textPositionValues.LEFT]: 'justify-start',
  [textPositionValues.CENTER]: 'justify-center',
  [textPositionValues.RIGHT]: 'justify-end',
}

const alignTokens = {
  [textAlignmentValues.LEFT]: 'tl',
  [textAlignmentValues.CENTER]: 'tc',
  [textAlignmentValues.RIGHT]: 'tr',
}

const itemsTokens = {
  [textAlignmentValues.LEFT]: 'items-start',
  [textAlignmentValues.CENTER]: 'items-center',
  [textAlignmentValues.RIGHT]: 'items-end',
}

type PropTokensNames = 'textPosition' | 'textAlignment'

const defaultValues = {
  textPosition: textPositionTypes.TEXT_POSITION_LEFT.value,
  textAlignment: textAlignmentTypes.TEXT_ALIGNMENT_LEFT.value,
}

const getEnumValues = (
  enumObject: Record<string, { value: string; name: string }>
) => values(enumObject).map(({ value }) => value)
const getEnumNames = (
  enumObject: Record<string, { value: string; name: string }>
) => values(enumObject).map(({ name }) => name)

const safelyGetToken = (
  tokenMap: Record<string, string>,
  valueWanted: string,
  propName: PropTokensNames
) => tokenMap[valueWanted] || defaultValues[propName]

interface Props extends WrappedComponentProps {
  font: string
  text: string
  textAlignment: textAlignmentValues
  textColor: string
  textPosition: textPositionValues
  htmlId?: string
}

interface VTEXIOComponent extends FunctionComponent<Props> {
  schema?: any
}

type RichTextCssHandles = CssHandles<typeof CSS_HANDLES>

const sanitizerConfig = {
  allowedTags: ['p', 'span', 'a', 'div', 'br', 'img', 'iframe', 'table', 'thead', 'tbody', 'tr', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li'],
  allowedAttributes: {
    a: ['class', 'href', 'title', 'target'],
    span: ['class'],
    p: ['class'],
    div: ['class'],
    table: ['class'],
    thead: ['class'],
    tbody: ['class'],
    img: ['class', 'src', 'title', 'alt'],
    iframe: ['frameborder', 'height', 'src', 'width', 'style'],
    h1: ['class'],
    h2: ['class'],
    h3: ['class'],
    h4: ['class'],
    h5: ['class'],
    h6: ['class'],
    ul: ['class'],
    ol: ['class'],
    li: ['class'],
  },
  allowedSchemes: ['http', 'https', 'mailto', 'tel'],
}

const getLevel = (level: number) => level > 0 && level <= 6 ? level : 6

const getTargetFromUrl = (url: string) => {
  const urlSplit = url.split('?')
  if (urlSplit.length < 2) {
    return ''
  }
  const qs = urlSplit[1]
  const hastTargetBlank = qs.includes('target=_blank')
  return hastTargetBlank ? 'target=_blank' : ''
}

const typography = [
  't-heading-1',
  't-heading-2',
  't-heading-3',
  't-heading-4',
  't-heading-5',
  't-heading-6',
  't-body',
  't-small',
  't-mini',
  't-code',
]

const sanitizeFont = (font: string) => {
  if (!font) {
    return 't-body'
  }

  const first = font.split(' ')[0]

  if (typography.indexOf(first) === -1) {
    return 't-body'
  }

  return first
}

const sanitizeColor = (color: string) => {
  if (!color) {
    return 'c-on-base'
  }

  const first = color.split(' ')[0]

  if (first.indexOf('c-') === 0) {
    return first
  }

  return 'c-on-base'
}

const getHeadingLevelClass = (handles: RichTextCssHandles, level: number) => {
  switch (level) {
    case 1:
      return handles.headingLevel1
    case 2:
      return handles.headingLevel2
    case 3:
      return handles.headingLevel3
    case 4:
      return handles.headingLevel4
    case 5:
      return handles.headingLevel5
    case 6:
      return handles.headingLevel6
    default:
      return ''
  }
}

const renderHeading = (handles: RichTextCssHandles) => (text: string, level: number) => {
  const levelNumber = getLevel(level)
  const classes =
    `${handles.heading} t-heading-${levelNumber} ${getHeadingLevelClass(handles, levelNumber)} ${styles[`heading-level-${levelNumber}`]}`
  return `<h${levelNumber} class="${classes}">${text}</h${levelNumber}>`
}

const RichText: FunctionComponent<any> = ({
  font,
  text,
  textAlignment,
  textColor,
  textPosition,
  htmlId,
  intl,
  blockClass,
}) => {
  return null
  // const [isMounted, setMounted] = useState(false)
  // const handles = useCssHandles(CSS_HANDLES,{blockClass})
  // const renderer = useRef<Renderer>()
  // useEffect(() => {
  //   setMounted(true)
  // }, [])

  // if (!isMounted) {
  //   renderer.current = new Renderer()
  //   renderer.current.paragraph = text =>
  //     `<p class="lh-copy ${handles.paragraph}">${text}</p>`
  //   renderer.current.strong = text => `<span class="b ${handles.strong}">${text}</span>`
  //   renderer.current.em = text => `<span class="i ${handles.italic}">${text}</span>`
  //   renderer.current.heading = renderHeading(handles)
  //   renderer.current.link = (href: string, title: string, text: string) => {
  //     const targetAtr = getTargetFromUrl(href)
  //     const targetRemoved = !!targetAtr ? href.replace(/target=_blank/, '').replace(/\?\&/, '?') : href

  //     //clean trailing ? or &
  //     const cleanHref = test(/\?|\&/, last(targetRemoved)) ? targetRemoved.slice(0, -1) : targetRemoved
  //     const titleAtr = title ? `title="${title}"` : ''

  //     let finalLink = `<a class="${handles.link}" href="${cleanHref}"`
  //     if (titleAtr) {
  //       finalLink += ` ${titleAtr}`
  //     }

  //     if (targetAtr) {
  //       finalLink += ` ${targetAtr}`
  //     }

  //     finalLink += `>${text}</any>`
  //     return finalLink
  //   }
  //   renderer.current.html = html => escapeHtml(html)
  //   renderer.current.table = (header, body) => `
  //   <table class="${handles.table}">
  //     <thead class="${handles.tableHead}">
  //       ${header}
  //     </thead>
  //     <tbody class="${handles.tableBody}">
  //       ${body}
  //     </tbody>
  //   </table>`
  //   renderer.current.image = (href: string, title: string, text: string) =>
  //     `<img class="${
  //     handles.image
  //     }" src="${href}" alt="${text}" ${title ? `title="${title}"` : ''} />`
  //   renderer.current.list = (body: string, ordered: boolean) => {
  //     const tag = ordered ? 'ol' : 'ul'
  //     return `<${tag} class="${handles.list} ${ordered ? handles.listOrdered : ''}">${body}</${tag}>`
  //   }
  //   renderer.current.listitem = (text: string) => `<li class="${handles.listItem}">${text}</li>`
  // }

  // const alignToken = safelyGetToken(alignTokens, textAlignment, 'textAlignment')
  // const itemsToken = safelyGetToken(itemsTokens, textPosition, 'textPosition')
  // const justifyToken = safelyGetToken(
  //   justifyTokens,
  //   textPosition,
  //   'textPosition'
  // )

  // const html = useMemo(() => {
  //   marked.setOptions({
  //     gfm: true,
  //     breaks: true,
  //     sanitize: false, //Use insane lib for sanitizing
  //     smartLists: true,
  //     renderer: renderer.current,
  //   })

  //   return insane(
  //     //TODO: While markdown component isn't released, it needs to be done this way.
  //     marked(formatIOMessage({ id: text, intl })),
  //     sanitizerConfig
  //   )
  // }, [text, intl, sanitizerConfig, marked, insane, formatIOMessage])

  // return (
  //   <div
  //     id={htmlId}
  //     className={`${handles.container} flex ${alignToken} ${itemsToken} ${justifyToken} ${sanitizeFont(font)} ${sanitizeColor(textColor)}`}
  //   >
  //     <div dangerouslySetInnerHTML={{ __html: html }} />
  //   </div>
  // )
}

RichText.defaultProps = {
  font: 't-body',
  text: '',
  textPosition: defaultValues.textPosition,
  textAlignment: defaultValues.textAlignment,
  textColor: 'c-on-base',
}

const MemoizedRichText: VTEXIOComponent = memo(RichText)

MemoizedRichText.schema = {
  title: 'admin/editor.rich-text.title',
  description: 'admin/editor.rich-text.description',
  type: 'object',
  properties: {
    textPosition: {
      title: 'admin/editor.rich-text.textPosition.title',
      description: 'admin/editor.rich-text.textPosition.description',
      type: 'string',
      enum: getEnumValues(textPositionTypes),
      enumNames: getEnumNames(textPositionTypes),
      default: defaultValues.textPosition,
      isLayout: true,
    },
    textAlignment: {
      title: 'admin/editor.rich-text.textAlignment.title',
      description: 'admin/editor.rich-text.textAlignment.description',
      type: 'string',
      default: defaultValues.textAlignment,
      enum: getEnumValues(textAlignmentTypes),
      enumNames: getEnumNames(textAlignmentTypes),
      isLayout: true,
    },
    font: {
      title: 'admin/editor.rich-text.font.title',
      description: 'admin/editor.rich-text.font.description',
      type: 'string',
      default: 't-body',
      isLayout: true,
    },
    textColor: {
      title: 'admin/editor.rich-text.textColor.title',
      description: 'admin/editor.rich-text.textColor.description',
      type: 'string',
      default: 'c-on-base',
      isLayout: true,
    },
    blockClass: {
      title: 'admin/editor.rich-text.blockClass.title',
      description: 'admin/editor.rich-text.blockClass.description',
      type: 'string',
      default: null,
      isLayout: true,
    },
  },
}

export default injectIntl(MemoizedRichText) as any

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/RichText/package.json from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.rich-text",
  "scripts": {
    "lint": "eslint . --ext .ts --ext .tsx",
    "lint:fix": "eslint --fix . --ext .ts --ext .tsx",
    "pretest": "yarn",
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "escape-html": "^1.0.3",
    "insane": "^2.6.2",
    "marked": "^0.6.1",
    "ramda": "^0.26.1",
    "react-intl": "^2.9.0"
  },
  "devDependencies": {
    "@babel/core": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "@types/escape-html": "^0.0.20",
    "@types/jest": "^24.0.9",
    "@types/marked": "^0.6.4",
    "@types/node": "^11.10.0",
    "@types/ramda": "^0.26.6",
    "@types/react": "^16.8.6",
    "@vtex/test-tools": "^0.2.0",
    "eslint": "^5.16.0",
    "eslint-config-vtex-react": "^4.0.0",
    "prettier": "^1.16.4",
    "react-dom": "^16.8.4",
    "typescript": "3.5.2"
  },
  "version": "0.8.2"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Shelf/Shelf.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import PropTypes from 'prop-types'
import React, { useMemo } from 'react'
import { graphql } from 'react-apollo'
import { Loading } from '../../../../vtex.render-runtime'
import useDevice from '../DeviceDetector/useDevice'
import useCssHandles from '../CssHandles/useCssHandles'
import ProductListContext from '../ProductListContext/ProductListContext'

import OrdenationTypes, {
  getOrdenationNames,
  getOrdenationValues,
} from './utils/OrdenationTypes'
import ProductList from './components/ProductList'
import {
  productListSchemaPropTypes,
  shelfContentPropTypes,
} from './utils/propTypes'
import { normalizeBuyable } from './utils/normalize'
import { loader } from 'graphql.macro'

const productsQuery = loader('./queries/productsQuery.gql')

const CSS_HANDLES = ['container']

const { ProductListProvider } = ProductListContext

/**
 * Shelf Component. Queries a list of products and shows them.
 */
const Shelf = props => {
  const {
    data,
    paginationDotsVisibility = 'visible',
    productList = ProductList.defaultProps,
  } = props
  const handles = useCssHandles(CSS_HANDLES)
  const { isMobile } = useDevice()
  const { loading, error, products } = data || {}

  const filteredProducts = useMemo(() => {
    return products && products.map(normalizeBuyable).filter(Boolean)
  }, [products])

  const productListProps = {
    ...productList,
    isMobile,
    loading: loading,
    paginationDotsVisibility,
    products: filteredProducts,
  }

  if (loading) {
    return <Loading />
  }

  if (error) {
    return null
  }

  return (
    <div className={`${handles.container} pv4 pb9`}>
      <ProductListProvider>
        <ProductList {...productListProps} />
      </ProductListProvider>
    </div>
  )
}

Shelf.propTypes = {
  /** Graphql data response. */
  data: PropTypes.shape({
    products: shelfContentPropTypes.products,
  }),
  /** Category Id. */
  category: PropTypes.string,
  /** Collection Id. */
  collection: PropTypes.string,
  /** Ordenation Type. */
  orderBy: PropTypes.oneOf(getOrdenationValues()),
  /** Hide unavailable items */
  hideUnavailableItems: PropTypes.bool,
  /** Should display navigation dots below the Shelf */
  paginationDotsVisibility: PropTypes.oneOf([
    'visible',
    'hidden',
    'mobileOnly',
    'desktopOnly',
  ]),
  /** ProductList schema configuration */
  productList: PropTypes.shape(productListSchemaPropTypes),
}

const parseFilters = ({ id, value }) => `specificationFilter_${id}:${value}`

const toBoolean = x => (typeof x === 'boolean' ? x : x === 'true')

const options = {
  options: ({
    category,
    collection,
    hideUnavailableItems,
    orderBy = OrdenationTypes.ORDER_BY_TOP_SALE_DESC.value,
    specificationFilters = [],
    maxItems = ProductList.defaultProps.maxItems,
    skusFilter,
  }) => ({
    variables: {
      ...(category && { category: category.toString() }),
      ...(collection && { collection: collection.toString() }),
      specificationFilters: specificationFilters.map(parseFilters),
      orderBy,
      from: 0,
      to: maxItems - 1,
      hideUnavailableItems: toBoolean(hideUnavailableItems),
      skusFilter,
    },
  }),
}

const EnhancedShelf = graphql(productsQuery, options)(Shelf)

EnhancedShelf.schema = {
  title: 'admin/editor.shelf.title',
}

export default EnhancedShelf

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Shelf/TabbedShelf.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import TabbedShelf from './components/TabbedShelf/index'

export default TabbedShelf
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Shelf/RelatedProducts.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { useMemo } from 'react'
import PropTypes from 'prop-types'
import { path, last } from 'ramda'
import { Query } from 'react-apollo'
import useDevice from '../DeviceDetector/useDevice'
import ProductListContext from '../ProductListContext/ProductListContext'
import useProduct from '../ProductContext/useProduct'
import useCssHandles from '../CssHandles/useCssHandles'
import { loader } from 'graphql.macro'

import ProductList from './components/ProductList'
import { productListSchemaPropTypes } from './utils/propTypes'

const productRecommendations = loader('./queries/productRecommendations.gql')
const CSS_HANDLES = ['relatedProducts']

const { ProductListProvider } = ProductListContext

// Previous values were in a wrong format with the message string in the enum value.
const fixRecommendation = recommendation => {
  if (recommendation.includes('editor.relatedProducts.')) {
    return last(recommendation.split('.'))
  }
  return recommendation
}

/**
 * Related Products Component. Queries and shows the related products
 */
const RelatedProducts = ({
  productQuery,
  productList,
  recommendation: cmsRecommendation,
}) => {
  const handles = useCssHandles(CSS_HANDLES)
  const { isMobile } = useDevice()

  const productContext = useProduct()

  const productId =
    path(['product', 'productId'], productQuery) ||
    path(['product', 'productId'], productContext)

  const recommendation = productId ? fixRecommendation(cmsRecommendation) : null
  const variables = useMemo(() => {
    if (!productId) {
      return null
    }

    return {
      identifier: { field: 'id', value: productId },
      type: recommendation,
    }
  }, [productId, recommendation])

  if (!productId) {
    return null
  }

  return (
    <Query
      query={productRecommendations}
      variables={variables}
      partialRefetch
      ssr={false}
    >
      {({ data, loading }) => {
        if (!data) {
          return null
        }
        const { productRecommendations } = data
        const productListProps = {
          products: productRecommendations || [],
          loading,
          isMobile,
          ...productList,
        }
        return (
          <div className={handles.relatedProducts}>
            <ProductListProvider>
              <ProductList {...productListProps} />
            </ProductListProvider>
          </div>
        )
      }}
    </Query>
  )
}

RelatedProducts.propTypes = {
  /** Main product to have related products queried */
  slug: PropTypes.string,
  /** Graphql productQuery response. */
  productQuery: PropTypes.shape({
    /** Product to have related products queried */
    product: PropTypes.shape({
      productId: PropTypes.string,
    }),
    loading: PropTypes.bool,
  }),
  /** ProductList schema configuration */
  productList: PropTypes.shape(productListSchemaPropTypes),
}

RelatedProducts.defaultProps = {
  recommendation: 'similars',
  productList: {
    ...ProductList.defaultProps,
    titleText: 'Related Products',
  },
}

RelatedProducts.schema = {
  title: 'admin/editor.relatedProducts.title',
  description: 'admin/editor.relatedProducts.description',
  type: 'object',
  properties: {
    recommendation: {
      title: 'admin/editor.relatedProducts.recommendation',
      description: 'admin/editor.relatedProducts.recommendation.description',
      type: 'string',
      default: RelatedProducts.defaultProps.recommendation,
      enum: [
        'similars',
        'view',
        'buy',
        'accessories',
        'viewAndBought',
        'suggestions',
      ],
      enumNames: [
        'admin/editor.relatedProducts.similars',
        'admin/editor.relatedProducts.view',
        'admin/editor.relatedProducts.buy',
        'admin/editor.relatedProducts.accessories',
        'admin/editor.relatedProducts.viewAndBought',
        'admin/editor.relatedProducts.suggestions',
      ],
    },
    productList: ProductList.schema,
  },
}

export default RelatedProducts

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Shelf/ProductList.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductList from './components/ProductList'

export default ProductList
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/InfoCard.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import InfoCard from './components/InfoCard/index'

export default InfoCard

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/UserAddress.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import UserAddress from './components/UserAddress/index'

export default UserAddress

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/NotificationBar.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import NotificationBar from './components/Notification/notificationBar'

export default NotificationBar

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/BuyButton.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import BuyButton from './components/BuyButton/Wrapper'

export default BuyButton

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/CollectionBadges.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import CollectionBadges from './components/CollectionBadges/index'

export default CollectionBadges

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/CategoriesHighlights.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import CategoriesHighlights from './components/CategoriesHighlights'

export default CategoriesHighlights

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/NotificationInline.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import NotificationInline from './components/Notification/notificationInline'

export default NotificationInline

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductImages.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductImages from './components/ProductImages/Wrapper'

export default ProductImages

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductName.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductName from './components/ProductName/Wrapper'

export default ProductName

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/AvailabilitySubscriber.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
export { default } from './components/AvailabilitySubscriber/Wrapper'

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/DiscountBadge.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import DiscountBadge from './components/DiscountBadge/index'

export default DiscountBadge

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/SearchBar.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import SearchBar from './components/SearchBar/index'

export default SearchBar

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductSeparator.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'

export default () => <hr className="o-30" size="1" />

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/GradientCollapse.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import GradientCollapse from './components/GradientCollapse/index'

export default GradientCollapse

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/Image.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Image from '../StoreImage/Image'

export default Image

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/SKUSelector.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import SKUSelector from './components/SKUSelector/Wrapper'

export default SKUSelector

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/AutocompleteResults.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import AutocompleteResults from './components/AutocompleteResults/index'

export default AutocompleteResults

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductDescription.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductDescription from './components/ProductDescription/Wrapper'

export default ProductDescription

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductHighlights.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductHighlights from './components/ProductHighlights/Wrapper'

export default ProductHighlights

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/Slider.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Slider from './components/Slider/index'

export default Slider

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/Animation.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Animation from './components/Animation/index'

export default Animation

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/Logo.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Logo from './components/Logo/index'

export default Logo

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/Container.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Container from './components/Container/index'

export default Container

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductBrand.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductBrand from './components/ProductBrand'

export default ProductBrand

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/Newsletter.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Newsletter from './components/Newsletter/index'

export default Newsletter

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductPrice.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductPrice from './components/ProductPrice/Wrapper'

export default ProductPrice

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/Share.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Share from './components/Share/Wrapper'

export default Share

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreComponents/ProductSpecifications.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductSpecifications from './components/ProductSpecifications/Wrapper'

export default ProductSpecifications

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ReactPortal/index.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import Overlay from './Overlay'

export { Overlay }

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ReactPortal/Overlay.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, {
  useRef,
  useEffect,
  useState,
  FunctionComponent,
  useCallback,
} from 'react'
import Portal, { Props as PortalProps } from './components/Portal'

interface Props extends PortalProps {
  fullWindow: boolean
  alignment: HorizontalAlignment
}

interface Position {
  x: number
  y: number
}

enum HorizontalAlignment {
  right = 'right',
  left = 'left',
  center = 'center',
}

const getXPositionByHorizontalAlignment = (
  alignment: HorizontalAlignment,
  bounds: ClientRect | DOMRect
) => {
  switch (alignment) {
    case 'left':
      return bounds.left
    case 'right':
      return bounds.right
    case 'center':
      return (bounds.right + bounds.left) / 2
    default:
      return bounds.left
  }
}

const getJustifyTypeByHorizontalAlignment = (
  alignment: HorizontalAlignment
) => {
  switch (alignment) {
    case 'left':
      return 'justify-start'
    case 'right':
      return 'justify-end'
    case 'center':
      return 'justify-center'
    default:
      return 'justify-start'
  }
}

const Overlay: FunctionComponent<Props> = ({
  children,
  fullWindow,
  target,
  alignment = HorizontalAlignment.left,
}) => {
  const container = useRef<HTMLDivElement>(null)
  const [position, setPosition] = useState<Position>()

  const updatePosition = useCallback(() => {
    if (!fullWindow && container.current) {
      const bounds = container.current.getBoundingClientRect()

      setPosition({
        x: getXPositionByHorizontalAlignment(alignment, bounds),
        y: bounds.top,
      })
    }
  }, [alignment, fullWindow])

  useEffect(() => {
    updatePosition()

    if (window) {
      window.addEventListener('scroll', updatePosition)
      window.addEventListener('load', updatePosition)
      window.addEventListener('resize', updatePosition)
      window.addEventListener('visibilitychange', updatePosition)
    }

    return () => {
      if (window) {
        window.removeEventListener('scroll', updatePosition)
        window.removeEventListener('load', updatePosition)
        window.removeEventListener('resize', updatePosition)
        window.removeEventListener('visibilitychange', updatePosition)
      }
    }
  }, [alignment, fullWindow, updatePosition, children])

  if (!fullWindow) {
    return (
      // Div used for anchoring the position of the overlay, for popovers etc
      <div
        ref={container}
        style={{
          width: 'auto',
          height: 1,
          marginTop: -1,
        }}
      >
        {position && (
          <Portal target={target}>
            <div
              className={`flex ${getJustifyTypeByHorizontalAlignment(
                alignment
              )}`}
              style={{
                position: 'absolute',
                left: position.x,
                top: position.y,
              }}
            >
              <div className="absolute">{children}</div>
            </div>
          </Portal>
        )}
      </div>
    )
  }

  return (
    <Portal target={target} cover>
      {children}
    </Portal>
  )
}

export default Overlay as any

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ProductContext/ProductContext.ts from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createContext } from 'react'

export default createContext({})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ProductContext/ProductContextProvider.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useEffect, Dispatch } from 'react'
import ProductContext from './ProductContext'
import { ProductDispatchContext } from './ProductDispatchContext'
import { useProductReducer, getSelectedItem } from './reducer'
import { getSelectedSKUFromQueryString } from './modules/skuQueryString'

function useProductInState(product: MaybeProduct, dispatch: Dispatch<Actions>) {
  useEffect(() => {
    if (product) {
      dispatch({
        type: 'SET_PRODUCT',
        args: { product },
      })
    }
  }, [product, dispatch])
}

function useSelectedItemFromId(
  dispatch: Dispatch<Actions>,
  product: MaybeProduct,
  skuId?: string
) {
  useEffect(() => {
    const items = (product && product.items) || []
    dispatch({
      type: 'SET_SELECTED_ITEM',
      args: { item: getSelectedItem(skuId, items as any) },
    })
  }, [dispatch, skuId, product])
}

const ProductContextProvider: FC<ProductAndQuery> = ({
  query,
  product,
  children,
}) => {
  const [state, dispatch] = useProductReducer({ query, product })

  // These hooks are used to keep the state in sync with API data, specially when switching between products without exiting the product page
  useProductInState(product, dispatch)
  const selectedSkuQueryString = getSelectedSKUFromQueryString(query)
  useSelectedItemFromId(dispatch, product, selectedSkuQueryString)

  return (
    <ProductContext.Provider value={state}>
      <ProductDispatchContext.Provider value={dispatch}>
        {children}
      </ProductDispatchContext.Provider>
    </ProductContext.Provider>
  )
}

export default ProductContextProvider

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ProductContext/useProduct.ts from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useContext } from 'react'
import ProductContext from './ProductContext'

function useProduct() {
  return useContext(ProductContext)
}

export default useProduct

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ProductContext/ProductDispatchContext.ts from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createContext, useContext, Dispatch } from 'react'

export const ProductDispatchContext = createContext<Dispatch<Actions> | null>(
  null
)
function useProductDispatch() {
  return useContext(ProductDispatchContext)
}
export default { ProductDispatchContext, useProductDispatch }

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Login/styles.css from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```css
.container {}

.contentInitialScreen {}

.contentFormVisible {}

.profile {}

.label {}

.loading {}

.optionsSticky {}

.optionsList {}

.optionsListItem {}

.optionsListItemContainer {}

.accessCodeOptionBtn {}

.emailPasswordOptionBtn {}

.facebookOptionBtn {}

.googleOptionBtn {}

.customOAuthOptionBtn {}

.oauthProvider {}

.oauthAutoRedirect {}

.oauthAutoRedirectLoading {}

.inputContainer {}

.inputContainerAccessCode {}

.inputContainerPassword {}

.inputContainerEmail {}

.emailVerification {}

.emailForm {}

.emailAndPasswordForm {}

.forgotPasswordForm {}

.formLinkContainer {}

.arrowUp {}

.buttonLink {}

.formError {}

.content {}

.button {}

.sendButton {}

.buttonSocial {}

.buttonDanger {}

.backButton {}

.accountOptions {}

.codeConfirmation {}

.formTitle {
  white-space: pre-line;
}

.box {
  top: 100%;
  visibility: visible;
  min-width: 19.375rem;
}

.contentContainer {
  min-width: 100%;
}

.formFooter {
  min-height: 2rem;
}

.contentForm {
  min-width: 18.125rem;
}

.contentAlwaysWithOptions {
  min-height: 18.75rem;
  max-width: 43.75rem;
}

@media only screen and (max-width: 600px) {
  .contentAlwaysWithOptions {
    max-width: 25rem;
  }
}

.options {
  min-width: 20rem;
}

.sendButton:only-child {
  margin: 0;
  width: 100%;
}

.sendButton:only-child :global(.vtex-button) {
  width: 100%;
}

.tooltipContainer {
  width: max-content;
}

.tooltipContainerTop {
  bottom: 110%;
  left: 50%;
  transform: translateX(-50%);
}

.tooltipContainerLeft {
  top: 50%;
  transform: translateY(-50%);
  right: 102%;
}

.tooltipContainerLeft::after {
  content: '';
  position: absolute;
  top: 45%;
  left: 100%;
  border-width: 0.625rem;
  border-style: solid;
  border-color: transparent transparent transparent #3b3b3b;
}

.tooltipContainerTop::after {
  content: '';
  position: absolute;
  left: 45%;
  top: 100%;
  border-width: 0.625rem;
  border-style: solid;
  border-color: #3b3b3b transparent transparent transparent;
}

.button :global(.vtex-button) {
  border: 1px solid rgb(233, 233, 233);
  width: 100%;
  min-height: 2.5rem;
}

.button :global(.vtex-button) .oauthLabel {
  margin: 0 1.25rem 0 1.25rem;
}

.buttonDanger > :global(.vtex-button){
  background-color: #ffe6e6;
  color: #FF4C4C;
}

.buttonDanger > :global(.vtex-button) :global(.vtex__icon-spinner){
  color: #FF4C4C;
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Login/README.md from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```markdown
# Login
Login is a canonical component that any VTEX app can import.

To import it into your code:
```js
import Login from 'vtex.store-components/Login'
```

## Usage
You can use it in your code like a React component with the jsx tag: `<Login />`.
```html
<Login />
```

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Login/LoginContent.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Component, Suspense } from 'react'
import LoginContent from './components/LoginContent'
import { NoSSR } from '../../../../vtex.render-runtime'
import Loading from './components/Loading'

const LoginContentWrapper = props => {
  return (
    <NoSSR>
      <Suspense fallback={<Loading />}>
        <LoginContent {...props} />
      </Suspense>
    </NoSSR>
  )
}

LoginContentWrapper.getSchema = () => ({
  title: 'admin/editor.loginPage.title',
  ...LoginSchema,
  properties: {
    ...LoginSchema.properties,
    isInitialScreenOptionOnly: {
      title: 'admin/editor.login.isInitialScreenOptionOnly.title',
      type: 'boolean',
      default: true,
      isLayout: true,
    },
    defaultOption: {
      title: 'admin/editor.login.defaultOption.title',
      type: 'number',
      default: 0,
      isLayout: true,
      enum: [0, 1],
      enumNames: [
        'admin/editor.login.defaultOption.token',
        'admin/editor.login.defaultOption.emailAndPassword',
      ],
      widget: {
        'ui:widget': 'radio',
        'ui:options': {
          inline: true,
        },
      },
    },
  },
})

export default LoginContentWrapper
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Login/Login.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Component } from 'react'

import { withSession } from '../../../../vtex.render-runtime'
import { injectIntl } from 'react-intl'

import { LoginSchema } from './schema'
import { setCookie } from './utils/set-cookie'
import { LoginContainerProptypes } from './propTypes'
import LoginComponent from './components/LoginComponent'
import { getProfile } from './utils/profile'

const DEFAULT_CLASSES = 'gray'

/** Canonical login that calls a mutation to retrieve the authentication token */

export default class Login extends Component {
  static propTypes = LoginContainerProptypes

  static defaultProps = {
    labelClasses: DEFAULT_CLASSES,
  }

  state = {
    isBoxOpen: false,
    renderIconAsLink: false,
    sessionProfile: null,
  }

  getSessionPromiseFromWindow = () =>
    !window.__RENDER_8_SESSION__ || !window.__RENDER_8_SESSION__.sessionPromise
      ? Promise.resolve(null)
      : window.__RENDER_8_SESSION__.sessionPromise

  componentDidMount() {
    window.addEventListener('resize', this.handleResize)
    this.handleResize()

    if (window.location.href.indexOf('accountAuthCookieName') > 0) {
      setCookie(window.location.href)
    }

    this.getSessionPromiseFromWindow().then(data => {
      const sessionResponse = (data || {}).response
      const sessionProfile = getProfile(sessionResponse)
      if (sessionProfile) this.setState({ sessionProfile })
    })
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize)
  }

  handleResize = () => {
    const WIDTH_THRESHOLD = 640

    if (window.innerWidth < WIDTH_THRESHOLD && !this.state.renderIconAsLink) {
      this.setState({
        renderIconAsLink: true,
      })
    } else if (
      window.innerWidth >= WIDTH_THRESHOLD &&
      this.state.renderIconAsLink
    ) {
      this.setState({
        renderIconAsLink: false,
      })
    }
  }

  handleProfileIconClick = () => {
    this.setState({ isBoxOpen: !this.state.isBoxOpen })
  }

  handleOutSideBoxClick = () => {
    this.setState({ isBoxOpen: false })
  }

  render() {
    return (
      <LoginWithSession
        isBoxOpen={this.state.isBoxOpen}
        renderIconAsLink={this.state.renderIconAsLink}
        sessionProfile={this.state.sessionProfile}
        {...this.props}
        onOutSideBoxClick={this.handleOutSideBoxClick}
        onProfileIconClick={this.handleProfileIconClick}
      />
    )
  }
}

Login.getSchema = () => ({
  title: 'admin/editor.login.title',
  ...LoginSchema,
  properties: {
    ...LoginSchema.properties,
    mirrorTooltipToRight: {
      title: 'admin/editor.login.mirrorTooltipToRightTitle',
      type: 'boolean',
      default: 'false',
    },
  },
})

const LoginWithSession = withSession({ renderWhileLoading: true })(injectIntl(LoginComponent))

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Login/schema.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
export const LoginSchema = {
  type: 'object',
  properties: {
    optionsTitle: {
      title: 'admin/editor.login.optionsTitle',
      type: 'string',
      widget: {
        'ui:widget': 'textarea',
      },
    },
    emailAndPasswordTitle: {
      title: 'admin/editor.login.emailAndPasswordTitle',
      type: 'string',
      widget: {
        'ui:widget': 'textarea',
      },
    },
    accessCodeTitle: {
      title: 'admin/editor.login.accessCodeTitle',
      type: 'string',
      widget: {
        'ui:widget': 'textarea',
      },
    },
    emailPlaceholder: {
      title: 'admin/editor.login.emailPlaceholder',
      type: 'string',
    },
    passwordPlaceholder: {
      title: 'admin/editor.login.passwordPlaceholder',
      type: 'string',
    },
    showPasswordVerificationIntoTooltip: {
      title: 'admin/editor.login.showPasswordVerificationIntoTooltip.title',
      type: 'boolean',
      isLayout: true,
    },
    accessCodePlaceholder: {
      title: 'admin/editor.login.accessCodePlaceholder',
      type: 'string',
    },
    showIconProfile: {
      title: 'admin/editor.login.showIconProfile',
      type: 'boolean',
    },
    iconLabel: {
      title: 'admin/editor.login.iconLabel',
      type: 'string',
    },
    providerPasswordButtonLabel: {
      title: 'admin/editor.login.providerPasswordButtonLabel',
      type: 'string',
    },
    hasIdentifierExtension: {
      title: 'admin/editor.login.hasIdentifierExtension',
      type: 'boolean',
    },
  },
  dependencies: {
    hasIdentifierExtension: {
      oneOf: [
        {
          properties: {
            hasIdentifierExtension: {
              enum: [true],
            },
            identifierPlaceholder: {
              title: 'admin/editor.login.identifierPlaceholder',
              type: 'string',
            },
            invalidIdentifierError: {
              title: 'admin/editor.login.invalidIdentifierError',
              type: 'string',
            },
          },
        },
      ],
    },
  },
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/Login/propTypes.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import PropTypes from 'prop-types'

export const LoginContainerProptypes = {
  /** Title of login options */
  optionsTitle: PropTypes.string,
  /** Title of classic login */
  emailAndPasswordTitle: PropTypes.string,
  /** Title of access code login */
  accessCodeTitle: PropTypes.string,
  /** Placeholder to email input */
  emailPlaceholder: PropTypes.string,
  /** Placeholder to password input */
  passwordPlaceholder: PropTypes.string,
  /** Placeholder to access code input */
  accessCodePlaceholder: PropTypes.string,
  /** Set the type of password verification ui */
  showPasswordVerificationIntoTooltip: PropTypes.bool,
  /** Icon's size */
  iconSize: PropTypes.number,
  /** Icon's label */
  iconLabel: PropTypes.string,
  /** Label's classnames */
  labelClasses: PropTypes.string,
  /** Determines if the icon profile will be hidden */
  showIconProfile: PropTypes.bool,
  /** Password login button text */
  providerPasswordButtonLabel: PropTypes.string,
  /** Whether the identifier extension values are enabled in the site editor */
  hasIdentifierExtension: PropTypes.bool,
  /** Placeholder for the identifier extension */
  identifierPlaceholder: PropTypes.string,
  /** Error message for the user identifier */
  invalidIdentifierError: PropTypes.string,
  /** Determines if the tooltip opens towards the right side */
  mirrorTooltipToRight: PropTypes.bool,
}

export const LoginPropTypes = {
  /** User profile information */
  profile: PropTypes.shape({}),
  /** Is box with the login options should be opened or not */
  isBoxOpen: PropTypes.bool.isRequired,
  /** Should the Icon be rendered as link or not */
  renderIconAsLink: PropTypes.bool.isRequired,
  /** Function called when the user click outside of the box*/
  onOutSideBoxClick: PropTypes.func.isRequired,
  /** Function called when the user clicks on the icon*/
  onProfileIconClick: PropTypes.func.isRequired,
  /** Runtime context. */
  runtime: PropTypes.shape({
    history: PropTypes.shape({
      location: PropTypes.shape({
        pathname: PropTypes.string,
        search: PropTypes.string,
      }),
    }),
  }),
  /** Props received through the LoginContainer */
  ...LoginContainerProptypes,
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/header/ForceCenter.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import useCssHandles from '../CssHandles/useCssHandles'

const CSS_HANDLES = ['forceCenter', 'forceCenterInnerContainer']

const ForceCenter = ({ children }) => {
  const handles = useCssHandles(CSS_HANDLES)

  return (
    <div
      className={`${handles.forceCenter} absolute left-0 right-0 flex justify-center z-1`}
      style={{ pointerEvents: 'none' }}
    >
      <div
        className={handles.forceCenterInnerContainer}
        style={{ pointerEvents: 'all' }}
      >
        {children}
      </div>
    </div>
  )
}

export default ForceCenter

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/header/Layout.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Layout from './components/Layout'

export default Layout

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/header/Spacer.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Spacer from './components/Spacer'

export default Spacer

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/header/index.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import Row from './components/Row'
import Spacer from './components/Spacer'
import Logo from '../StoreComponents/Logo'
import Menu from '../Menu/Menu'
import MenuItem from '../Menu/MenuItem'
import Submenu from '../Menu/Submenu'
import FlexCol from  '../FlexLayout/Col'
import FlexRow from  '../FlexLayout/FlexLayout'
import InfoCard from '../StoreComponents/InfoCard'
import Drawer from '../Drawer/Drawer'
import SearchBar from '../StoreComponents/SearchBar'
import LocaleSwitcher from '../LocaleSwitcher/LocaleSwitcher'
import Login from '../Login/Login'
import Minicart from '../Minicart/index'
import NotificationBar from '../StoreComponents/NotificationBar'
// import MinicartBase from '../Minicart/BaseContent'
// import ProductList from '../Minicart/ProductList'
// import Sticky from '../Sticky'

import useDevice from '../DeviceDetector/useDevice'

// import CustomHeader from './components/CustomHeader'

// "header-layout.desktop": {
//   "children": [
//     "header-row#1-desktop",
//     "header-row#2-desktop",
//     "header-row#3-desktop",
//     "header-row#4-desktop"
//   ]
// },

// "header-row#1-desktop": {
//   "children": ["telemarketing"],
//   "props": {
//     "fullWidth": true
//   }
// },

// "header-row#2-desktop": {
//   "children": ["notification.bar#home"],
//   "props": {
//     "fullWidth": "true"
//   }
// },
// "notification.bar#home": {
//   "props": {
//     "content": "SELECTED ITEMS ON SALE! CHECK IT OUT!"
//   }
// },
// "header-row#3-desktop": {
//   "children": [
//     "vtex.menu@2.x:menu#websites",
//     "header-spacer",
//     "vtex.menu@2.x:menu#institutional"
//   ],
//   "props": {
//     "blockClass": "menu-link",
//     "inverted": "true"
//   }
// },
// "header-row#4-desktop": {
//   "children": [
//     "logo#desktop",
//     "vtex.menu@2.x:menu#category-menu",
//     "header-spacer",
//     "header-spacer",
//     "search-bar",
//     "locale-switcher",
//     "login",
//     "minicart.v2"
//   ],
//   "props": {
//     "sticky": true,
//     "blockClass": "main-header"
//   }
// },
// "logo#desktop": {
//   "props": {
//     "title": "Logo",
//     "href": "/",
//     "url": "https://storecomponents.vteximg.com.br/arquivos/store-theme-logo.png",
//     "width": "180"
//   }
// },
// "header-layout.mobile": {
//   "children": ["header-row#1-mobile"]
// },
// "header-row#1-mobile": {
//   "children": [
//     "drawer",
//     "logo#mobile",
//     "header-spacer",
//     "login",
//     "minicart.v2"
//   ],
//   "props": {
//     "sticky": true,
//     "blockClass": "main-header-mobile"
//   }
// },
// "drawer": {
//   "children": ["menu#drawer"]
// },

// "menu#drawer": {
//   "children": [
//     "menu-item#category-apparel",
//     "menu-item#category-home",
//     "menu-item#more"
//   ],
//   "props": {
//     "orientation": "vertical"
//   }
// },

// "logo#mobile": {
//   "props": {
//     "title": "Logo",
//     "href": "/",
//     "url": "https://storecomponents.vteximg.com.br/arquivos/store-theme-logo-mobile.png",
//     "width": "70"
//   }
// }
// }

// "minicart-base-content": {
//   "blocks": ["minicart-empty-state"],
//   "children": ["minicart-product-list", "sticky-layout#minicart-footer"]
// },

const CategoryMenu = () => (
  <MenuItem id="menu-item-category-apparel" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/apparel---accessories/", noFollow: false, tagTitle:"Apparel & Accessories", text:"Apparel & Accessories"}}>
    <Submenu width="auto">
      <Menu orientation="vertical">
        <MenuItem id="menu-item-category-apparel-clothing" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/apparel---accessories/clothing/", noFollow: false, tagTitle:"Clothing", text:"Clothing"}}/>
        <MenuItem id="menu-item-category-apparel-accessories" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/apparel---accessories/accessories/", noFollow: false, tagTitle:"Accessories", text:"Accessories"}}/>
        <MenuItem id="menu-item-category-apparel-eyeglasses" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/apparel---accessories/eyeglasses/", noFollow: false, tagTitle:"Eyeglasses", text:"Eyeglasses"}}/>
      </Menu>
    </Submenu>
  </MenuItem>
)

const MenuMore = () => (
  <MenuItem id="menu-item-custom-sale" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "#", noFollow: false, tagTitle:"More", text:"More"}}>
    <Submenu width="100%">
      <FlexRow>
        <FlexCol>
          <Menu orientation="vertical">
            <MenuItem id="menu-item-about-us" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/about-us", noFollow: false, tagTitle:"About us", text:"About us"}} />
          </Menu>
        </FlexCol>
        <FlexCol>
          <InfoCard id="info-card-home" isFullModeStyle={false} textPosition="left" imageUrl="https://storecomponents.vteximg.com.br/arquivos/banner-infocard2.png" headline="Clearance Sale" callToActionText="DISCOVER" callToActionUrl="/sale/d" blockClass="info-card-home" textAlignment="center" />
        </FlexCol>
      </FlexRow>
    </Submenu>
  </MenuItem>
)

const DesktopHeader = () => {
  return (
    <div>
      <Row fullWidth>
        <NotificationBar content="SELECTED ITEMS ON SALE! CHECK IT OUT!" />
      </Row>
      <Row blockClass="menu-link" inverted>
        <Menu>
          <MenuItem id="menu-item-shop" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "#", noFollow: false, tagTitle:"Shop", text:"Shop"}} />
          <MenuItem id="menu-item-about-us" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/about-us", noFollow: false, tagTitle:"about-us", text:"About Us"}} />
        </Menu>
        <Spacer />
        <Menu>
          <MenuItem id="menu-item-vtex-website" type="custom" iconId={null} highlight={false} itemProps={{ type: "external", href: "http://vtex.com", noFollow: false, tagTitle:"visit vtex.com", text:"visit vtex.com"}} />
        </Menu>
      </Row>
      <Row blockClass="main-header" sticky>
        <Logo title="Logo" href="/" url="https://storecomponents.vteximg.com.br/arquivos/store-theme-logo.png" width="180" />
        <Menu>
          <CategoryMenu />
          <MenuItem id="menu-item-category-home" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/home---decor/", noFollow: false, tagTitle:"Home & Decor", text:"Home & Decor"}}/>
          <MenuMore />
        </Menu>
        <Spacer />
        <Spacer />
        <SearchBar />
        <LocaleSwitcher />
        <Login />
        <Minicart type="popup" showRemoveButton showDiscount showSku labelMiniCartEmpty="" labelButtonFinishShopping="Go to checkout" enableQuantitySelector maxQuantity={10} labelClasses="gray" productSummaryProps={{}}/>
      </Row>
    </div>
  )
}

const MobileHeader = () => {
  return (
    <Row blockClass="main-header-mobile" sticky>
      <Drawer>
        <CategoryMenu />
        <MenuItem id="menu-item-category-home" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/home---decor/", noFollow: false, tagTitle:"Home & Decor", text:"Home & Decor"}}/>
        <MenuMore />
      </Drawer>
      <Logo title="Logo" href="/" url="https://storecomponents.vteximg.com.br/arquivos/store-theme-logo-mobile.png" width="70" />
      <Spacer />
      <Login />
      <Minicart type="popup" showRemoveButton showDiscount showSku labelMiniCartEmpty="" labelButtonFinishShopping="Go to checkout" enableQuantitySelector maxQuantity={10} labelClasses="gray" productSummaryProps={{}}/>
    </Row>
  )
}

const Header = () => {
  const { isMobile } = useDevice()
  return isMobile ? <MobileHeader/> : <DesktopHeader />
}

// Header.schema = LegacyHeader.schema

export default Header

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/header/Row.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Row from './components/Row'

export default Row

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/header/Border.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Border from './components/Border'

export default Border

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/ProductSummaryContext/ProductSummaryContext.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useReducer } from 'react'
import { createContext, useContext } from 'react'

const ProductSummaryContext = createContext<State | undefined>(undefined)
const ProductDispatchContext = createContext<Dispatch | undefined>(undefined)

interface State {
  product: any
  isHovering: boolean
  isLoading: boolean
  selectedItem: any,
  selectedQuantity: number,
  productQuery?: string,
}

type Dispatch = (action: Action) => void

type SetProductAction = {
  type: 'SET_PRODUCT',
  args: {
    product: any
  }
}

type SetProductQueryAction = {
  type: 'SET_PRODUCT_QUERY',
  args: {
    query: string
  }
}

type SetHoverAction = {
  type: 'SET_HOVER'
  args: {
    isHovering: boolean
  }
}

type SetLoadingAction = {
  type: 'SET_LOADING'
  args: {
    isLoading: boolean
  }
}

type SetProductQuantity = {
  type: 'SET_QUANTITY'
  args: {
    quantity: number
  }
}

type Action = SetProductAction | SetHoverAction | SetLoadingAction | SetProductQuantity | SetProductQueryAction

export function reducer(state: State, action: Action) {
  switch (action.type) {
    case 'SET_PRODUCT': {
      const product = action.args.product
      return {
        ...state,
        product: product,
        //TODO: STOP USING PRODUCT.SKU https://app.clubhouse.io/vtex/story/18547/productsummarycontext-refactor
        selectedItem: product.sku
      }
    }
    case 'SET_HOVER': {
      return {
        ...state,
        isHovering: action.args.isHovering
      }
    }
    case 'SET_LOADING': {
      return {
        ...state,
        isLoading: action.args.isLoading
      }
    }
    case 'SET_QUANTITY': {
      return {
        ...state,
        selectedQuantity: action.args.quantity,
      }
    }
    case 'SET_PRODUCT_QUERY':
      return {
        ...state,
        query: action.args.query,
      }
    default:
      return state
  }
}

function ProductSummaryProvider({ product, children }) {
  const initialState = {
    product,
    isHovering: false,
    isLoading: false,
    selectedItem: null,
    selectedQuantity: 1,
  }

  const [state, dispatch] = useReducer(reducer, initialState)

  return (
    <ProductSummaryContext.Provider value={state}>
      <ProductDispatchContext.Provider value={dispatch}>
        {children}
      </ProductDispatchContext.Provider>
    </ProductSummaryContext.Provider>
  )
}

function useProductSummaryDispatch() {
  const context = useContext(ProductDispatchContext)

  if (context === undefined) {
    throw new Error('useProductSummaryDispatch must be used within a ProductSummaryDispatchProvider')
  }

  return context
}

function useProductSummary() {
  const context = useContext(ProductSummaryContext)

  if (context === undefined) {
    throw new Error('useProductSummary must be used within a ProductSummaryProvider')
  }

  return context
}

export default {
  ProductSummaryProvider,
  useProductSummary,
  useProductSummaryDispatch,
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of store-on-localhost/src/monobloco/components/new/StoreResources/Mutations.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { loader } from 'graphql.macro'

const addToCart = loader('./mutations/addToCart.gql')
const updateItems = loader('./mutations/updateItems.gql')
const updateOrderFormProfile = loader('./mutations/updateOrderFormProfile.gql')
const updateOrderFormShipping = loader('./mutations/updateOrderFormShipping.gql')
const updateOrderFormCheckin = loader('./mutations/updateOrderFormCheckin.gql')

export default {
  addToCart,
  updateItems,
  updateOrderFormProfile,
  updateOrderFormShipping,
  updateOrderFormCheckin,
}

```