[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/OrderFormProvider.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { loader } from 'graphql.macro'
import { useMutation, useQuery } from 'react-apollo'
import { canUseDOM } from 'exenv'

import OrderFormContext from './new/StoreResources/OrderFormContext'

const addToCartMutation = loader('./new/StoreResources/mutations/addToCart.gql')
const updateItemsMutation = loader('./new/StoreResources/mutations/updateItems.gql')
const updateOrderFormProfileMutation = loader('./new/StoreResources/mutations/updateOrderFormProfile.gql')
const updateOrderFormShippingMutation = loader('./new/StoreResources/mutations/updateOrderFormShipping.gql')
const updateOrderFormCheckinMutation = loader('./new/StoreResources/mutations/updateOrderFormCheckin.gql')
const orderForm = loader('./new/StoreResources/queries/orderForm.gql')

const { Provider } = OrderFormContext

let value = {}

const OrderFormProvider = ({ children }) => {
  const { data, error } = useQuery(orderForm, { ssr: false })
  const addItem = useMutation(addToCartMutation)
  const updateOrderForm = useMutation(updateItemsMutation)
  const updateOrderFormProfile = useMutation(updateOrderFormProfileMutation)
  const updateOrderFormShipping = useMutation(updateOrderFormShippingMutation)
  const updateOrderFormCheckin = useMutation(updateOrderFormCheckinMutation)

  if (error) {
    throw error
  }

  value = {
    message: data?.message,
    orderFormContext: {
      updateToastMessage: () => console.log('updateToastMessage'),
      updateAndRefetchOrderForm: () => console.log('updateAndRefetchOrderForm'),
      updateOrderForm,
      addItem,
      updateOrderFormProfile,
      updateOrderFormShipping,
      updateOrderFormCheckin,
    }
  }

  return <Provider value={value}>{children}</Provider>

}

export default OrderFormProvider

// class OrderFormProvider extends Component {
//   state = {
//     orderFormContext: {
//       message: { isSuccess: null, text: null },
//       loading: true,
//       orderForm: {},
//       refetch: () => {},
//       addItem: this.props.addItem,
//       updateToastMessage: this.handleMessageUpdate,
//       updateOrderForm: this.props.updateOrderForm,
//       updateAndRefetchOrderForm: this.handleUpdateAndRefetchOrderForm,
//       updateOrderFormProfile: this.props.updateOrderFormProfile,
//       updateOrderFormShipping: this.props.updateOrderFormShipping,
//       updateOrderFormCheckin: this.props.updateOrderFormCheckin,
//     },
//   }

//   static getDerivedStateFromProps(props, state) {
//     if (!props.data.loading && !props.data.error) {
//       const orderFormContext = props.data

//       orderFormContext.message = state.orderFormContext.message

//       return {
//         orderFormContext,
//       }
//     }

//     return state
//   }

//   handleUpdateAndRefetchOrderForm = vars => {
//     return this.props.updateOrderForm(vars).then(() => {
//       return this.props.data.refetch()
//     })
//   }

//   handleMessageUpdate = message => {
//     const context = this.state.orderFormContext
//     context.message = message

//     this.setState({ orderFormContext: context })
//   }

//   render() {
//     const state = this.state

//     state.orderFormContext.updateToastMessage = this.handleMessageUpdate
//     state.orderFormContext.updateAndRefetchOrderForm = this.handleUpdateAndRefetchOrderForm
//     state.orderFormContext.updateOrderForm = this.props.updateOrderForm
//     state.orderFormContext.addItem = this.props.addItem
//     state.orderFormContext.updateOrderFormProfile = this.props.updateOrderFormProfile
//     state.orderFormContext.updateOrderFormShipping = this.props.updateOrderFormShipping
//     state.orderFormContext.updateOrderFormCheckin = this.props.updateOrderFormCheckin

//     return <Provider value={this.state}>{this.props.children}</Provider>
//   }
// }

// const options = {
//   options: () => ({
//     ssr: false,
//   }),
// }

// export default compose(
//   graphql(orderForm, options),
//   graphql(addToCart, { name: 'addItem' }),
//   graphql(updateItems, { name: 'updateOrderForm' }),
//   graphql(updateOrderFormProfile, { name: 'updateOrderFormProfile' }),
//   graphql(updateOrderFormShipping, { name: 'updateOrderFormShipping' }),
//   graphql(updateOrderFormCheckin, { name: 'updateOrderFormCheckin' })
// )(OrderFormProvider)
```


[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/WrapperContainer.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'

const WrapperContainer = ({ children, className }) => (
  <div className={className}>
    <div className="flex flex-column min-vh-100 w-100">{children}</div>
  </div>
)

export default WrapperContainer

```


[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/NetworkStatusToast.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { path, pathOr } from 'ramda'
import { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import { injectIntl } from 'react-intl'
import ToastContext from '../components/new/Styleguide/ToastContext'
import { useRuntime } from '../../vtex.render-runtime'

function NetworkStatusToast({ intl }) {
  const runtime = useRuntime()
  const [offline, setOffline] = useState(false)
  // Useful to dismissable toast flow.
  const [showingOffline, setShowingOffline] = useState(false)
  const { showToast, hideToast, toastState } = useContext(ToastContext)

  const toastConfig = useMemo(
    () => ({
      message: intl.formatMessage({
        id: 'store/store.network-status.offline',
      }),
      dismissable: pathOr(false, ['hints', 'mobile'], runtime),
      duration: Infinity,
    }),
    [intl, runtime]
  )

  const updateStatus = useCallback(() => {
    if (navigator) {
      setOffline(!pathOr(true, ['onLine'], navigator))
    }
  }, [])

  useEffect(() => {
    if (window) {
      window.addEventListener('online', updateStatus)
      window.addEventListener('offline', updateStatus)
    }
    updateStatus()
    return function cleanUp() {
      if (window) {
        window.removeEventListener('online', updateStatus)
        window.removeEventListener('offline', updateStatus)
      }
    }
  }, [updateStatus])

  useEffect(() => {
    if (offline && !toastState.currentToast) {
      if (!showingOffline) {
        showToast(toastConfig)
      }
      setShowingOffline(!showingOffline)
    } else if (
      !offline &&
      toastState.isToastVisible &&
      path(['currentToast', 'message'], toastState) === toastConfig.message
    ) {
      hideToast()
      setShowingOffline(false)
    }
  }, [offline, toastState, toastConfig, showingOffline, showToast, hideToast])

  return null
}

export default injectIntl(NetworkStatusToast)

```


[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/PageViewPixel.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable react-hooks/exhaustive-deps */
import { canUseDOM } from 'exenv'
import { useMemo } from 'react'

import { useRuntime } from '../../vtex.render-runtime'
import useDataPixel from '../hooks/useDataPixel'

interface UsePageViewArgs {
  title?: string
  cacheKey?: string
  skip?: boolean
}

export const usePageView = ({ title, cacheKey, skip }: UsePageViewArgs = {}) => {
  const { route, account } = useRuntime()
  const pixelCacheKey = cacheKey || route.routeId

  const eventData = useMemo(() => {
    if (!canUseDOM || skip) {
      return null
    }

    return {
      event: 'pageView',
      pageTitle: title || document.title,
      pageUrl: window.location.href,
      referrer:
        document.referrer.indexOf(window.location.origin) === 0
          ? undefined
          : document.referrer,
      accountName: account,
      routeId: route && route.routeId ? route.routeId : '',
    }
  }, [account, title, canUseDOM, pixelCacheKey])

  useDataPixel(skip ? null : eventData, pixelCacheKey)
}

// Those pages already use the hook above (`usePageView`)
// They need to handle the pageView event because they set the page title async
const SKIP_PAGES = ['store.search', 'store.product']

/** When you navigate to a new page, the route object will remain the one from the previous route.
 * So we save the ref on the first mount. After that, we wait for the first time route changes to send a page view with the correct title.
 * A possible better implementation for the future, is add a loading state in the route object.
 */
const PageViewPixel = ({ title }: Partial<UsePageViewArgs>) => {
  const { route } = useRuntime()

  const skip = route && SKIP_PAGES.some(routeId => route.routeId.indexOf(routeId) === 0)
  usePageView({ title, skip })

  return null
}

export default PageViewPixel

```


[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/hooks/useDataPixel.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useEffect, useRef } from 'react'
import {usePixel} from '../components/new/PixelContext/PixelContext'
import { isEmpty } from 'ramda'

type Data = unknown[] | unknown

const useDataPixel = (data: Data, pageIdentifier: string = '', isLoading = false) => {
  const { push } = usePixel()
  const previousIdRef = useRef<string|null>(null)

  const previousId = previousIdRef.current

  useEffect(() => {
    if (pageIdentifier && !isLoading && previousId !== pageIdentifier) {
      if (!data || isEmpty(data)) {
        return
      }
      if (Array.isArray(data)) {
        data.forEach(push)
      } else {
        push(data as any)
      }

      previousIdRef.current = pageIdentifier
    }
  }, [data, isLoading, pageIdentifier, previousId, push])
}

export default useDataPixel

```


[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/FormatCurrency/formatCurrency.ts from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { WrappedComponentProps } from 'react-intl'

interface FormatCurrencyParams extends WrappedComponentProps {
  value: number
  culture: {
    currency: string
    customCurrencyDecimalDigits?: number | null
    customCurrencySymbol?: string | null
  }
}

export default function formatCurrency({
  intl,
  culture,
  value,
}: FormatCurrencyParams) {

  return intl.formatNumber(value, {
    style: 'currency',
    currency: culture.currency,
    ...(culture.customCurrencyDecimalDigits != null
      ? { minimumFractionDigits: culture.customCurrencyDecimalDigits }
      : {}),
  })
}

```


[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/FormatCurrency/FormattedCurrency.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, Fragment } from 'react'
import { useRuntime } from '../../../../vtex.render-runtime'
import { injectIntl, WrappedComponentProps } from 'react-intl'

const FormattedCurrency: FC<FormattedCurrencyProps & WrappedComponentProps> = ({
  value,
  intl,
}) => {
  const { culture } = useRuntime()

  const number = intl.formatNumber(value, {
    style: 'currency',
    currency: culture.currency,
    ...(culture.customCurrencyDecimalDigits != null
      ? { minimumFractionDigits: culture.customCurrencyDecimalDigits }
      : {}),
  })

  return (
    <Fragment>
      {number}
    </Fragment>
  )
}

interface FormattedCurrencyProps {
  value: number
}

export default injectIntl(FormattedCurrency)

```


[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/StackLayout/index.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { defineMessages } from 'react-intl'
import useCssHandles from '../CssHandles/useCssHandles'
import applyModifiers from '../CssHandles/applyModifiers'

const CSS_HANDLES = ['stackContainer', 'stackItem'] as const

interface Props {
  zIndexOffset?: number
  blockClass?: string
}

const StackLayout: StorefrontFunctionComponent<Props> = ({
  children,
  zIndexOffset = 0,
  blockClass,
}) => {
  const handles = useCssHandles(CSS_HANDLES,{blockClass})
  return (
    <div className={`${handles.stackContainer} relative`}>
      {React.Children.toArray(children).map((child, idx) => {

        // This allows the user customize the stackItem via CSS, via the blockClass of each child
        const childBlockClass = (child as any)?.props?.blockProps?.blockClass || ''
        let stackItemBlockClass = ''
        if (childBlockClass) {
          stackItemBlockClass = applyModifiers(handles.stackItem, childBlockClass)
        }

        if (idx === 0) {
          return (
            <div
              key={idx}
              className={`${applyModifiers(handles.stackItem, 'first')} ${stackItemBlockClass}`}
              style={{ zIndex: zIndexOffset + 1 }}
            >
              {child}
            </div>
          )
        }

        return (
          <div
            key={idx}
            className={`${handles.stackItem} absolute top-0 left-0 w-auto h-auto ${stackItemBlockClass}`}
            style={{ zIndex: zIndexOffset + idx + 1 }}
          >
            {child}
          </div>
        )
      })}
    </div>
  )
}

const messages = defineMessages({
  title: {
    defaultMessage: '',
    id: 'admin/editor.stack-layout.title',
  },
  description: {
    defaultMessage: '',
    id: 'admin/editor.stack-layout.description',
  },
})

StackLayout.schema = {
  title: messages.title.id,
  description: messages.description.id,
}

export default StackLayout

```


[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/Drawer/styles.css from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```css
.hiddenBody {
  overflow: hidden;
  position: fixed;
  bottom: 0;
  left: 0;
}

```


[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/Drawer/Drawer.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { ReactElement, Suspense, useReducer } from 'react'
import { defineMessages } from 'react-intl'

import IconClose from '../StoreIcons/IconClose'
import IconMenu from '../StoreIcons/IconMenu'
import useCssHandles from '../CssHandles/useCssHandles'

import Overlay from './Overlay'
import Portal from './Portal'
import useLockScroll from './modules/useLockScroll'

const Swipable = React.lazy(() => import('./Swipable'))

interface MenuState {
  isOpen: boolean
  hasBeenOpened: boolean
}

interface MenuAction {
  type: 'open' | 'close'
}

const initialMenuState: MenuState = {
  isOpen: false,
  hasBeenOpened: false,
}

function menuReducer(state: MenuState, action: MenuAction) {
  switch (action.type) {
    case 'open':
      return {
        ...state,
        isOpen: true,
        hasBeenOpened: true,
      }
    case 'close':
      return {
        ...state,
        isOpen: false,
      }
    default:
      return state
  }
}

const useMenuState = () => {
  const [state, dispatch] = useReducer(menuReducer, initialMenuState)
  const setLockScroll = useLockScroll()

  const setMenuOpen = (value: boolean) => {
    dispatch({ type: value ? 'open' : 'close' })
    setLockScroll(value)
  }

  const openMenu = () => setMenuOpen(true)
  const closeMenu = () => setMenuOpen(false)

  return {
    state,
    openMenu,
    closeMenu,
  }
}

const CSS_HANDLES = [
  'openIconContainer',
  'drawer',
  'closeIconContainer',
  'childrenContainer',
  'closeIconButton',
]

const Drawer: any = ({
  width,
  customIcon,
  maxWidth = 450,
  isFullWidth,
  slideDirection = 'horizontal',
  children,
}) => {
  const { state: menuState, openMenu, closeMenu } = useMenuState()
  const { isOpen: isMenuOpen, hasBeenOpened: hasMenuBeenOpened } = menuState
  const handles = useCssHandles(CSS_HANDLES)

  const direction =
    slideDirection === 'horizontal' || slideDirection === 'leftToRight'
      ? 'left'
      : 'right'

  const swipeHandler = direction === 'left' ? 'onSwipeLeft' : 'onSwipeRight'

  return (
    <>
      <div
        className={`pa4 pointer ${handles.openIconContainer}`}
        onClick={openMenu}
        aria-hidden
      >
        {customIcon || <IconMenu size={20} />}
      </div>
      <Portal>
        <Overlay visible={isMenuOpen} onClick={closeMenu} />
        <Suspense fallback={<React.Fragment />}>
          <Swipable
            {...{
              [swipeHandler]: closeMenu,
            }}
            enabled={isMenuOpen}
            position={isMenuOpen ? 'center' : direction}
            allowOutsideDrag
            className={`${handles.drawer} ${
              direction === 'right' ? 'right-0' : 'left-0'
            } fixed top-0 bottom-0 bg-base z-999 flex flex-column`}
            style={{
              width: width || (isFullWidth ? '100%' : '85%'),
              maxWidth,
              minWidth: 280,
              pointerEvents: isMenuOpen ? 'auto' : 'none',
            }}
          >
            <div
              style={{
                WebkitOverflowScrolling: 'touch',
                overflowY: 'scroll',
              }}
            >
              <div className={`flex ${handles.closeIconContainer}`}>
                <button
                  className={`${handles.closeIconButton} pa4 pointer bg-transparent transparent bn pointer`}
                  onClick={closeMenu}
                >
                  <IconClose size={30} type="line" />
                </button>
              </div>
              <div className={`${handles.childrenContainer} flex flex-grow-1`}>
                {hasMenuBeenOpened && children}
              </div>
            </div>
          </Swipable>
        </Suspense>
      </Portal>
    </>
  )
}

const messages = defineMessages({
  title: {
    defaultMessage: '',
    id: 'admin/editor.drawer.title',
  },
})

Drawer.getSchema = () => {
  return {
    title: messages.title.id,
  }
}

export default Drawer 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/Drawer/Portal.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { FunctionComponent } from 'react'
import ReactDOM from 'react-dom'
import { useSSR } from '../../../../vtex.render-runtime'

const Portal: FunctionComponent = ({ children }) => {
  const body = window && window.document && window.document.body
  const isSSR = useSSR()

  if (!body || isSSR) {
    return null
  }

  return ReactDOM.createPortal(children, body)
}

export default Portal

```


[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/Drawer/Swipable.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { animate } from './modules/animation'
import PropTypes from 'prop-types'
import parseMeasure from './modules/parseMeasure'
import getPointerPosition from './modules/getPointerPosition'

const CENTER = 'center'
const LEFT = 'left'
const RIGHT = 'right'

export default class Swipable extends React.Component {
  constructor(props) {
    super(props)

    this.dragContainer = React.createRef()

    this.stopAnimation = () => {}
    this.isPointerDown = false
    this.isDragging = false

    /* Used for the click event handler, which is
     * fired after mouseup is fired.
     * See comment on handleClick function */
    this.wasDragging = false

    this.offset = this.getOffsetFromPosition()
    this.offsetAnimation = { value: this.offset }
    this.momentum = null
    this.momentumTimeout = null
    this.dragStartPos = {
      x: 0,
      y: 0,
    }
    this.previousDragPositions = []
    this.willTrigger = false
  }

  componentDidMount() {
    if (!window || !window.document) {
      return
    }

    window.document.addEventListener('mousedown', this.handleDragStart)
    window.document.addEventListener('touchstart', this.handleDragStart)
    window.document.addEventListener('mousemove', this.handleDragMove)
    window.document.addEventListener('touchmove', this.handleDragMove)
    window.document.addEventListener('mouseup', this.handleDragEnd)
    window.document.addEventListener('touchend', this.handleDragEnd)
    window.document.addEventListener('click', this.handleClick, {
      capture: true,
    })
  }

  componentWillUnmount() {
    if (!window || !window.document) {
      return
    }

    window.document.removeEventListener('mousedown', this.handleDragStart)
    window.document.removeEventListener('touchstart', this.handleDragStart)
    window.document.removeEventListener('mousemove', this.handleDragMove)
    window.document.removeEventListener('touchmove', this.handleDragMove)
    window.document.removeEventListener('mouseup', this.handleDragEnd)
    window.document.removeEventListener('touchend', this.handleDragEnd)
    window.document.removeEventListener('click', this.handleClick, {
      capture: true,
    })
  }

  /* Prevents click events from firing in the event of
   * firing swipe events. */
  handleClick = event => {
    if (this.wasDragging || this.isPointerDown) {
      event.preventDefault()
      event.stopPropagation()
    }
    this.wasDragging = false
  }

  componentDidUpdate(prevProps) {
    if (prevProps.enabled && !this.props.enabled && this.isPointerDown) {
      this.isPointerDown = false
    }

    if (prevProps.position !== this.props.position) {
      this.updatePosition()
    }
  }

  updatePosition = () => {
    this.offsetAnimation.value = this.offset
    animate({
      object: this.offsetAnimation,
      prop: 'value',
      target: this.getOffsetFromPosition(),
      ...(this.momentum
        ? { speed: this.momentum, acceleration: 1.25 }
        : { duration: 0.25 }),
      onUpdate: value => {
        this.setOffset(value)
      },
    })

    this.momentum = null
    if (this.momentumTimeout) {
      clearTimeout(this.momentumTimeout)
      this.momentumTimeout = null
    }
  }

  getOffsetFromPosition = () => {
    switch (this.props.position) {
      case 'center':
        return 0
      case 'right':
        return this.props.positionRight
      case 'left':
        return this.props.positionLeft
    }
  }

  handleDragStart = event => {
    if (this.isPointerDown || !this.props.enabled) {
      return
    }

    if (
      !this.props.allowOutsideDrag &&
      !this.dragContainer.current.contains(event.target)
    ) {
      return
    }

    const pos = getPointerPosition(event)
    if (pos === null) return

    this.isPointerDown = true
    this.isScrolling = false
    this.isDragging = false
    this.stopAnimation()
    this.dragStartPos = {
      ...pos,
    }
    this.previousDragPositions = [pos]
    this.willTrigger = false
    this.dispatchTriggerChange(this.willTrigger)
  }

  /** Lets the parent know that a swipe event will be triggered if the cursor
   * is released. Useful for displaying UI feedback */
  dispatchTriggerChange = willTrigger => {
    const { onTriggerChange } = this.props
    if (onTriggerChange) {
      onTriggerChange(willTrigger)
    }
  }

  handleDragMove = event => {
    const {
      onDragStart,
      onLockScroll,
      onSwipeLeft,
      onSwipeRight,
      enabled,
      rubberBanding,
    } = this.props
    if (this.isPointerDown && !this.isScrolling) {
      const pos = getPointerPosition(event)

      if (pos === null) return

      const lastPos = this.previousDragPositions[
        this.previousDragPositions.length - 1
      ]

      if (lastPos && pos.source !== lastPos.source) {
        return
      }

      /* Values to determine if the dragging means either a swipe or a scroll */
      const threshold = {
        x: 15,
        y: 10,
      }

      const distance = {
        x: pos.x - this.dragStartPos.x,
        y: pos.y - this.dragStartPos.y,
      }

      if (!this.isDragging) {
        if (Math.abs(distance.x) >= threshold.x) {
          this.isDragging = true
          onDragStart()
          onLockScroll()
        } else if (Math.abs(distance.y) >= threshold.y) {
          this.isScrolling = true
        }
      } else {
        this.offset = distance.x

        /** Either applies rubberbanding or stops dragging at the limits */
        const limitDragging = offset => {
          const rubberBandingMultiplier = 0.3
          return rubberBanding ? offset * rubberBandingMultiplier : 0
        }

        if (!enabled || (!onSwipeLeft && this.offset < 0)) {
          this.offset = limitDragging(this.offset)
        } else if (!enabled || (!onSwipeRight && this.offset > 0)) {
          this.offset = limitDragging(this.offset)
        }

        this.setOffset(this.offset)
        this.previousDragPositions.push(pos)

        const willTrigger = this.checkTrigger()

        if (this.willTrigger !== willTrigger) {
          this.dispatchTriggerChange(willTrigger)
        }

        this.willTrigger = willTrigger
      }
    }
  }

  setOffset = offset => {
    this.offset = offset
    if (this.dragContainer && this.dragContainer.current) {
      this.props.onSetPosition({
        element: this.props.element || this.dragContainer.current,
        offset,
      })
      this.props.onUpdateOffset(offset)
    }
  }

  setMomentum = (momentum, target) => {
    const [, targetUnit] = parseMeasure(target)

    if (targetUnit === '%') {
      const bounds = this.dragContainer.current.getBoundingClientRect()
      const width = bounds.width
      this.offset = `${(this.offset / width) * 100}%`
      momentum = (momentum / width) * 100
    }
    this.momentum = momentum

    /* Lets momentum live only for a brief time. If position changes in this meantime,
     * then momentum is applied. Otherwise it's ignored and a regular transition is done */
    if (this.momentumTimeout) {
      clearTimeout(this.momentumTimeout)
    }
    this.momentumTimeout = setTimeout(() => {
      this.momentum = null
      this.momentumTimeout = null
    }, 100)
  }

  /** Checks if the mouse/touch movement at the time of release triggers a
   * swipe, and if so, to which direction */
  checkTrigger = () => {
    if (!this.props.enabled) {
      return null
    }

    /* Checks the last $samples cursor positions to determine the
     * average speed and direction of movement */
    const samples = 6
    const fps = 60
    const releaseSpeed =
      this.previousDragPositions
        .slice(-samples)
        .map((cur, i, arr) => {
          const last = arr[i - 1]
          if (last == null) {
            return null
          }
          return cur.x - last.x
        })
        .filter(cur => cur != null)
        .reduce((sum, cur) => sum + cur / samples, 0) * fps

    const { onSwipeLeft, onSwipeRight } = this.props

    const triggers = {
      left:
        onSwipeLeft && releaseSpeed < 0 && this.offset < -this.props.threshold,
      right:
        onSwipeRight && releaseSpeed > 0 && this.offset > this.props.threshold,
    }

    if (triggers.left) {
      return {
        type: LEFT,
        speed: releaseSpeed,
      }
    }
    if (triggers.right) {
      return {
        type: RIGHT,
        speed: releaseSpeed,
      }
    }
    return null
  }

  handleDragEnd = event => {
    if (this.isPointerDown && this.isDragging) {
      event.preventDefault()
      event.stopPropagation()
      const trigger = this.checkTrigger()
      if (trigger) {
        switch (trigger.type) {
          case LEFT:
            if (this.props.preserveMomentum) {
              this.setMomentum(trigger.speed, this.props.positionLeft)
            }
            this.props.onSwipeLeft()
            break
          case RIGHT:
            if (this.props.preserveMomentum) {
              this.setMomentum(trigger.speed, this.props.positionRight)
            }
            this.props.onSwipeRight()
            break
        }
      } else {
        this.offsetAnimation.value = this.offset
        animate({
          object: this.offsetAnimation,
          prop: 'value',
          target: 0,
          duration: 0.2,
          onUpdate: value => {
            this.setOffset(value)
          },
        })
      }
      this.props.onDragEnd()
      this.props.onUnlockScroll()
    }
    this.isScrolling = false
    this.wasDragging = this.isPointerDown && this.isDragging
    this.isPointerDown = false
  }

  render() {
    return (
      <div
        aria-hidden
        ref={this.dragContainer}
        style={{
          ...this.props.style,
          transform: `translate3d(${this.getOffsetFromPosition()}, 0, 0)`,
        }}
        className={this.props.className}
      >
        {this.props.children}
      </div>
    )
  }
}

Swipable.propTypes = {
  children: PropTypes.node,
  onSwipeLeft: PropTypes.func,
  onSwipeRight: PropTypes.func,
  onTriggerChange: PropTypes.func,
  onLockScroll: PropTypes.func,
  onUnlockScroll: PropTypes.func,
  onDragStart: PropTypes.func,
  onDragEnd: PropTypes.func,
  onSetPosition: PropTypes.func,
  onUpdateOffset: PropTypes.func,
  threshold: PropTypes.number,
  enabled: PropTypes.bool,
  rubberBanding: PropTypes.bool,
  element: PropTypes.element,
  position: PropTypes.oneOf([CENTER, LEFT, RIGHT]),
  className: PropTypes.string,
  style: PropTypes.object,
  positionRight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  positionLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  preserveMomentum: PropTypes.bool,
  allowOutsideDrag: PropTypes.bool,
}

Swipable.defaultProps = {
  onSwipeLeft: null,
  leftTargetPosition: null,
  onSwipeRight: null,
  rightTargetPosition: null,
  onTriggerChange: null,
  position: CENTER,
  onLockScroll: () => {},
  onUnlockScroll: () => {},
  onDragStart: () => {},
  onDragEnd: () => {},
  onSetPosition: ({ element, offset }) => {
    const unit = typeof offset === 'number' ? 'px' : ''
    element.style.transform = `translate3d(${offset}${unit},0,0)`
  },
  onUpdateOffset: () => {},
  element: null,
  threshold: 0,
  enabled: true,
  rubberBanding: false,
  style: {},
  positionRight: '100%',
  positionLeft: '-100%',
  preserveMomentum: true,
  allowOutsideDrag: false,
}

```


[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/Drawer/Overlay.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { RefForwardingComponent } from 'react'

interface Props {
  visible: boolean
  onClick(event: React.MouseEvent | React.TouchEvent): void
}

const Overlay: RefForwardingComponent<HTMLDivElement, Props> = (
  { visible, onClick }: Props,
  ref
) => {
  return (
    <div
      ref={ref}
      aria-hidden
      onClick={onClick}
      style={{
        opacity: visible ? 0.5 : 0,
        pointerEvents: visible ? 'auto' : 'none',
        transition: 'opacity 300ms',
      }}
      className="bg-base--inverted z-999 fixed top-0 bottom-0 left-0 right-0"
    />
  )
}

export default React.forwardRef(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/Footer/SocialNetworks.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import IOMessage from '../NativeTypes/IOMessage'
import useCssHandles from '../CssHandles/useCssHandles'

import SocialNetwork from './components/SocialNetwork'

interface SocialNetworkData {
  url: string
  name: string
}

interface Props {
  title?: string
  socialNetworks: SocialNetworkData[]
  showInColor: boolean
}

const CSS_HANDLES = [
  'socialNetworksTitle',
  'socialNetworksContainer',
  'socialNetworkWrapper',
]

const SocialNetworks: StorefrontFunctionComponent<Props> = ({
  title,
  showInColor,
  socialNetworks = [],
}) => {
  const handles = useCssHandles(CSS_HANDLES)

  return (
    <div className={handles.socialNetworkWrapper}>
      {title && (
        <div className={`${handles.socialNetworksTitle} mb4`}>
          <IOMessage id={title} />
        </div>
      )}
      <div className={`${handles.socialNetworksContainer} nh2 flex`}>
        {socialNetworks.map(socialNetworkData => (
          <SocialNetwork
            key={socialNetworkData.name + socialNetworkData.url}
            showInColor={showInColor}
            url={socialNetworkData.url}
            name={socialNetworkData.name}
          />
        ))}
      </div>
    </div>
  )
}

SocialNetworks.schema = {
  title: 'admin/editor.footer.socialNetworks.title',
  description: 'admin/editor.footer.socialNetworks.description',
  type: 'object',
  properties: {
    showInColor: {
      default: false,
      isLayout: true,
      title: 'admin/editor.footer.showSocialNetworksInColor.title',
      type: 'boolean',
    },
  },
}

export default SocialNetworks

```


[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/Footer/Spacer.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import useCssHandles from '../CssHandles/useCssHandles'

const CSS_HANDLES = ['footerSpacer'] as const

const Spacer: FunctionComponent = () => {
  const handles = useCssHandles(CSS_HANDLES)

  return <div className={`${handles.footerSpacer} flex flex-grow-1`} />
}

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/Footer/AcceptedPaymentMethods.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

import PaymentMethodIcon, {
  PaymentMethod,
} from './components/PaymentMethodIcon'

interface Props {
  paymentMethods: PaymentMethod[]
  showInColor: boolean
}

const CSS_HANDLES = ['acceptedPaymentMethodContainer'] as const

const AcceptedPaymentMethods: StorefrontFunctionComponent<Props> = ({
  paymentMethods = [],
  showInColor = false,
}) => {
  const handles = useCssHandles(CSS_HANDLES)

  return (
    <div className={`${handles.acceptedPaymentMethodContainer} nh2 flex`}>
      {paymentMethods.map(paymentMethod => (
        <PaymentMethodIcon
          key={paymentMethod}
          paymentMethod={paymentMethod}
          showInColor={showInColor}
        />
      ))}
    </div>
  )
}

AcceptedPaymentMethods.schema = {
  title: 'admin/editor.footer.acceptedPaymentMethods.title',
  description: 'admin/editor.footer.acceptedPaymentMethods.description',
  type: 'object',
  properties: {
    showInColor: {
      default: false,
      isLayout: true,
      title: 'admin/editor.footer.showPaymentMethodsInColor.title',
      type: 'boolean',
    },
  },
}

export default AcceptedPaymentMethods

```


[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/Footer/PoweredBy.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import useCssHandles from '../CssHandles/useCssHandles'
import { withRuntimeContext } from 'vtex.render-runtime'

import withImage from './components/withImage'
import { PLATFORM_GOCOMMERCE } from './modules/platformCode'

const CSS_HANDLES = ['poweredBy', 'poweredByImage', 'poweredByLink']

/**
 * "Powered By VTEX/GoCommerce" image component, used in Footer
 */
const PoweredBy: StorefrontFunctionComponent<PoweredByProps> = ({
  imageSrc,
  runtime,
}) => {
  const handles = useCssHandles(CSS_HANDLES)
  if (!imageSrc) {
    return null
  }

  if (runtime.platform === PLATFORM_GOCOMMERCE) {
    return (
      <a
        href="https://www.gocommerce.com/?utm_source=store_footer"
        className={handles.poweredByLink}
        target="_blank"
        rel="noopener noreferrer"
      >
        <div className={`${handles.poweredBy} flex items-center w4`}>
          <img
            className={`${handles.poweredByImage} w-100`}
            src={imageSrc}
            alt="GoCommerce"
          />
        </div>
      </a>
    )
  }

  return (
    <div className={`${handles.poweredBy} flex items-center h3 w3`}>
      <img
        className={`${handles.poweredByImage} w-100`}
        src={imageSrc}
        alt="VTEX"
      />
    </div>
  )
}

interface PoweredByProps extends PoweredBySchema {
  runtime: {
    platform: string
  }
  logoUrl: string
  imageSrc: string
}

interface PoweredBySchema {
  showInColor: boolean
}

PoweredBy.displayName = 'PoweredBy'

const getImagePathFromProps = ({ runtime, showInColor }: PoweredByProps) =>
  `${runtime.platform}${showInColor ? '' : '-bw'}.svg`

export default withRuntimeContext(withImage(getImagePathFromProps)(PoweredBy))

```


[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/Footer/FooterLayout.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

const CSS_HANDLES = ['footerLayout', 'footerLayoutSpacer'] as const

const FooterLayout: React.FC = props => {
  const handles = useCssHandles(CSS_HANDLES)

  return (
    <>
      <div className={`${handles.footerLayoutSpacer} flex flex-grow-1`} />
      <div className={handles.footerLayout}>{props.children}</div>
    </>
  )
}

export default FooterLayout

```


[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/Footer/Row.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import classNames from 'classnames'
import useCssHandles from '../CssHandles/useCssHandles'
import Container from '../StoreComponents/Container'

interface RowProps {
  fullWidth?: boolean
  inverted?: boolean
  blockClass?: string
}

const CSS_HANDLES = ['rowContainer', 'row', 'rowContentContainer'] as const

const Row: StorefrontFunctionComponent<RowProps> = ({
  children,
  fullWidth,
  inverted,
  blockClass,
}) => {
  const handles = useCssHandles(CSS_HANDLES,{blockClass})

  const content = (
    <div className={`${handles.rowContainer} w-100 flex items-center`}>
      {children}
    </div>
  )

  return (
    <div
      className={classNames(
        handles.row,
        'w-100',
        inverted ? 'bg-base--inverted c-on-base--inverted' : 'bg-base c-on-base'
      )}
    >
      {fullWidth ? (
        content
      ) : (
        <Container className={`${handles.rowContentContainer} w-100 flex`}>
          {content}
        </Container>
      )}
    </div>
  )
}

Row.schema = {
  title: 'admin/editor.row.title',
  type: 'object',
  properties: {
    blockClass: {
      title: 'admin/editor.blockClass.title',
      description: 'admin/editor.blockClass.description',
      type: 'string',
      isLayout: true,
    },
    inverted: {
      title: 'admin/editor.inverted.title',
      description: 'admin/editor.inverted.description',
      type: 'boolean',
      default: true,
      isLayout: true,
    },
    fullWidth: {
      title: 'admin/editor.fullWidth.title',
      description: 'admin/editor.fullWidth.description',
      type: 'boolean',
      default: false,
      isLayout: true,
    },
  },
}

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/Footer/Footer.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import useDevice from '../DeviceDetector/useDevice'
import Row from './Row'
import Spacer from './Spacer'
import SocialNetworks from './SocialNetworks'
import Menu from '../Menu/Menu'
import MenuItem from '../Menu/MenuItem'
import AcceptedPaymentMethods from './AcceptedPaymentMethods'
import RichText from '../RichText'
import SubmenuAccordion from '../Menu/SubmenuAccordion'

const Desktop = () => {
  return (
    <div>
    <Row blockClass="menu-row" paddingTop={6} paddingBottom={3}>
      <Menu orientation="vertical">
        <MenuItem id="menu-item-news" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "#", noFollow: true, tagTitle:"News", text:"News"}}/>
        <MenuItem id="menu-item-black-friday" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "#", noFollow: true, tagTitle:"BlackFriday", text:"Black Friday"}}/>
        <MenuItem id="menu-item-sale" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "#", noFollow: true, tagTitle:"Sale", text:"Sale"}}/>
        <MenuItem id="menu-item-personalization" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "#", noFollow: true, tagTitle:"Personalization", text:"Personalization"}}/>
      </Menu>
      <Menu orientation="vertical">
        <MenuItem id="menu-item-category-clothing" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/d", noFollow: true, tagTitle:"Clothing", text:"Clothing"}}/>
        <MenuItem id="menu-item-shorts" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/shorts", noFollow: true, tagTitle:"Shorts", text:"Shorts"}}/>
        <MenuItem id="menu-item-tank-tops" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/tank-tops", noFollow: true, tagTitle:"Tank Tops", text:"Tank Tops"}}/>
        <MenuItem id="menu-item-shirts" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/shirts", noFollow: true, tagTitle:"Shirts", text:"Shirts"}}/>
        <MenuItem id="menu-item-sweat-shirts" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/sweatshirt", noFollow: true, tagTitle:"Sweatshirt", text:"Sweatshirt"}}/>
        <MenuItem id="menu-item-cropped" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/cropped", noFollow: true, tagTitle:"Cropped", text:"Cropped"}}/>
      </Menu>
      <Menu orientation="vertical">
        <MenuItem id="menu-item-smartphones" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/smartphones", noFollow: true, tagTitle:"Smartphones", text:"Smartphones"}}/>
        <MenuItem id="menu-item-videogames" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/videogames", noFollow: true, tagTitle:"Videogames", text:"Videogames"}}/>
        <MenuItem id="menu-item-tvs" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/tvs", noFollow: true, tagTitle:"TVs", text:"TVs"}}/>
      </Menu>
      <Menu orientation="vertical">
        <MenuItem id="menu-item-bags" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/bags/d", noFollow: true, tagTitle:"Bags", text:"Bags"}}/>
        <MenuItem id="menu-item-backpacks" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/bags/backpacks", noFollow: true, tagTitle:"Backpacks", text:"Backpacks"}}/>
        <MenuItem id="menu-item-necessaire" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/bags/necessaire", noFollow: true, tagTitle:"Necessaire", text:"Necessaire"}}/>
      </Menu>
      <Spacer />
      <SocialNetworks socialNetworks={[
        {
          "name": "Facebook",
          "url": "https://www.facebook.com/vtexonline/"
        },
        {
          "name": "Instagram",
          "url": "https://www.instagram.com/vtextruecloud/"
        },
        {
          "name": "Twitter",
          "url": "https://twitter.com/vtexonline"
        },
        {
          "name": "Youtube",
          "url": "https://www.youtube.com/user/VTEXTV"
        }
      ]}/>
    </Row>
    <Row blockClass="payment-methods">
      <AcceptedPaymentMethods paymentMethods={["MasterCard", "Visa", "Diners Club"]} />
    </Row>
    <Row blockClass="credits">
      <RichText text="All stock and product photos are from photos.icons8.com" blockClass="footer"/>
    </Row>
    </div>
  )
}

const Mobile = () => {
  return (
    <div>
      <Row paddingTop={4} paddingBottom={4}>
      <Menu orientation="vertical">
        <MenuItem id="menu-item-category-clothing" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/d", noFollow: true, tagTitle:"Clothing", text:"Clothing"}}>
          <SubmenuAccordion>
            <Menu orientation="vertical">
              <MenuItem id="menu-item-category-clothing" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/d", noFollow: true, tagTitle:"Clothing", text:"Clothing"}}/>
              <MenuItem id="menu-item-shorts" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/shorts", noFollow: true, tagTitle:"Shorts", text:"Shorts"}}/>
              <MenuItem id="menu-item-tank-tops" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/tank-tops", noFollow: true, tagTitle:"Tank Tops", text:"Tank Tops"}}/>
              <MenuItem id="menu-item-shirts" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/shirts", noFollow: true, tagTitle:"Shirts", text:"Shirts"}}/>
              <MenuItem id="menu-item-sweat-shirts" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/sweatshirt", noFollow: true, tagTitle:"Sweatshirt", text:"Sweatshirt"}}/>
              <MenuItem id="menu-item-cropped" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/clothing/cropped", noFollow: true, tagTitle:"Cropped", text:"Cropped"}}/>
            </Menu>
          </SubmenuAccordion>
        </MenuItem>
        <MenuItem itemProps={{ "tagTitle": "Decoration", "text": "Decoration" }}>
          <SubmenuAccordion>
            <MenuItem id="menu-item-smartphones" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/smartphones", noFollow: true, tagTitle:"Smartphones", text:"Smartphones"}}/>
            <MenuItem id="menu-item-videogames" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/videogames", noFollow: true, tagTitle:"Videogames", text:"Videogames"}}/>
            <MenuItem id="menu-item-tvs" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/tvs", noFollow: true, tagTitle:"TVs", text:"TVs"}}/>
          </SubmenuAccordion>
        </MenuItem>
        <MenuItem itemProps={{ "tagTitle": "Sale", "text": "Sale" }}>
          <SubmenuAccordion>
            <MenuItem id="menu-item-smartphones" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/smartphones", noFollow: true, tagTitle:"Smartphones", text:"Smartphones"}}/>
            <MenuItem id="menu-item-videogames" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/videogames", noFollow: true, tagTitle:"Videogames", text:"Videogames"}}/>
            <MenuItem id="menu-item-tvs" type="custom" iconId={null} highlight={false} itemProps={{ type: "internal", href: "/decoration/tvs", noFollow: true, tagTitle:"TVs", text:"TVs"}}/>
          </SubmenuAccordion>
        </MenuItem>
      </Menu>
      </Row>
      <Row>

      </Row>
    </div>
  )
}

const Footer = () => {
  const { isMobile } = useDevice()
  return isMobile ? <Mobile /> : <Desktop />
}

Footer.schema = {
  title: 'admin/editor.footer.title',
  description: 'admin/editor.footer.description',
  type: 'object',
  properties: {
    showPaymentFormsInColor: {
      type: 'boolean',
      title: 'admin/editor.footer.showPaymentMethodsInColor.title',
      default: false,
      isLayout: true,
    },
    showSocialNetworksInColor: {
      type: 'boolean',
      title: 'admin/editor.footer.showSocialNetworksInColor.title',
      default: false,
      isLayout: true,
    },
    showVtexLogoInColor: {
      type: 'boolean',
      title: 'admin/editor.footer.showVtexLogoInColor.title',
      default: false,
      isLayout: true,
    },
  },
}

export default Footer

```


[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/ProductListContext/ProductListContext.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export interface Product {
  productId: string
  [key: string]: any
}
export interface State {
  nextImpressions: Product[]
  sentIds: Set<string>
}

type ReducerActions =
  | { type: 'SEND_IMPRESSION'; args: { product: Product } }
  | { type: 'RESET_NEXT_IMPRESSIONS' }

export type Dispatch = (action: ReducerActions) => void

const DEFAULT_STATE: State = {
  nextImpressions: [],
  sentIds: new Set<string>(),
}

const ProductListStateContext = createContext<State>(DEFAULT_STATE)
const ProductListDispatchContext = createContext<Dispatch>(action => {
  console.error('error in dispatch ', action)
})

function productListReducer(state: State, action: ReducerActions): State {
  switch (action.type) {
    case 'SEND_IMPRESSION': {
      const { product } = action.args
      let nextImpressions = state.nextImpressions
      if (!state.sentIds.has(product.productId)) {
        state.sentIds.add(product.productId)
        nextImpressions = state.nextImpressions.concat(product)
      }
      return {
        ...state,
        nextImpressions,
      }
    }
    case 'RESET_NEXT_IMPRESSIONS': {
      return { ...state, nextImpressions: [] }
    }
    default: {
      throw new Error(`Unhandled action type on product-list-context`)
    }
  }
}

const initialState: State = {
  nextImpressions: [],
  sentIds: new Set(),
}

const ProductListProvider: FC = ({ children }) => {
  const [state, dispatch] = useReducer(productListReducer, initialState)
  return (
    <ProductListStateContext.Provider value={state}>
      <ProductListDispatchContext.Provider value={dispatch}>
        {children}
      </ProductListDispatchContext.Provider>
    </ProductListStateContext.Provider>
  )
}

const useProductListState = () => useContext(ProductListStateContext)

const useProductListDispatch = () => useContext(ProductListDispatchContext)

export default {
  ProductListProvider,
  useProductListState,
  useProductListDispatch,
}

```


[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/ProductListContext/useProductImpression.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useEffect, useCallback } from 'react'
import debounce from 'debounce'
import PixelContext from '../PixelContext/PixelContext'

import productImpressionHooks, { Product, Dispatch } from './ProductListContext'
import { parseToProductImpression } from './utils/parser'

const { useProductListDispatch, useProductListState } = productImpressionHooks

const sendImpressionEvents = (
  products: Product[],
  push: any,
  dispatch: Dispatch
) => {
  if (!products || products.length <= 0) {
    return
  }
  const parsedProducts = products.filter(Boolean).map(parseToProductImpression)
  const impressions = parsedProducts.map((product: Product, index: number) => ({
    product,
    position: index + 1,
  }))
  push({
    event: 'productImpression',
    list: 'Shelf',
    impressions,
  })
  dispatch({ type: 'RESET_NEXT_IMPRESSIONS' })
}

const useProductImpression = () => {
  const { nextImpressions } = useProductListState()
  const { push } = PixelContext.usePixel()
  const dispatch = useProductListDispatch()

  const debouncedSendImpressionEvents = useCallback(
    debounce(sendImpressionEvents, 1000, false),
    []
  )

  useEffect(() => {
    debouncedSendImpressionEvents(nextImpressions, push, dispatch)
  }, [nextImpressions, debouncedSendImpressionEvents, dispatch, push])
}

export default useProductImpression

```


[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/CheckoutResources/Queries.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

const orderForm = loader('./queries/orderForm.graphql')

export default {
  orderForm,
}

```


[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/CheckoutResources/Mutations.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

const addToCart = loader('./mutations/addToCart.graphql')
const estimateShipping = loader('./mutations/estimateShipping.graphql')
const insertCoupon = loader('./mutations/insertCoupon.graphql')
const selectDeliveryOption = loader('./mutations/selectDeliveryOption.graphql')
const updateItems = loader('./mutations/updateItems.graphql')

export default {
  addToCart,
  estimateShipping,
  insertCoupon,
  selectDeliveryOption,
  updateItems,
}

```


[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/CheckoutResources/Utils.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useCheckoutURL } from './utils/useCheckoutURL'

export default {
  useCheckoutURL,
}

```


[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/LocaleSwitcher/LocaleSwitcher.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
/* eslint-disable react-hooks/exhaustive-deps */
import { loader } from 'graphql.macro'
import { path } from 'ramda'
import React, { useEffect, useMemo, useState } from 'react'
import { useQuery } from 'react-apollo'

import { useRuntime } from '../../../../vtex.render-runtime'
import useCssHandles from '../CssHandles/useCssHandles'
import IconGlobe from '../StoreIcons/IconGlobe'

const Locales = loader('./queries/locales.gql')

const CSS_HANDLES = ['container', 'button', 'buttonText', 'list', 'listElement']

function getLabel(localeId) {
  return localeId.split('-')[0]
}

function getSupportedLanguages(data) {
  if (data.loading || data.error) {
    return []
  }

  const supportedLanguages = path(['currentBinding', 'supportedLocales'], data) || path(['languages', 'supported'], data) || []

  return supportedLanguages.reduce((acc, lang) => {
    if (!lang.includes('-')) {
      return acc
    }

    return acc.concat({
      text: getLabel(lang),
      localeId: lang
    })
  }, [])
}

const getLocale = (supportedLangs, locale) => {
  const localeObj = supportedLangs.find(
    ({ localeId }) => getLabel(localeId) === getLabel(locale)
  )
  return localeObj || (supportedLangs && supportedLangs[0])
}

const LocaleSwitcher = () => {
  const data = useQuery(Locales)
  const supportedLangs = useMemo(() => getSupportedLanguages(data), [data])
  const { culture, emitter } = useRuntime()
  const [openLocaleSelector, setOpenLocaleSelector] = useState(false)
  const [selectedLocale, setSelectedLocale] = useState(() => getLocale(supportedLangs, culture && culture.locale))
  const handles = useCssHandles(CSS_HANDLES)

  useEffect(() => {
    const newSelectedLocale = getLocale(supportedLangs, culture.locale)

    if (newSelectedLocale !== selectedLocale) {
      setSelectedLocale(selectedLocale)
    }
  }, [supportedLangs, culture.locale])

  const handleLocaleClick = id => {
    emitter.emit('localesChanged', id)
    setOpenLocaleSelector(false)
    setSelectedLocale(getLocale(supportedLangs, id))
  }

  const handleMouseDown = e => {
    e.preventDefault()
  }

  if (supportedLangs.length === 0 || !selectedLocale) {
    return null
  }

  const containerClasses = `${handles.container} w3 flex items-center justify-end ml2 mr3 relative`
  const buttonClasses = `${handles.button} link pa0 bg-transparent bn flex items-center pointer mr3 c-on-base`
  const buttonTextClasses = `${handles.buttonText} pl2 t-action--small order-1`
  const listClasses = `${handles.list} absolute z-5 list top-1 w3 ph0 mh0 mv4 bg-base`
  const listElementClasses = `${handles.listElement} t-action--small pointer f5 pa3 hover-bg-muted-5 tc`

  return (
    <div className={containerClasses}>
      <button
        className={buttonClasses}
        onBlur={() => setOpenLocaleSelector(false)}
        onClick={() => setOpenLocaleSelector(!openLocaleSelector)}
      >
        <IconGlobe />
        <span className={buttonTextClasses}>{selectedLocale.text}</span>
      </button>
      <ul
        hidden={!openLocaleSelector}
        className={listClasses}
      >
        {supportedLangs
        .filter(({ localeId }) => localeId !== selectedLocale.localeId)
        .map(({ localeId, text }) => (
          <li
            key={localeId}
            onMouseDown={handleMouseDown}
            className={listElementClasses}
            onClick={() => handleLocaleClick(localeId)}
          >
            {text}
          </li>
        ))}
      </ul>
    </div>
  )
}

export default LocaleSwitcher

```


[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/ProductSummary/ProductSummaryAttachmentList.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import AttachmentList from './components/ProductSummaryAttachmentList/AttachmentList'

export default AttachmentList

```


[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/ProductSummary/ProductSummarySpecificationBadges.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummarySpecificationBadges

```


[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/ProductSummary/Spacer.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 = ['spacer']

const Spacer = () => {
  const handles = useCssHandles(CSS_HANDLES)
  return <div className={`${handles.spacer} flex flex-grow-1`}/>
}

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/ProductSummary/productSummary.css from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```css
.containerInline .imageContainer {
  max-width: 30%;
}

.containerInline .imageContainer > img {
  max-height: 100%;
}

.container {
}
.containerSmall {
}
.containerInline {
}
.containerInlinePrice {
}
.information {
}
.element {
}
.image {
}
.buyButtonContainer {
}
.buyButton {
}
.description {
}
.quantityStepperContainer {
}
.imageInline {
  max-height: 7rem;
}

.isHidden {
  visibility: hidden;
}

.containerNormal {
}

.nameContainer {
}

.clearLink {
  text-decoration: inherit;
  color: inherit;
}

.aspectRatio {
  padding-top: 100%;
  background: center / contain no-repeat;
}

.priceContainer {
}

.SKUSelectorContainer {}

.attachmentListContainer {
}

.attachmentItemContainer {
}

.imageNormal {
  max-height: 17.56rem;
}

.addToListBtn {
}

.imagePlaceholder {
}

.attachmentChildrenContainer {
}

.imageStackContainer {
}

.hoverEffect {
}

.hoverEffect:hover .hoverImage {
  display: inline;
}

.hoverImage {
}

```


[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/ProductSummary/ProductSummarySKUSelector.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummarySKUSelector

```


[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/ProductSummary/ProductSummaryName.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummaryName

```


[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/ProductSummary/ProductSummaryCustom.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummary

```


[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/ProductSummary/ProductSummaryImage.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductImage from './components/ProductSummaryImage/ProductImage'

export default ProductImage

```


[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/ProductSummary/ProductSummaryBrand.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummaryBrand
```


[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/ProductSummary/ProductSummaryPrice.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummaryPrice

```


[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/ProductSummary/ProductSummaryLegacy.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import ProductSummaryLegacy from './legacy'

export default ProductSummaryLegacy

```


[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/ProductSummary/ProductSummaryDescription.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummaryDescription

```


[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/ProductSummary/ProductSummaryContext.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummaryContext

```


[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/ProductSummary/useProductSummaryListState.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { useProductSummaryListState } from './ProductSummaryList'

export default useProductSummaryListState

```


[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/ProductSummary/ProductSummaryBuyButton.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummaryBuyButton

```


[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/ProductSummary/ProductSummaryAddToListButton.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

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

export default ProductSummaryAddToListButton

```


[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/ProductSummary/ProductSummaryList.js from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { useQuery } from 'react-apollo'
import ProductListContext from '../ProductListContext/ProductListContext'
import { ExtensionPoint, useTreePath } from '../../../../vtex.render-runtime'
import ListContextProvider from '../ListContext/ListContextProvider'
import useListContext from '../ListContext/useListContext'

import { mapCatalogProductToProductSummary } from './utils/normalize'
import ProductListEventCaller from './components/ProductListEventCaller'
import { loader } from 'graphql.macro'

const productSearchV2 = loader('../StoreResources/queries/productSearchV2.gql')

const ORDER_BY_OPTIONS = {
  RELEVANCE: {
    name: 'admin/editor.productSummaryList.orderType.relevance',
    value: 'OrderByScoreDESC',
  },
  TOP_SALE_DESC: {
    name: 'admin/editor.productSummaryList.orderType.sales',
    value: 'OrderByTopSaleDESC',
  },
  PRICE_DESC: {
    name: 'admin/editor.productSummaryList.orderType.priceDesc',
    value: 'OrderByPriceDESC',
  },
  PRICE_ASC: {
    name: 'admin/editor.productSummaryList.orderType.priceAsc',
    value: 'OrderByPriceASC',
  },
  NAME_ASC: {
    name: 'admin/editor.productSummaryList.orderType.nameAsc',
    value: 'OrderByNameASC',
  },
  NAME_DESC: {
    name: 'admin/editor.productSummaryList.orderType.nameDesc',
    value: 'OrderByNameDESC',
  },
  RELEASE_DATE_DESC: {
    name: 'admin/editor.productSummaryList.orderType.releaseDate',
    value: 'OrderByReleaseDateDESC',
  },
  BEST_DISCOUNT_DESC: {
    name: 'admin/editor.productSummaryList.orderType.discount',
    value: 'OrderByBestDiscountDESC',
  },
}
const parseFilters = ({ id, value }) => `specificationFilter_${id}:${value}`

function getOrdinationProp(attribute) {
  return Object.keys(ORDER_BY_OPTIONS).map(
    key => ORDER_BY_OPTIONS[key][attribute]
  )
}

const ProductSummaryList = ({
  children,
  category = '',
  collection,
  hideUnavailableItems = false,
  orderBy = ORDER_BY_OPTIONS.TOP_SALE_DESC.value,
  specificationFilters = [],
  maxItems = 10,
  withFacets = false,
}) => {
  const { data } = useQuery(productSearchV2, {
    ssr: true,
    name: 'productList',
    variables: {
      category,
      ...(collection != null
        ? {
            collection,
          }
        : {}),
      specificationFilters: specificationFilters.map(parseFilters),
      orderBy,
      from: 0,
      to: maxItems - 1,
      hideUnavailableItems,
      withFacets,
    },
  })

  const { list } = useListContext()
  const { treePath } = useTreePath()

  const componentList =
    data.productSearch &&
    data.productSearch.products.map(product => {
      const normalizedProduct = mapCatalogProductToProductSummary(product)

      return (
        <ExtensionPoint
          id="product-summary"
          key={product.id}
          treePath={treePath}
          product={normalizedProduct}
        />
      )
    })

  const newListContextValue = list.concat(componentList)

  return (
    <ListContextProvider list={newListContextValue}>
      {children}
    </ListContextProvider>
  )
}

const EnhancedProductList = ({ children }) => {
  const { ProductListProvider } = ProductListContext

  return (
    <ProductListProvider>
      <ProductSummaryList>{children}</ProductSummaryList>
      <ProductListEventCaller />
    </ProductListProvider>
  )
}

EnhancedProductList.getSchema = () => ({
  title: 'admin/editor.productSummaryList.title',
  description: 'admin/editor.productSummaryList.description',
  type: 'object',
  properties: {
    category: {
      title: 'admin/editor.productSummaryList.category.title',
      description: 'admin/editor.productSummaryList.category.description',
      type: 'string',
      isLayout: false,
    },
    specificationFilters: {
      title: 'admin/editor.productSummaryList.specificationFilters.title',
      type: 'array',
      items: {
        title:
          'admin/editor.productSummaryList.specificationFilters.item.title',
        type: 'object',
        properties: {
          id: {
            type: 'string',
            title:
              'admin/editor.productSummaryList.specificationFilters.item.id.title',
          },
          value: {
            type: 'string',
            title:
              'admin/editor.productSummaryList.specificationFilters.item.value.title',
          },
        },
      },
    },
    collection: {
      title: 'admin/editor.productSummaryList.collection.title',
      type: 'number',
      isLayout: false,
    },
    orderBy: {
      title: 'admin/editor.productSummaryList.orderBy.title',
      type: 'string',
      enum: getOrdinationProp('value'),
      enumNames: getOrdinationProp('name'),
      default: ORDER_BY_OPTIONS.TOP_SALE_DESC.value,
      isLayout: false,
    },
    hideUnavailableItems: {
      title: 'admin/editor.productSummaryList.hideUnavailableItems',
      type: 'boolean',
      default: false,
      isLayout: false,
    },
    maxItems: {
      title: 'admin/editor.productSummaryList.maxItems.title',
      type: 'number',
      isLayout: false,
      default: 10,
    },
  },
})

export default EnhancedProductList

```


[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/ProductSummary/Column.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 = ['column']

const Column = ({ children }) => {
  const handles = useCssHandles(CSS_HANDLES)
  return <div className={`${handles.column} flex items-center`}>{children}</div>
}

export default Column

```


[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/Minicart/ProductList.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import OrderFormOrder from '../OrderManager/OrderForm'
const { useOrderForm } = OrderFormOrder
import OrderItems from '../OrderItems/OrderItems'
const { useOrderItems } = OrderItems
import { ExtensionPoint } from '../../../../vtex.render-runtime'
import { usePixel } from '../PixelContext/PixelContext'
import useCssHandles from '../CssHandles/useCssHandles'

import { mapCartItemToPixel } from './modules/pixelHelper'

interface Props {
  renderAsChildren: boolean
}

const CSS_HANDLES = ['minicartProductListContainer'] as const

const ProductList: FC<Props> = ({ renderAsChildren }) => {
  const {
    orderForm: { items },
  } = useOrderForm()
  const { updateQuantity, removeItem } = useOrderItems()
  const { push } = usePixel()
  const handles = useCssHandles(CSS_HANDLES)

  const handleQuantityChange = (
    uniqueId: string,
    quantity: number,
    item: OrderFormItem
  ) => {
    const adjustedItem = {
      ...mapCartItemToPixel(item),
      quantity,
    }

    push({
      event: 'addToCart',
      items: [adjustedItem],
    })
    updateQuantity({ uniqueId, quantity })
  }
  const handleRemove = (uniqueId: string, item: OrderFormItem) => {
    const adjustedItem = mapCartItemToPixel(item)
    push({
      event: 'removeFromCart',
      items: [adjustedItem],
    })
    removeItem({ uniqueId })
  }

  return (
    <div
      /*
        This prevents an interaction with the quantity selector
        inside of a product in the ProductList to bubble up a
        mouseleave event to the Popup component, which would result
        in the minicart being closed (when openOnHover = true).
      */
      onMouseLeave={e => e.stopPropagation()}
      className={`${handles.minicartProductListContainer} ${
        renderAsChildren ? 'w-100 h-100' : ''
      } overflow-y-auto ph4 ph6-l`}
    >
      <ExtensionPoint
        id="product-list"
        items={items}
        onQuantityChange={handleQuantityChange}
        onRemove={handleRemove}
      />
    </div>
  )
}

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/Minicart/MinicartContext.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { createContext, useReducer, useContext, FC } from 'react'
import useDevice from '../DeviceDetector/useDevice'

interface OpenMinicartAction {
  type: 'OPEN_MINICART'
}
interface CloseMinicartAction {
  type: 'CLOSE_MINICART'
}
interface SetOpenBehaviorAction {
  type: 'SET_OPEN_BEHAVIOR'
  value: 'click' | 'hover'
}

interface State {
  variation: MinicartVariationType
  open: boolean
  hasBeenOpened: boolean
  /** Controls the minicart opening behavior */
  openBehavior: 'click' | 'hover'
  /** Value provided by the user to openOnHover prop */
  openOnHoverProp: boolean
}

interface Props {
  openOnHover: boolean
  variation: MinicartVariationType
}

type Action = OpenMinicartAction | CloseMinicartAction | SetOpenBehaviorAction
type Dispatch = (action: Action) => void

const MinicartStateContext = createContext<State | undefined>(undefined)
const MinicartDispatchContext = createContext<Dispatch | undefined>(undefined)

function minicartContextReducer(state: State, action: Action): State {
  switch (action.type) {
    case 'OPEN_MINICART':
      return {
        ...state,
        open: true,
        hasBeenOpened: true,
      }
    case 'CLOSE_MINICART':
      return {
        ...state,
        open: false,
      }
    case 'SET_OPEN_BEHAVIOR':
      return {
        ...state,
        openBehavior: action.value,
      }
    default:
      return state
  }
}

const MinicartContextProvider: FC<Props> = ({
  variation = 'drawer',
  openOnHover: openOnHoverProp = false,
  children,
}) => {
  const { isMobile } = useDevice()

  // This prevents a popup minicart from being used on a mobile device
  const resolvedVariation =
    isMobile || (window && window.innerWidth <= 480) ? 'drawer' : variation

  const [state, dispatch] = useReducer(minicartContextReducer, {
    variation: resolvedVariation,
    open: false,
    hasBeenOpened: false,
    openOnHoverProp,
    openBehavior:
      resolvedVariation === 'popup' && openOnHoverProp ? 'hover' : 'click',
  })

  return (
    <MinicartStateContext.Provider value={state}>
      <MinicartDispatchContext.Provider value={dispatch}>
        {children}
      </MinicartDispatchContext.Provider>
    </MinicartStateContext.Provider>
  )
}

function useMinicartState() {
  const context = useContext(MinicartStateContext)
  if (context === undefined) {
    throw new Error(
      'useMinicartState must be used within a MinicartContextProvider'
    )
  }
  return context
}

function useMinicartDispatch() {
  const context = useContext(MinicartDispatchContext)

  if (context === undefined) {
    throw new Error(
      'useMinicartDispatch must be used within a MinicartContextProvider'
    )
  }
  return context
}

export { MinicartContextProvider, useMinicartDispatch, useMinicartState }

```


[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/Minicart/styles.css from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```css
.drawerStyles {
  height: 100%;
}

.popupStyles {
  max-height: 600px;
}

.minicartEmptyStateContainerDefault {
  width: 340px;
}

.minicartQuantityBadgeDefault {
  top: -0.7rem;
  right: -0.8rem;
}

.popupBoxPosition {
  right: -40px;
  width: 364px;
  top: 100%;
}

.popupArrowUp {
  right: 7px;
}
```


[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/Minicart/Minicart.tsx from the store-on-localhost VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import useCssHandles from '../CssHandles/useCssHandles'
import CheckoutUtils from '../CheckoutResources/Utils'
const { useCheckoutURL } = CheckoutUtils
import OrderFormOrder from '../OrderManager/OrderForm'
const { useOrderForm } = OrderFormOrder

import MinicartIconButton from './components/MinicartIconButton'
import DrawerMode from './components/DrawerMode'
import { MinicartContextProvider, useMinicartState } from './MinicartContext'
import PopupMode from './components/Popup'
import useCartIdPixel from './modules/useCartIdPixel'

const CSS_HANDLES = ['minicartWrapperContainer', 'minicartContainer'] as const

const Minicart: FC<MinicartProps> = ({
  maxDrawerWidth = 400,
  drawerSlideDirection = 'rightToLeft',
  linkVariationUrl,
  children,
}) => {
  const handles = useCssHandles(CSS_HANDLES)
  const { variation } = useMinicartState()
  const { url: checkoutUrl } = useCheckoutURL()

  if (variation === 'link') {
    return (
      <aside
        className={`${handles.minicartWrapperContainer} relative fr flex items-center`}
      >
        <div className={`${handles.minicartContainer} flex flex-column`}>
          <a href={linkVariationUrl || checkoutUrl}>{MinicartIconButton}</a>
        </div>
      </aside>
    )
  }

  return (
    <aside
      className={`${handles.minicartWrapperContainer} relative fr flex items-center`}
    >
      <div className={`${handles.minicartContainer} flex flex-column`}>
        {variation === 'drawer' ? (
          <DrawerMode
            maxDrawerWidth={maxDrawerWidth}
            drawerSlideDirection={drawerSlideDirection}
          >
            {children}
          </DrawerMode>
        ) : (
          <PopupMode>{children}</PopupMode>
        )}
      </div>
    </aside>
  )
}

const CartIdPixel = () => {
  const { orderForm, loading }: OrderFormContext = useOrderForm()

  const orderFormId = !loading && orderForm ? orderForm.id : undefined
  useCartIdPixel(orderFormId)

  return null
}

const EnhancedMinicart = (props: MinicartProps) => (
  <MinicartContextProvider
    variation={props.variation}
    openOnHover={props.openOnHover}
  >
    <CartIdPixel />
    <Minicart {...props} />
  </MinicartContextProvider>
)

export default EnhancedMinicart

```