[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 category-menu/messages/ar.json from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/editor.category-menu.departments.items.id": "معرف القسم",
  "admin/editor.category-menu.departments.items.title": "القسم 1",
  "admin/editor.category-menu.description": "قائمة تظهر لائحة الفئات المتاحة في المتجر",
  "admin/editor.category-menu.disposition-type.center": "متوسط",
  "admin/editor.category-menu.disposition-type.left": "اليسار",
  "admin/editor.category-menu.disposition-type.right": "اليمين",
  "admin/editor.category-menu.disposition-type.title": "موضع القائمة",
  "admin/editor.category-menu.show-departments-category.title": "إظهار فئة الأقسام",
  "admin/editor.category-menu.show-subcategories.title": "إظهار الفئات الفرعية",
  "admin/editor.category-menu.sort-subcategories.title": "فرز الفئات الفرعية",
  "admin/editor.category-menu.sort-type.default": "العنوان الرئيسي",
  "admin/editor.category-menu.sort-type.name": "الاسم",
  "admin/editor.category-menu.title": "قائمة الفئة",
  "store/category-menu.all-category.title": "شاهد الكل",
  "store/category-menu.departments.title": "الأقسام"
}

```


[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 category-menu/docs/README.md from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```markdown
📢 Use this project, [contribute](https://github.com/vtex-apps/category-menu) to it or open issues to help evolve it using [Store Discussion](https://github.com/vtex-apps/store-discussion).

# Category Menu

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

The Category Menu is a store component that displays a list of departments in a configurable menu layout. It helps organize and present categories and subcategories to improve navigation.

![category-menu](https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/vtex-menu-0.png)

## Configuration

1. Add the app to your store theme's dependencies in the `manifest.json`.

```json
  dependencies: {
    "vtex.category-menu": "2.x"
  }
```

2. Add the `category-menu` block to your store theme.

```json
{
  "category-menu": {
    "props": {
      "showAllDepartments": true,
      "showSubcategories": true,
      "menuDisposition": "center",
      "departments": [],
      "sortSubcategories": "name"
    }
  }
}
```

### `category-menu` props

| Prop name            | Type           | Description                                                                                | Default Value |
| -------------------- | -------------- | ----------------------------------------------------------------------------------------------- | ------------- |
| `showAllDepartments` | `Boolean`      | Shows all department categories in the menu                                                          | `true`        |
| `menuDisposition`    | `Enum`         | Indicates the menu's position on the screen. Possible values: `left`, `center`, `right` | `center`      |
| `showSubcategories`  | `Boolean`      | Defines if the subcategories will be displayed                                                  | `true`        |
| `departments`        | `Array(items)` | List of department `items` to be displayed on the menu                                         | `[]`          |
| `mobileMode`         | `Boolean`      | Renders the category menu in a sidebar if set to `true`                                     | `false`       |
| `sortSubcategories`  | `Enum`         | Determines how subcategories are sorted. Possible value: `name`                                  |               |

### `category-menu` items

| Prop name | Type     | Description                                   |
| --------- | -------- | --------------------------------------------- |
| `id`      | `Number` | The department ID to be displayed on the menu |

## Customization

In order to apply CSS customizations in this and other blocks, follow the instructions on [Using CSS Handles for store customization](https://vtex.io/docs/recipes/style/using-css-handles-for-store-customization).

| CSS Handles                 |
| --------------------------- |
| `container`                 |
| `departmentLink`            |
| `departmentList`            |
| `firstLevelLink`            |
| `firstLevelLinkContainer`   |
| `firstLevelList`            |
| `itemContainer`             |
| `itemContainer--category`   |
| `itemContainer--department` |
| `menuContainer`             |
| `secondLevelLink`           |
| `secondLevelLinkContainer`  |
| `secondLevelList`           |
| `section--category`         |
| `section--department`       |
| `sidebar`                   |
| `sidebarContainer`          |
| `sidebarContent`            |
| `sidebarHeader`             |
| `sidebarItem`               |
| `sidebarItemContainer`      |
| `sidebarOpen`               |
| `sidebarScrim`              |
| `submenuItem`               |
| `submenuList`               |

<!-- DOCS-IGNORE:start -->
## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tr>
    <td align="center"><a href="https://github.com/khrizzcristian"><img src="https://avatars.githubusercontent.com/u/43498488?v=4?s=100" width="100px;" alt=""/><br /><sub><b>khrizzcristian</b></sub></a><br /><a href="https://github.com/vtex-apps/category-menu/commits?author=khrizzcristian" title="Code">💻</a></td>
  </tr>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!
<!-- DOCS-IGNORE:end -->

```


[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 category-menu/react/index.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import PropTypes from 'prop-types'
import React, { Fragment, useState } from 'react'
import { graphql } from 'react-apollo'
import { injectIntl, intlShape } from 'react-intl'
import { IconMenu } from 'vtex.store-icons'
import { useRuntime } from 'vtex.render-runtime'
import { compose, path } from 'ramda'
import classNames from 'classnames'
import { Container } from 'vtex.store-components'

import CategoryItem from './components/CategoryItem'
import SideBar from './components/SideBar'
import { categoryPropType } from './propTypes'
import getCategories from './queries/categoriesQuery.gql'

import styles from './categoryMenu.css'
import categoryMenuPosition, {
  getMenuPositionNames,
  getMenuPositionValues,
} from './utils/categoryMenuPosition'
import sortSubcategoriesItems, {
  getSortSubcategoriesNames,
  getSortSubcategoriesValues,
} from './utils/sortSubcategoriesItems'

const DEFAULT_SUBCATEGORIES_LEVELS = 1

/**
 * Component that represents the menu containing the categories of the store
 */
const CategoryMenu = ({
  mobileMode = false,
  showAllDepartments = true,
  showSubcategories = true,
  menuPosition = categoryMenuPosition.DISPLAY_CENTER.value,
  sortSubcategories = sortSubcategoriesItems.SORT_DEFAULT.value,
  departments = [],
  data: { categories = [] },
  intl,
}) => {
  const runtime = useRuntime()
  const [sideBarVisible, setSidebarVisible] = useState(false)

  const handleSidebarToggle = () => {
    setSidebarVisible(prevVisible => !prevVisible)
  }

  const departmentsIds = departments.map(dept => dept.id)
  const departmentsSelected = categories.filter(category =>
    departmentsIds.includes(category.id)
  )

  const visibleDepartments =
    (departmentsSelected.length && departmentsSelected) || categories

  if (mobileMode) {
    return (
      <div className={`${styles.sidebarContainer} ${styles.mobile}`}>
        <SideBar
          visible={sideBarVisible}
          title={intl.formatMessage({
            id: 'store/category-menu.departments.title',
          })}
          departments={visibleDepartments}
          onClose={handleSidebarToggle}
          showSubcategories={showSubcategories}
        />
        <div className="flex pa4 pointer" onClick={handleSidebarToggle}>
          <IconMenu size={20} />
        </div>
      </div>
    )
  }

  const pathName = path(['route', 'params', 'department'], runtime)

  const department = pathName ? pathName : ''

  const desktopClasses = classNames(
    `${styles.container} w-100 bg-base dn flex-m`,
    {
      'justify-start': menuPosition === categoryMenuPosition.DISPLAY_LEFT.value,
      'justify-end': menuPosition === categoryMenuPosition.DISPLAY_RIGHT.value,
      'justify-center':
        menuPosition === categoryMenuPosition.DISPLAY_CENTER.value,
    }
  )

  return (
    <nav className={desktopClasses}>
      <Container
        className={`${styles['section--department']} justify-center flex`}
      >
        <ul
          className={`${styles.departmentList} pa0 list ma0 flex flex-wrap flex-row t-action overflow-hidden h3`}
        >
          {showAllDepartments && (
            <CategoryItem
              noRedirect
              menuPosition={menuPosition}
              subcategoryLevels={
                DEFAULT_SUBCATEGORIES_LEVELS + showSubcategories
              }
              sortSubcategories={sortSubcategories}
              category={{
                children: categories,
                name: intl.formatMessage({
                  id: 'store/category-menu.departments.title',
                }),
              }}
            />
          )}
          {visibleDepartments.map(category => (
            <Fragment key={category.id}>
              <CategoryItem
                menuPosition={menuPosition}
                category={category}
                subcategoryLevels={
                  DEFAULT_SUBCATEGORIES_LEVELS + showSubcategories
                }
                isCategorySelected={department === category.slug}
                sortSubcategories={sortSubcategories}
              />
            </Fragment>
          ))}
        </ul>
      </Container>
    </nav>
  )
}

CategoryMenu.propTypes = {
  /** Categories query data */
  data: PropTypes.shape({
    loading: PropTypes.bool.isRequired,
    categories: PropTypes.arrayOf(categoryPropType),
  }),
  /** Set mobile mode */
  mobileMode: PropTypes.bool,
  /** Whether to show the departments category or not */
  showAllDepartments: PropTypes.bool,
  /** Whether to show subcategories or not */
  showSubcategories: PropTypes.bool,
  /** Defines the position of the category menu */
  menuPosition: PropTypes.oneOf(getMenuPositionValues()),
  /** Intl */
  intl: intlShape,
  /** Departments to be shown in the desktop mode. */
  departments: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number,
    })
  ),
  sortSubcategories: PropTypes.oneOf(getSortSubcategoriesValues()),
}

CategoryMenu.schema = {
  title: 'admin/editor.category-menu.title',
  description: 'admin/editor.category-menu.description',
  type: 'object',
  properties: {
    showAllDepartments: {
      type: 'boolean',
      title: 'admin/editor.category-menu.show-departments-category.title',
      default: true,
    },
    menuPosition: {
      title: 'admin/editor.category-menu.disposition-type.title',
      type: 'string',
      enum: getMenuPositionValues(),
      enumNames: getMenuPositionNames(),
      default: categoryMenuPosition.DISPLAY_CENTER.value,
      isLayout: true,
    },
    showSubcategories: {
      type: 'boolean',
      title: 'admin/editor.category-menu.show-subcategories.title',
      default: true,
    },
    sortSubcategories: {
      title: 'admin/editor.category-menu.sort-subcategories.title',
      type: 'string',
      enum: getSortSubcategoriesValues(),
      enumNames: getSortSubcategoriesNames(),
      default: sortSubcategoriesItems.SORT_DEFAULT.value,
    },
    departments: {
      title: 'store/category-menu.departments.title',
      type: 'array',
      minItems: 0,
      items: {
        title: 'admin/editor.category-menu.departments.items.title',
        type: 'object',
        properties: {
          id: {
            title: 'admin/editor.category-menu.departments.items.id',
            type: 'number',
          },
        },
      },
    },
  },
}

export default compose(
  graphql(getCategories),
  injectIntl
)(CategoryMenu)

```


[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 category-menu/react/categoryMenu.css from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```css
.itemContainer {
  max-height: 21.875rem;
}
.itemContainer--department {}
.itemContainer--category {}

.animation {
  left: -0.5rem;
}

@media only screen and (max-width: 40rem) {
  body.sidebarOpen {
      overflow-y: hidden;
  }
}

.container {}

.section--department {}
.section--category {}

.departmentList {}
.departmentLink {}

.firstLevelList {}
.firstLevelLinkContainer {}
.firstLevelLink {}

.secondLevelList {}
.secondLevelLinkContainer {}
.secondLevelLink {}

.submenuList {}
.submenuItem {}

.sidebarOpen {}

.sidebarScrim {}

.sidebar {}

.sidebarHeader {}

.sidebarContent {}

.sidebarItem {}

.sidebarContainer {}

.menuContainer {}

.sidebarItemContainer {}

```


[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 category-menu/react/package.json from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.category-menu",
  "version": "2.18.1",
  "scripts": {
    "pretest": "yarn",
    "test": "vtex-test-tools test",
    "lint": "eslint --ext js,jsx,ts,tsx ."
  },
  "dependencies": {
    "apollo-cache-inmemory": "^1.6.3",
    "classnames": "^2.2.6",
    "graphql": "^14.0.2",
    "jsdom": "^11.8.0",
    "ramda": "^0.26.1",
    "react-apollo": "^2.5.8",
    "react-intl": "^2.4.0"
  },
  "devDependencies": {
    "@types/classnames": "^2.2.9",
    "@types/jest": "^24.0.18",
    "@vtex/test-tools": "^0.1.2",
    "@vtex/tsconfig": "^0.1.1",
    "apollo-client": "^2.5.1"
  },
  "vtexTestTools": {
    "defaultLocale": "en"
  }
}

```


[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 category-menu/react/propTypes.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

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

function lazyFunction(f) {
  return function() {
    return f.apply(this, arguments)
  }
}

export const categoryPropType = PropTypes.shape({
  id: PropTypes.number.isRequired,
  name: PropTypes.string.isRequired,
  slug: PropTypes.string.isRequired,
  children: PropTypes.arrayOf(lazyFunction(() => categoryPropType)),
})

export const categoryItemShape = PropTypes.shape({
  name: PropTypes.string.isRequired,
  slug: PropTypes.string,
  children: PropTypes.arrayOf(lazyFunction(() => categoryPropType)),
})

```


[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 category-menu/react/setupTests.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import { JSDOM } from 'jsdom'

const jsdom = new JSDOM('<!doctype html><html><body></body></html>')

global.window = jsdom.window
global.document = window.document

Enzyme.configure({ adapter: new Adapter() })

```


[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 category-menu/store/interfaces.json from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "category-menu": {
    "component": "index"
  }
}
```


[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 category-menu/react/queries/categoriesQuery.gql from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```graphql
query {
  categories(treeLevel: 2) {
    id
    name
    href
    slug
    hasChildren
    children {
      id
      name
      href
      slug
      hasChildren
      children {
        id
        name
        href
        slug
      }
    }
  }
}

```


[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 category-menu/react/utils/categoryMenuPosition.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { values, pluck } from 'ramda'

const categoryMenuPosition = {
  DISPLAY_CENTER: {
    name: 'admin/editor.category-menu.disposition-type.center',
    value: 'center',
  },
  DISPLAY_LEFT: {
    name: 'admin/editor.category-menu.disposition-type.left',
    value: 'left',
  },
  DISPLAY_RIGHT: {
    name: 'admin/editor.category-menu.disposition-type.right',
    value: 'right',
  },
}

export function getMenuPositionNames() {
  return pluck('name', values(categoryMenuPosition))
}

export function getMenuPositionValues() {
  return pluck('value', values(categoryMenuPosition))
}

export default categoryMenuPosition

```


[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 category-menu/react/utils/sortSubcategoriesItems.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { values, pluck } from 'ramda'

const sortSubcategoriesItems = {
  SORT_DEFAULT: {
    name: 'admin/editor.category-menu.sort-type.default',
    value: '',
  },
  SORT_NAME: {
    name: 'admin/editor.category-menu.sort-type.name',
    value: 'name',
  },
}

export function getSortSubcategoriesNames() {
  return pluck('name', values(sortSubcategoriesItems))
}

export function getSortSubcategoriesValues() {
  return pluck('value', values(sortSubcategoriesItems))
}

export default sortSubcategoriesItems

```


[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 category-menu/react/components/SideBarItem.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { useState, Fragment } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { FormattedMessage } from 'react-intl'

import { useRuntime } from 'vtex.render-runtime'
import { IconMinus, IconPlus } from 'vtex.store-icons'

import styles from '../categoryMenu.css'

const SideBarItem = ({
  treeLevel = 1,
  item: { children },
  showSubcategories,
  onClose,
  linkValues,
  item,
}) => {
  const runtime = useRuntime()
  const [open, setOpen] = useState(false)

  const subCategoriesVisible =
    showSubcategories && children && children.length > 0

  const navigateToPage = () => {
    const [department, category, subcategory] = linkValues
    const params = { department }

    if (category) params.category = category
    if (subcategory) params.subcategory = subcategory

    const page = category
      ? subcategory
        ? 'store.search#subcategory'
        : 'store.search#category'
      : 'store.search#department'

    runtime.navigate({
      page,
      params,
      fallbackToWindowLocation: false,
    })
    onClose()
  }

  const handleItemClick = () => {
    if (subCategoriesVisible) {
      setOpen(prevOpen => !prevOpen)
    } else {
      navigateToPage()
    }
  }

  const sideBarContainerClasses = classNames(
    styles.sidebarItemContainer,
    'flex justify-between items-center pa5 pointer list ma0'
  )
  const sideBarItemTitleClasses = classNames('', {
    't-body lh-solid': treeLevel === 1,
  })

  const sideBarSpanClasses = classNames(
    treeLevel === 1 ? 'c-on-base' : 'c-muted-3'
  )

  const sideBarItemClasses = classNames(`${styles.sidebarItem} list pa0 ma0`, {
    'c-muted-2 t-body pl4': treeLevel > 1,
    'c-on-base': treeLevel === 1,
  })

  return (
    <ul className={sideBarItemClasses}>
      <li className={sideBarContainerClasses} onClick={handleItemClick}>
        <span className={sideBarItemTitleClasses}>{item.name}</span>
        {subCategoriesVisible && (
          <span className={sideBarSpanClasses}>
            {open ? <IconMinus size={16} /> : <IconPlus size={16} />}
          </span>
        )}
      </li>
      {subCategoriesVisible && open && (
        <>
          <li
            className="pa5 pointer t-body c-muted-2 ma0 list"
            onClick={navigateToPage}
          >
            <FormattedMessage id="store/category-menu.all-category.title">
              {txt => <span className="pl4">{txt}</span>}
            </FormattedMessage>
          </li>
          {children.map(child => (
            <li key={child.id} className="list ma0 pa0">
              <SideBarItem
                showSubcategories={showSubcategories}
                item={child}
                linkValues={[...linkValues, child.slug]}
                onClose={onClose}
                treeLevel={treeLevel + 1}
                runtime={runtime}
              />
            </li>
          ))}
        </>
      )}
    </ul>
  )
}

SideBarItem.propTypes = {
  /** Sidebar's item. */
  item: PropTypes.object.isRequired,
  /** Link values to create the redirect. */
  linkValues: PropTypes.arrayOf(PropTypes.string).isRequired,
  /** Closes sidebar. */
  onClose: PropTypes.func.isRequired,
  /** Runtime context. */
  runtime: PropTypes.shape({
    navigate: PropTypes.func,
  }),
  /** Tree level. */
  treeLevel: PropTypes.number,
  /** Whether to show subcategories or not */
  showSubcategories: PropTypes.bool,
}

export default SideBarItem

```


[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 category-menu/react/components/CategoryItem.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { useState, useRef } from 'react'
import { Link } from 'vtex.render-runtime'
import PropTypes from 'prop-types'
import { categoryItemShape } from '../propTypes'

import ItemContainer from './ItemContainer'
import classNames from 'classnames'
import styles from '../categoryMenu.css'
import categoryMenuPosition, {
  getMenuPositionValues,
} from '../utils/categoryMenuPosition'
import { getSortSubcategoriesValues } from '../utils/sortSubcategoriesItems'

/**
 * Component that represents a single category displayed in the menu, also displays
 * the subcategories, if the provided category has them
 */
const CategoryItem = ({
  category,
  subcategoryLevels,
  menuPosition,
  category: { name, slug },
  noRedirect,
  isCategorySelected,
  sortSubcategories,
}) => {
  const [isHover, setHover] = useState(false)
  const itemRef = useRef(null)

  const handleCloseMenu = () => {
    setHover(false)
  }

  const categoryClasses = classNames(
    styles.departmentLink,
    'w-100 pv5 no-underline t-small outline-0 db tc link truncate bb bw1 c-muted-1',
    {
      'b--transparent': !isHover && !isCategorySelected,
      'b--action-primary pointer': isHover || isCategorySelected,
      mr8: menuPosition === categoryMenuPosition.DISPLAY_LEFT.value,
      ml8: menuPosition === categoryMenuPosition.DISPLAY_RIGHT.value,
      mh6: menuPosition === categoryMenuPosition.DISPLAY_CENTER.value,
    }
  )

  const containerStyle = {
    top:
      itemRef.current &&
      itemRef.current.offsetTop + itemRef.current.clientHeight,
    display: isHover ? 'flex' : 'none',
  }

  return (
    <li
      className={`${styles.itemContainer} ${
        styles['itemContainer--department']
      } flex items-center db list`}
      ref={itemRef}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={handleCloseMenu}
    >
      {noRedirect ? (
        <span className={categoryClasses}>{name}</span>
      ) : (
        <Link
          onClick={handleCloseMenu}
          page="store.search#department"
          params={{ department: slug }}
          className={categoryClasses}
        >
          {name}
        </Link>
      )}

      {subcategoryLevels > 0 && category.children.length > 0 && (
        <ItemContainer
          menuPosition={menuPosition}
          containerStyle={containerStyle}
          categories={category.children}
          parentSlug={category.slug}
          onCloseMenu={handleCloseMenu}
          showSecondLevel={subcategoryLevels === 2}
          sortSubcategories={sortSubcategories}
        />
      )}
    </li>
  )
}

CategoryItem.propTypes = {
  /** Category to be displayed */
  category: categoryItemShape.isRequired,
  /** Set use of Link component */
  noRedirect: PropTypes.bool,
  /** Number of subcategory levels */
  subcategoryLevels: PropTypes.oneOf([0, 1, 2]),
  /** Defines the position of the category menu */
  menuPosition: PropTypes.oneOf(getMenuPositionValues()),
  /** Menu category selection */
  isCategorySelected: PropTypes.bool,
  sortSubcategories: PropTypes.oneOf(getSortSubcategoriesValues()),
}

export default CategoryItem

```


[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 category-menu/react/components/SideBar.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Fragment, useEffect } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import { Animation } from 'vtex.store-components'
import { IconClose } from 'vtex.store-icons'

import SideBarItem from './SideBarItem'
import styles from '../categoryMenu.css'

const OPEN_SIDEBAR_CLASS = styles.sidebarOpen

const SideBar = ({
  title = 'Departments',
  visible,
  onClose = () => {},
  showSubcategories,
  departments = [],
}) => {
  useEffect(() => {
    if (visible) {
      document.body.classList.add(OPEN_SIDEBAR_CLASS)

      return () => document.body.classList.remove(OPEN_SIDEBAR_CLASS)
    } else {
      document.body.classList.remove(OPEN_SIDEBAR_CLASS)
    }
  }, [visible])

  const scrimClasses = classNames(
    styles.sidebarScrim,
    'fixed dim bg-base--inverted top-0 z-1 vw-100 vh-100 o-40',
    {
      dn: !visible,
    }
  )

  return (
    <Fragment>
      <div className={scrimClasses} onClick={onClose} />
      <Animation
        isActive={visible}
        type="drawerRight"
        className={`${styles.animation} fixed w-80 top-0 z-max`}
      >
        <aside
          className={`${styles.sidebar} w-100 bg-base z-max vh-100 shadow-5 overflow-scroll`}
        >
          <div
            className={`${styles.sidebarHeader} flex justify-between items-center pa5 pointer`}
            onClick={onClose}
          >
            <IconClose size={24} activeClassName="c-muted-1" />
          </div>
          <ul className={`${styles.sidebarContent} pb7 list ma0 pa0`}>
            {departments.map(department => (
              <li key={department.id} className="list ma0 pa0">
                <SideBarItem
                  item={department}
                  linkValues={[department.slug]}
                  onClose={onClose}
                  showSubcategories={showSubcategories}
                />
              </li>
            ))}
          </ul>
        </aside>
      </Animation>
    </Fragment>
  )
}

SideBar.propTypes = {
  /** Sidebar's departments. */
  departments: PropTypes.arrayOf(PropTypes.object),
  /** Closes sidebar. */
  onClose: PropTypes.func,
  /** Sidebar's visibility. */
  visible: PropTypes.bool,
  /** Whether to show subcategories or not */
  showSubcategories: PropTypes.bool,
}

export default SideBar

```


[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 category-menu/react/components/ItemContainer.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { Link } from 'vtex.render-runtime'
import { categoryPropType } from '../propTypes'
import classNames from 'classnames'
import { Container } from 'vtex.store-components'

import PropTypes from 'prop-types'
import styles from '../categoryMenu.css'
import categoryMenuPosition, {
  getMenuPositionValues,
} from '../utils/categoryMenuPosition'
import sortSubcategoriesItems from '../utils/sortSubcategoriesItems'

const getLinkParams = (parentSlug, item) => {
  const params = {
    department: parentSlug || item.slug,
  }

  if (parentSlug) params.category = item.slug

  return params
}

/**
 * Component responsible dor rendering an array of categories and its respective subcategories
 */
const ItemContainer = ({
  containerStyle,
  categories,
  parentSlug,
  menuPosition,
  onCloseMenu,
  showSecondLevel,
  sortSubcategories,
}) => {
  const shouldRenderSecondLevel = category => {
    const { children } = category

    return children && children.length > 0 && showSecondLevel
  }

  const containerClasses = classNames(
    styles.submenuList,
    'w-100 flex flex-wrap pa0 list mw9',
    {
      'justify-start': menuPosition === categoryMenuPosition.DISPLAY_LEFT.value,
      'justify-end': menuPosition === categoryMenuPosition.DISPLAY_RIGHT.value,
      'justify-center':
        menuPosition === categoryMenuPosition.DISPLAY_CENTER.value,
    }
  )

  const columnItemClasses = classNames(styles.firstLevelList, {
    'pl0 pr7': menuPosition === categoryMenuPosition.DISPLAY_LEFT.value,
    'pr0 pl7': menuPosition === categoryMenuPosition.DISPLAY_RIGHT.value,
  })

  const firstLevelLinkClasses = classNames(
    styles.firstLevelLink,
    'db pv4 link no-underline outline-0 tl t-small truncate c-on-base underline-hover',
    {
      pr4: menuPosition === categoryMenuPosition.DISPLAY_LEFT.value,
      pl4: menuPosition === categoryMenuPosition.DISPLAY_RIGHT.value,
      ph4: menuPosition === categoryMenuPosition.DISPLAY_CENTER.value,
    }
  )

  const secondLevelLinkClasses = classNames(
    styles.secondLevelLink,
    'db pv3 no-underline outline-0 tl link t-small truncate c-muted-1 underline-hover',
    {
      pr5: menuPosition === categoryMenuPosition.DISPLAY_LEFT.value,
      pl5: menuPosition === categoryMenuPosition.DISPLAY_RIGHT.value,
      ph5: menuPosition === categoryMenuPosition.DISPLAY_CENTER.value,
    }
  )

  return (
    <div
      className={`${styles.itemContainer} ${
        styles['itemContainer--category']
      } absolute w-100 left-0 bg-base pb2 bw1 bb b--muted-3`}
      style={containerStyle}
    >
      <Container
        className={`${styles['section--category']} justify-center w-100 flex`}
      >
        <ul className={containerClasses}>
          {categories
            .sort((a, b) => {
              if (
                sortSubcategories === sortSubcategoriesItems.SORT_NAME.value
              ) {
                return a.name > b.name ? 1 : -1
              }
              return 0
            })
            .map(category => (
              <li key={category.id} className={`${styles.submenuItem} dib`}>
                <ul className={columnItemClasses}>
                  <li className={`${styles.firstLevelLinkContainer} list pa0`}>
                    <Link
                      onClick={onCloseMenu}
                      page={
                        parentSlug
                          ? 'store.search#category'
                          : 'store.search#department'
                      }
                      className={firstLevelLinkClasses}
                      params={getLinkParams(parentSlug, category)}
                    >
                      {category.name}
                    </Link>
                  </li>

                  {shouldRenderSecondLevel(category) &&
                    category.children
                      .sort((a, b) => {
                        if (
                          sortSubcategories ===
                          sortSubcategoriesItems.SORT_NAME.value
                        ) {
                          return a.name > b.name ? 1 : -1
                        }
                        return 0
                      })
                      .map(subCategory => {
                        const params = {
                          department: parentSlug || category.slug,
                          category: parentSlug
                            ? category.slug
                            : subCategory.slug,
                        }
                        if (parentSlug) params.subcategory = subCategory.slug

                        return (
                          <li
                            key={subCategory.id}
                            className={`${styles.secondLevelLinkContainer} list pa0`}
                          >
                            <Link
                              onClick={onCloseMenu}
                              page={
                                parentSlug
                                  ? 'store.search#subcategory'
                                  : 'store.search#category'
                              }
                              className={secondLevelLinkClasses}
                              params={params}
                            >
                              {subCategory.name}
                            </Link>
                          </li>
                        )
                      })}
                </ul>
              </li>
            ))}
        </ul>
      </Container>
    </div>
  )
}

ItemContainer.propTypes = {
  /** Category to be displayed */
  categories: PropTypes.arrayOf(categoryPropType),
  /** Department slug */
  parentSlug: PropTypes.string,
  /** Close menu callback */
  onCloseMenu: PropTypes.func.isRequired,
  /** Whether to show second level links or not */
  showSecondLevel: PropTypes.bool,
  /** Defines the position of the category menu */
  menuPosition: PropTypes.oneOf(getMenuPositionValues()),
  /** Custom styles to item container */
  containerStyle: PropTypes.object,
  sortSubcategories: PropTypes.oneOf(getMenuPositionValues()),
}

export default ItemContainer

```


[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 category-menu/react/__tests__/SideBar.test.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { render } from '@vtex/test-tools/react'
import SideBar from '../components/SideBar'

describe('SideBar component', () => {
  const renderComponent = customProps => {
    return render(
      <SideBar
        departments={[]}
        onClose={() => {}}
        showSubcategories
        visible={false}
        {...customProps}
      />
    )
  }

  it('should be rendered', () => {
    expect(renderComponent()).toBeDefined()
  })

  it('should match snapshot', () => {
    expect(renderComponent({ visible: true }).asFragment()).toMatchSnapshot()
  })
})

```


[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 category-menu/react/__tests__/CategoryMenu.test.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { render, wait } from '@vtex/test-tools/react'
import CategoryMenu from '../index'
import categoriesQuery from '../queries/categoriesQuery.gql'

describe('CategoryMenu component', () => {
  const mockedCategories = [
    {
      id: 1,
      href: '#1',
      name: 'Category 1',
      slug: 'category-1',
      hasChildren: false,
      children: [],
    },
    {
      id: 2,
      href: '#2',
      name: 'Category 2',
      slug: 'category-2',
      hasChildren: false,
      children: [],
    },
    {
      id: 3,
      href: '#3',
      name: 'Category 3',
      slug: 'category-3',
      hasChildren: false,
      children: [],
    },
  ]

  const renderComponent = customProps => {
    const departments = mockedCategories.map(category => ({ id: category.id }))

    const mocks = [
      {
        request: {
          query: categoriesQuery,
        },
        result: {
          data: { categories: mockedCategories },
        },
      },
    ]

    return render(<CategoryMenu departments={departments} {...customProps} />, {
      graphql: { mocks },
    })
  }

  it('should be rendered', () => {
    expect(renderComponent()).toBeDefined()
  })

  it('should match snapshot', async () => {
    const { asFragment } = renderComponent()

    await wait(() => {})

    expect(asFragment()).toMatchSnapshot()
  })

  it("shouldn't be able to find a `Category 4` item", async () => {
    const element = renderComponent().queryByText(/Category 4/)

    await wait(() => expect(element).toBeNull())
  })
})

```


[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 category-menu/react/__tests__/CategoryItem.test.js from the category-menu VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { render } from '@vtex/test-tools/react'

import CategoryItem from '../components/CategoryItem'

describe('CategoryItem component', () => {
  let wrapper

  beforeEach(() => {
    const categoryMock = {
      id: 1,
      name: 'Category',
      slug: 'category',
      hasChildren: true,
      children: [
        {
          id: 2,
          name: 'Sub-category',
          slug: 'sub-category',
        },
      ],
    }

    wrapper = render(<CategoryItem category={categoryMock} />)
  })

  it('should have the correct href', () => {
    const element = wrapper.getByText(/CATEGORY/i)

    expect(element.href).toMatch(/\/category\/s$/i)
  })

  it('should match snapshot', () => {
    expect(wrapper.asFragment()).toMatchSnapshot()
  })
})

```


[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 amp-store/react/AmpProvider.tsx from the amp-store VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { Helmet } from 'react-helmet'
import { useRuntime } from 'vtex.render-runtime'
import * as Amp from 'react-amphtml'

const CONTENT_TYPE = 'text/html; charset=utf-8'
const META_ROBOTS = 'index, follow'

const joinKeywords = (keywords: string[]) => keywords && keywords.join(', ')

const AmpProvider: React.FC = ({ children }) => {
  const runtime = useRuntime()
  const {
    getSettings,
    culture: { country, locale, currency },
    route: { title: pageTitle, metaTags },
  } = runtime

  const storeSettings = getSettings('vtex.store')

  const {
    titleTag,
    metaTagDescription,
    metaTagKeywords,
    metaTagRobots,
    storeName,
  } = storeSettings

  const description = (metaTags && metaTags.description) || metaTagDescription
  const keywords =
    joinKeywords(metaTags && metaTags.keywords) || metaTagKeywords

  const title = pageTitle || titleTag

  return (
    <React.Fragment>
      <Helmet
        title={title}
        meta={[
          { name: 'description', content: description },
          { name: 'keywords', content: keywords },
          { name: 'copyright', content: storeName },
          { name: 'author', content: storeName },
          { name: 'country', content: country },
          { name: 'language', content: locale },
          { name: 'currency', content: currency },
          { name: 'robots', content: metaTagRobots || META_ROBOTS },
          { httpEquiv: 'Content-Type', content: CONTENT_TYPE },
        ].filter(meta => !!meta.content)}
      />
      <Amp.AmpState id="__RUNTIME__" specName="amp-state">
        {runtime}
      </Amp.AmpState>
      {children}
    </React.Fragment>
  )
}

export default AmpProvider

```


[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 amp-store/react/package.json from the amp-store VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "private": true,
  "dependencies": {
    "react": "^16.8.6",
    "react-amphtml": "^4.0.1",
    "react-dom": "^16.8.6",
    "react-helmet": "^5.2.1"
  },
  "devDependencies": {
    "@types/node": "^12.7.0",
    "@types/react": "^16.8.24",
    "@types/react-dom": "^16.8.5",
    "@types/react-helmet": "^5.0.9"
  },
  "version": "0.1.5"
}

```


[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 amp-store/store/interfaces.json from the amp-store VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "amp-store": {
    "component": "*",
    "before": ["header.full"],
    "after": ["footer"],
    "around": ["ampProvider"]
  },
  "amp-store.home": {},
  "ampProvider": {
    "component": "AmpProvider"
  }
}

```


[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 amp-store/store/routes.json from the amp-store VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "amp-store.home": {
    "path": "/amp/",
    "canonical": "/"
  }
}

```


[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 amp-store/react/typings/vtex.render-runtime.d.ts from the amp-store VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.render-runtime' {
  export function useRuntime(): 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 mkp-seller-auth/docs/README.md from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```markdown
# TODO - Document this app

# Service Example

A reference app implementing a VTEX IO service with HTTP route handlers.

![Service Example Architecture](https://user-images.githubusercontent.com/18706156/77381360-72489680-6d5c-11ea-9da8-f4f03b6c5f4c.jpg)

We use [**KoaJS**](https://koajs.com/) as the web framework, so you might want to get into that

We also use the [**node-vtex-api**](https://github.com/vtex/node-vtex-api), a VTEX set of utilities for Node services. You can import this package using NPM from `@vtex/api` (already imported on this project)

- Start from `node/index.ts` and follow the comments and imports :)

## Recipes

### Defining routes on _service.json_
```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 2,
  "minReplicas": 2,
  "maxReplicas": 4,
  "routes": {
    "status": {
      "path": "/_v/status/:code",
      "public": true
    }
  }
}
```

The `service.json` file that sits on the root of the `node` folder holds informations about this service, like the maximum timeout and number of replicas, what might be discontinued on the future, but also **sets its routes**.

Koa uses the [path-to-regexp](https://github.com/pillarjs/path-to-regexp) format for defining routes and, as seen on the example, we use the `:code` notation for declaring a **route param** named code, in this case. A HTTP request for `https://{{workspace}}--{{account}}.myvtex.com/_v/status/500` will match the route we've defined.

For cach _key_ on the `routes` object, there should be a **corresponding entry** on the exported Service object on `node/index.ts`, this will hook your code to a specific route.

### Access Control
You can also provide a `public` option for each route. If `true`, that resource will be reachable for everyone on the internet. If `false`, VTEX credentials will be requested as well.

Another way of controlling access to specific routes is using **ReBACs (Resource-based access)**, that supports more robust configuration. You can read more [on this document](https://docs.google.com/document/d/1ZxNHMFIXfXz3BgTN9xyrHL3V5dYz14wivYgQjRBZ6J8/edit#heading=h.z7pad3qd2qw7) (VTEX only).

#### Query String
For `?accepting=query-string`, you **don't need to declare anything**, as any query provided to the URL will already be available for you to use on the code as `ctx.query`, already parsed as an object, or `ctx.queryString`, taken directly from the URL as a string.

#### Route Params
Route Params will be available for you to use on the code as `ctx.vtex.params`, already parsed as an object.
For a path like `/_v/status/:code`, if you receive the request `/_v/status/200`, `ctx.vtex.params` will return `{ code: '200' }`

#### HTTP methods
When you define a route on the `service.json`, your NodeJS handlers for that route will be triggered  **on every HTTP method** (GET, POST, PUT...), so, if you need to handle them separately you need to implement a "sub-router". Fortunately, the _node-vtex-api_ provides a helper function `method`, exported from `@vtex/api`, to accomplish that behaviour. Instead of passing your handlers directly to the corresponding route on `index.ts`, you pass a `method` call passing **an object with the desired method as key and one handler as its corresponding value**. Check this example:
```typescript
import { method } from '@vtex/api'
...

export default new Service<Clients, State>({
  clients,
  routes: {
    status: method({
      GET: statusGetHandler,
      POST: statusPostHandler,
    }),
  },
})
```

### Throwing errors

When building a HTTP service, we should follow HTTP rules regarding data types, cache, authorization, and status code. Our example app sets a `ctx.status` value that will be used as a HTTP status code return value, but often we also want to give proper information about errors as well.

The **node-vtex-api** already exports a handful of **custom error classes** that can be used for that purpose, like the `NotFoundError`. You just need to throw them inside one of the the route handlers that the appropriate response will be sent to the server.

```typescript
import { UserInputError } from '@vtex/api'

export async function validate(ctx: Context, next: () => Promise<any>) {
  const { code } = ctx.vtex.route.params
  if (isNaN(code) || code < 100 || code > 600) {
    throw new UserInputError('Code must be a number between 100 and 600')
  }
...
```

You can check all the available errors [here](https://github.com/vtex/node-vtex-api/tree/fd6139349de4e68825b1074f1959dd8d0c8f4d5b/src/errors), but some are not useful for just-HTTP services. Check the most useful ones:

|Error Class | HTTP Code |
|--|:--:|
| `UserInputError` | 400 |
| `AuthenticationError` | 401 |
| `ForbiddenError` | 403 |
| `NotFoundError` | 404 |

You can also **create your custom error**, just see how it's done above ;)

### Reading a JSON body

When writing POST or PUT handlers, for example, often you need to have access to the **request body** that comes as a JSON format, which is not provided directly by the handler function.

For this, you have to use the [co-body](https://www.npmjs.com/package/co-body) package that will parse the request into a readable JSON object, used as below:
```typescript
import { json } from 'co-body'
export async function method(ctx: Context, next: () => Promise<any>) {
    const body = await json(ctx.req)
```

### Other example apps

We use Node services across all VTEX, and there are a lot inspiring examples. If you want to dive deeper on learning about this subject, don't miss those internal apps: [builder-hub](https://github.com/vtex/builder-hub) or [store-sitemap](https://github.com/vtex-apps/store-sitemap)

## Testing

`@vtex/test-tools` and `@types/jest` should be installed on `./node` package as `devDependencies`.

Run `vtex test` and [Jest](https://jestjs.io/) will do its thing.

Check the `node/__tests__/simple.test.ts` test case and also [Jest's Documentation](https://jestjs.io/docs/en/getting-started).

## Splunk Dashboard

We have an (for now, VTEX-only, internal) Splunk dashboard to show all metrics related to your app. You can find it [here](https://splunk7.vtex.com/en-US/app/vtex_colossus/node_app_metrics).

After linking this app and making some requests, you can select `vtex.service-example` and see the metrics for your app. **Don't forget to check the box Development, as you are linking your app in a development workspace**.

For convenience, the link for the current version: https://splunk7.vtex.com/en-US/app/vtex_colossus/node_app_metrics?form.time.earliest=-30m%40m&form.time.latest=%40m&form.picked_context=false&form.picked_region=aws-us-east-*&form.picked_service=vtex.service-example

```


[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 mkp-seller-auth/node/service.json from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 10000,
  "minReplicas": 2,
  "maxReplicas": 4,
  "workers": 1,
  "routes": {
    "healthcheck": {
      "path": "/mkp-seller-auth/v0/healthcheck",
      "public": true
    },
    "executeCall": {
      "path": "/mkp-seller-auth/v0/executeCall",
      "public": true
    }
  }
}

```


[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 mkp-seller-auth/node/package.json from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "co-body": "^6.0.0",
    "ramda": "^0.25.0",
    "atob": "^2.1.2"
  },
  "devDependencies": {
    "@types/co-body": "^0.0.3",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.0.0",
    "@types/ramda": "types/npm-ramda#dist",
    "@vtex/api": "6.45.12",
    "@vtex/test-tools": "^1.0.0",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "3.9.7",
    "@types/atob": "^2.1.2"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty"
  },
  "version": "0.2.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 mkp-seller-auth/node/index.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ClientsConfig, ServiceContext, RecorderState } from '@vtex/api'
import { LRUCache, method, Service } from '@vtex/api'

import { Clients } from './clients'
import { validateRequest } from './middlewares/validateRequest'
import { checkConfiguration } from './middlewares/checkConfiguration'
import { validateVtexIdclientAutCookie } from './middlewares/validateVtexIdclientAutCookie'
import { executeCall } from './middlewares/executeCall'
import { healthcheck } from './middlewares/healthcheck'

const TIMEOUT_MS = 6000

// Create a LRU memory cache for the Status client.
// The @vtex/api HttpClient respects Cache-Control headers and uses the provided cache.
const memoryCache = new LRUCache<string, any>({ max: 5000 })

metrics.trackCache('status', memoryCache)

// This is the configuration for clients available in `ctx.clients`.
const clients: ClientsConfig<Clients> = {
  // We pass our custom implementation of the clients bag, containing the Status client.
  implementation: Clients,
  options: {
    // All IO Clients will be initialized with these options, unless otherwise specified.
    default: {
      retries: 2,
      timeout: TIMEOUT_MS,
    },
    // This key will be merged with the default options and add this cache to our Status client.
    status: {
      memoryCache,
    },
  },
}

declare global {
  // We declare a global Context type just to avoid re-writing ServiceContext<Clients, State> in every handler and resolver
  type Context = ServiceContext<Clients, State>

  // The shape of our State object found in `ctx.state`. This is used as state bag to communicate between middlewares.
  interface State extends RecorderState {
    code: number
    params: any
    requestBody: any
    requestHeaders: any
    requesterTokenDetails: any
  }
}

// Export a service that defines route handlers and client options.
export default new Service({
  clients,
  routes: {
    healthcheck: method({
      GET: [healthcheck],
    }),
    executeCall: method({
      POST: [
        validateRequest,
        checkConfiguration,
        validateVtexIdclientAutCookie,
        executeCall,
      ],
    }),
  },
})

```


[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 mkp-seller-auth/node/clients/vtexid.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { JanusClient } from '@vtex/api'

export default class VtexID extends JanusClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super(context, {
      ...options,
      headers: {
        ...options?.headers,
        'x-vtex-user-agent': context.userAgent,
      },
    })
  }

  // https://developers.vtex.com/vtex-rest-api/reference/catalog-api-get-seller-list
  public async validate(token: string, account: string): Promise<any> {
    const url = `/api/vtexid/credential/validate?an=${account}`

    return this.http.post(url, { token }, { metric: 'vtexid-validate' })
  }
}

```


[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 mkp-seller-auth/node/clients/executeCall.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext, IOResponse } from '@vtex/api'
import { JanusClient } from '@vtex/api'

export default class ExecuteCall extends JanusClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super(context, {
      ...options,
      headers: {
        ...options?.headers,
        VtexIdclientAutCookie:
          context.adminUserAuthToken ?? context.authToken ?? '',
        'x-vtex-user-agent': context.userAgent,
      },
    })
  }

  public async get(url: string): Promise<IOResponse<string>> {
    return this.http.getRaw(url, {
      metric: 'mkp-seller-auth-get',
    })
  }

  public async post(url: string, body: any): Promise<IOResponse<string>> {
    return this.http.postRaw(url, body, {
      metric: 'mkp-seller-auth-post',
    })
  }

  public async put(url: string, body: any): Promise<IOResponse<string>> {
    return this.http.putRaw(url, body, {
      metric: 'mkp-seller-auth-put',
    })
  }
}

```


[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 mkp-seller-auth/node/clients/sellers.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { JanusClient } from '@vtex/api'

export default class Sellers extends JanusClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super(context, {
      ...options,
      headers: {
        ...options?.headers,
        VtexIdclientAutCookie:
          context.adminUserAuthToken ?? context.authToken ?? '',
        'x-vtex-user-agent': context.userAgent,
      },
    })
  }

  // https://developers.vtex.com/vtex-rest-api/reference/catalog-api-get-seller-list
  public async getSellerList(
    tradePolicy?: string,
    sellerType?: string,
    isBetterScope?: boolean
  ): Promise<any> {
    let url = `/api/catalog_system/pvt/seller/list?an=${this.context.account}`

    if (tradePolicy) {
      url += `&${tradePolicy}`
    }

    if (sellerType) {
      url += `&${sellerType}`
    }

    if (isBetterScope) {
      url += `&${isBetterScope}`
    }

    return this.http.getRaw(url, { metric: 'seller-list' })
  }
}

```


[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 mkp-seller-auth/node/clients/index.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { IOClients } from '@vtex/api'

import ExecuteCall from './executeCall'
import Sellers from './sellers'
import Affiliations from './affiliations'
import VtexID from './vtexid'

// Extend the default IOClients implementation with our own custom clients.
export class Clients extends IOClients {
  public get executeCallClient() {
    return this.getOrSet('executeCallClient', ExecuteCall)
  }

  public get vtexid() {
    return this.getOrSet('vtexid', VtexID)
  }

  public get sellers() {
    return this.getOrSet('sellers', Sellers)
  }

  public get affiliations() {
    return this.getOrSet('affiliations', Affiliations)
  }
}

```


[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 mkp-seller-auth/node/clients/affiliations.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { JanusClient } from '@vtex/api'

export default class Affiliations extends JanusClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super(context, {
      ...options,
      headers: {
        ...options?.headers,
        VtexIdclientAutCookie:
          context.adminUserAuthToken ?? context.authToken ?? '',
        'x-vtex-user-agent': context.userAgent,
      },
    })
  }

  // https://developers.vtex.com/vtex-rest-api/reference/affiliations
  public async getAffiliationsList(): Promise<any> {
    const url = `/api/fulfillment/pvt/affiliates`

    return this.http.getRaw(url, { metric: 'seller-list' })
  }
}

```


[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 mkp-seller-auth/node/middlewares/executeCall.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { UserInputError } from '@vtex/api'

export async function executeCall(ctx: Context, next: () => Promise<any>) {
  const {
    vtex: { logger },
    state: { requestBody },
    clients: { executeCallClient },
  } = ctx

  // console.info('executeCall Received requestHeaders:', requestHeaders)
  // console.info('executeCall Received requestBody:', requestBody)

  let response

  switch (requestBody.method) {
    case 'get':
      response = await executeCallClient.get(requestBody.url)
      break

    case 'post':
      response = await executeCallClient.post(requestBody.url, requestBody.body)
      break

    case 'put':
      response = await executeCallClient.put(requestBody.url, requestBody.body)
      break

    default:
      logger.error({
        message: 'Invalid body',
        data: {
          requestBody,
        },
      })
      throw new UserInputError('Invalid method. It must be get, post or put')
  }

  ctx.body = response.data
  ctx.status = response.status

  await next()
}

```


[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 mkp-seller-auth/node/middlewares/healthcheck.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function healthcheck(ctx: Context, next: () => Promise<any>) {
  ctx.status = 200
  ctx.body = { timestamp: Date.now() }

  await next()
}

```


[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 mkp-seller-auth/node/middlewares/validateRequest.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { json } from 'co-body'
import { UserInputError } from '@vtex/api'

export async function validateRequest(ctx: Context, next: () => Promise<any>) {
  const {
    vtex: {
      logger,
      route: { params },
    },
  } = ctx

  const body = await json(ctx.req)
  // console.info('validateRequest Received params:', params)
  // console.info('validateRequest Received body: ', body)

  if (body.accountType !== 'seller' && body.accountType !== 'marketplace') {
    logger.error({
      message: 'Invalid body',
      data: {
        body,
      },
    })
    throw new UserInputError(
      'Invalid accountType. It must be seller or marketplace'
    )
  }

  if (
    body.method !== 'get' &&
    body.method !== 'post' &&
    body.method !== 'put'
  ) {
    logger.error({
      message: 'Invalid body',
      data: {
        body,
      },
    })
    throw new UserInputError('Invalid method. It must be get, post or put')
  }

  ctx.state.params = params
  ctx.state.requestBody = body
  ctx.state.requestHeaders = ctx.headers

  // console.info('validateRequest passed')

  await next()
}

```


[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 mkp-seller-auth/node/middlewares/validateVtexIdclientAutCookie.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { AuthenticationError } from '@vtex/api'

export async function validateVtexIdclientAutCookie(
  ctx: Context,
  next: () => Promise<any>
) {
  const {
    vtex: { logger },
    state: { requestHeaders, requesterTokenDetails },
    clients: { vtexid },
  } = ctx

  const tokenValidation = await vtexid.validate(
    requestHeaders.requestervtexidclientautcookie,
    requesterTokenDetails.account
  )

  if (tokenValidation.authStatus !== 'Success') {
    logger.error({
      message: 'Invalid RequesterVtexIdclientAutCookie',
      data: {
        requesterTokenDetails,
      },
    })
    throw new AuthenticationError(
      'Invalid RequesterVtexIdclientAutCookie Header'
    )
  }

  // TODO
  // also review policies to align with this url to have a double validation
  // check params url to see if it's an url it can hit

  //   const { url } = requestBody

  //   if (url !== 'valid url to hit' && url !== 'other valid url to hit') {
  //     throw new AuthenticationError('Invalid url')
  //   }

  await next()
}

```


[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 mkp-seller-auth/node/middlewares/checkConfiguration.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
import atob from 'atob'
import { NotFoundError } from '@vtex/api'

function parseJwt(token: string) {
  const base64Url = token.split('.')[1]
  const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
  const jsonPayload = decodeURIComponent(
    atob(base64)
      .split('')
      .map((c: string) => {
        return `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`
      })
      .join('')
  )

  return JSON.parse(jsonPayload)
}

// TODO optimize this to avoid always iterating the whole array
function listContainsAccountId(list: [], accountId: string) {
  // console.info('checkConfiguration accountId: ', accountId)
  const mapped = list.map((elem: any) => {
    console.info('checkConfiguration SellerId: ', elem.SellerId)

    return accountId === elem.SellerId
  })

  return mapped.includes(true)
}

export async function checkConfiguration(
  ctx: Context,
  next: () => Promise<any>
) {
  const {
    vtex: { logger },
    state: { requestBody, requestHeaders },
    clients: { sellers, affiliations },
  } = ctx

  const requesterTokenDetails = parseJwt(
    requestHeaders.requestervtexidclientautcookie
  )

  // console.warn(
  //   'checkConfiguration requesterTokenDetails: ',
  //   requesterTokenDetails
  // )

  ctx.state.requesterTokenDetails = requesterTokenDetails

  let validConfig = false

  if (requestBody.accountType === 'seller') {
    // check account seller list
    const sellersListResponse = await sellers.getSellerList()

    validConfig = listContainsAccountId(
      sellersListResponse.data,
      requesterTokenDetails.account
    )
  } else if (requestBody.accountType === 'marketplace') {
    // check account affiliations
    const affiliationsListResponse = await affiliations.getAffiliationsList()
    const affiliatedMarketplaces = affiliationsListResponse.data.map( (affiliation: any) => {
      const splittedUri = affiliation.searchURIEndpoint.split('/')
      return { SellerId: splittedUri[splittedUri.length-2] }
    })
    validConfig = listContainsAccountId(
      affiliatedMarketplaces,
      requesterTokenDetails.account
    )
  }

  if (!validConfig) {
    logger.error({
      message: 'Invalid configuration',
      data: {
        requesterTokenDetails,
      },
    })
    throw new NotFoundError(
      'Configuration for account not found. If seller check affiliations (https://{account}.myvtex.com/admin/checkout/#/affiliates). If marketplace check sellers list (https://{account}.myvtex.com/admin/Site/Seller.aspx)'
    )
  }

  await next()
}

```


[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 mkp-seller-auth/node/__tests__/simple.test.ts from the mkp-seller-auth VTEX app.

[Assistant]
Here's the implementation:

```typescript
// You can import your files here for testing them
//
// More info: https://github.com/sapegin/jest-cheat-sheet

describe('simpleTest', () => {
  it('one test case', async () => {
    expect(0.2 + 0.1).not.toBe(0.3)
  })
})

```


[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 cybersource-payer-auth/pages/pages.json from the cybersource-payer-auth VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "extensions": {
    "checkout/transactions/cybersource-payer-auth": {
      "component": "index"
    }
  }
}

```


[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 cybersource-payer-auth/react/index.tsx from the cybersource-payer-auth VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable no-console */
import React, { Component } from 'react'
import { Modal, Alert, Spinner } from 'vtex.styleguide'

interface CyberSourceAuthenticationProps {
  appPayload: string
}

declare const $: any
declare const vtex: any

class CybersourcePayerAuth extends Component<CyberSourceAuthenticationProps> {
  private formRef: React.RefObject<HTMLFormElement>
  private formRefStepUp: React.RefObject<HTMLFormElement>

  constructor(
    props:
      | CyberSourceAuthenticationProps
      | Readonly<CyberSourceAuthenticationProps>
  ) {
    super(props)
    this.formRef = React.createRef<HTMLFormElement>()
    this.formRefStepUp = React.createRef<HTMLFormElement>()
  }

  public state = {
    submitted: false,
    renderStepUp: false,
    showAlert: false,
    height: '',
    width: '',
    stepUpUrl: '',
    stepUpAccessToken: '',
    createPaymentRequestReference: '',
    alertMessage: '',
    showSpinner: false,
  }

  public componentDidMount() {
    if (this.state.submitted) {
      return
    }

    window.addEventListener(
      'message',
      async event => {
        if (
          event.origin !== 'https://centinelapistag.cardinalcommerce.com' &&
          event.origin !== 'https://centinelapi.cardinalcommerce.com'
        ) {
          return
        }

        const { createPaymentRequestReference } = JSON.parse(
          this.props.appPayload
        )

        this.setState({
          ...this.state,
          createPaymentRequestReference,
        })

        const payAuthRequest = await fetch(
          `/cybersource/payer-auth/${createPaymentRequestReference}`,
          {
            headers: {
              'Content-Type': 'application/json',
              Accept: 'application/json',
              'Cache-Control': 'no-cache',
            },
          }
        )

        const payAuthResponse = await payAuthRequest.json()

        if (
          payAuthResponse.status === 'AUTHENTICATION_SUCCESSFUL' ||
          payAuthResponse.status === 'AUTHORIZED'
        ) {
          this.respondTransaction(true)
        } else if (
          payAuthResponse.status === 'DECLINED' ||
          payAuthResponse.status === 'REFUSED' ||
          payAuthResponse.status === 'AUTHENTICATION_FAILED'
        ) {
          this.verifyStatus(createPaymentRequestReference)
        } else if (payAuthResponse.status === 'PENDING_AUTHENTICATION') {
          const dec = atob(
            payAuthResponse.consumerAuthenticationInformation.pareq
          )

          const decObj = JSON.parse(dec)

          this.renderStepUp(
            decObj.challengeWindowSize,
            payAuthResponse.consumerAuthenticationInformation.stepUpUrl,
            payAuthResponse.consumerAuthenticationInformation.accessToken
          )

          if (this.formRefStepUp.current) {
            this.formRefStepUp.current.submit()
            this.setState({ submitted: true })
          }

          this.verifyStatus(createPaymentRequestReference)
        } else {
          this.verifyStatus(createPaymentRequestReference)
        }
      },
      false
    )

    if (this.formRef.current) {
      this.formRef.current.submit()
      this.setState({ submitted: true })
    }
  }

  public respondTransaction(status: boolean) {
    $(window).trigger('transactionValidation.vtex', [status])
  }

  public render() {
    const { deviceDataCollectionUrl, accessToken } = JSON.parse(
      this.props.appPayload
    )

    return (
      <>
        <iframe
          id="cardinal_collection_iframe"
          title="Cardinal Collection Iframe"
          name="collectionIframe"
          height="10"
          width="10"
          style={{ display: 'none' }}
        />
        <form
          ref={this.formRef}
          id="cardinal_collection_form"
          method="POST"
          target="collectionIframe"
          action={deviceDataCollectionUrl}
        >
          <input
            id="cardinal_collection_form_input"
            type="hidden"
            name="JWT"
            value={accessToken}
          />
        </form>
        {this.state.renderStepUp && (
          <Modal isOpen={true} showCloseIcon={false}>
            <iframe
              name="step-up-iframe"
              height={this.state.height}
              width={this.state.width}
            />
            <form
              ref={this.formRefStepUp}
              id="step-up-form"
              method="POST"
              target="step-up-iframe"
              action={this.state.stepUpUrl}
            >
              <input
                type="hidden"
                name="JWT"
                value={this.state.stepUpAccessToken}
              />
              <input
                type="hidden"
                name="MD"
                value={this.state.createPaymentRequestReference}
              />
            </form>
          </Modal>
        )}
        {this.state.showAlert && (
          <Alert type="error" onClose={() => this.respondTransaction(false)}>
            {this.state.alertMessage}
          </Alert>
        )}
        {this.state.showSpinner && <Spinner />}
      </>
    )
  }

  public renderStepUp(
    challengeWindowSize: string,
    stepUpUrl: string,
    accessToken: string
  ) {
    // Width x Height
    // 01 250 x 400
    // 02 390 x 400
    // 03 500 x 600
    // 04 600 x 400
    // 05 Full screen
    const widthArr = [250, 390, 500, 600, 1200]
    const heightArr = [400, 400, 600, 400, 800]
    let windowSize = +challengeWindowSize

    windowSize -= 1
    this.setState({
      ...this.state,
      height: heightArr[windowSize].toString(),
      width: widthArr[windowSize].toString(),
      stepUpUrl,
      stepUpAccessToken: accessToken,
      renderStepUp: true,
    })
    vtex.checkout.MessageUtils.hidePaymentMessage()
  }

  public showAlert(alertMessage: string) {
    this.setState({
      ...this.state,
      alertMessage,
      showAlert: true,
      renderStepUp: false,
    })
  }

  public verifyStatus(createPaymentRequestReference: string) {
    const checkAuthStatus = setInterval(async () => {
      const authStatus = await fetch(
        `/cybersource/payer-auth/status/${createPaymentRequestReference}`,
        {
          headers: {
            'Content-Type': 'application/json',
            Accept: 'application/json',
            'Cache-Control': 'no-cache',
          },
        }
      )

      const authStatusResponse = await authStatus.json()

      if (authStatusResponse === 'approved') {
        this.respondTransaction(true)
        clearInterval(checkAuthStatus)
      } else if (authStatusResponse === 'denied') {
        this.respondTransaction(false)
        clearInterval(checkAuthStatus)
      }

      this.setState({ ...this.state, showSpinner: true })
    }, 3000)
  }
}

export default CybersourcePayerAuth

```


[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 cybersource-payer-auth/react/index.css from the cybersource-payer-auth VTEX app.

[Assistant]
Here's the implementation:

```css
.wrapper {
  align-items: center;
  background: white;
  display: flex;
  flex-direction: column;
  height: 500px;
  justify-content: center;
  left: 0;
  margin-left: auto;
  margin-right: auto;
  position: absolute;
  right: 0;
  width: 500px;
  top: 0;
  box-shadow: 0px 0px 26px 0px rgba(0, 0, 0, 0.42);
  z-index: 999;
}

.buttonDanger {
  color: #fff;
  background-color: #d9534f;
  border-color: #d43f3a;
}

.buttonSuccess {
  color: #fff;
  background-color: #8bc34a;
  border-color: #8bc34a;
}

.appPayload {
  width: 100%;
  word-break: break-word;
}

```


[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 cybersource-payer-auth/react/package.json from the cybersource-payer-auth VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "cybersource-payer-auth",
  "version": "0.0.6",
  "main": "index.js",
  "license": "UNLICENSED",
  "dependencies": {
    "react": "^16.8.6",
    "react-apollo": "^3.1.5",
    "apollo-client": "^2.6.4",
    "graphql": "^14.3.1"
  },
  "devDependencies": {
    "@types/node": "^10.14.4",
    "@types/react": "^16.8.8",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@7.45.0/public/@types/vtex.render-runtime"
  }
}

```


[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 cybersource-payer-auth/react/mutations/payerAuthorize.gql from the cybersource-payer-auth VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation PayerAuthorize($paymentId: String) {
  payerAuthorize(app: "vtex.cybersource", paymentId: $paymentId)
    @context(provider: "vtex.apps-graphql") {
    message
  }
}

```


[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 b2b-supplier/messages/sl.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Vaša organizacija trenutno ni odobrena za oddajanje naročil v tej trgovini. Če je tako že nekaj časa in menite, da gre za napako, se obrnite na nas.",
  "store/b2b-auth.signup": "Vpis",
  "store/b2b-supplier.creating-buyer-org": "Ustvarjanje organizacije kupcev pri dobavitelju"
}

```


[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 b2b-supplier/messages/nl.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Uw organisatie is momenteel niet goedgekeurd om bestellingen te plaatsen op deze winkel. Als dit al een tijdje zo is en u denkt dat dit een fout is, neem dan contact met ons op.",
  "store/b2b-auth.signup": "Registreren",
  "store/b2b-supplier.creating-buyer-org": "Koperorganisatie aanmaken in de leverancier"
}

```


[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 b2b-supplier/messages/ru.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "В настоящее время ваша организация не имеет права размещать заказы в этом магазине. Свяжитесь с нами, если такая ситуация продолжается довольно долго, и вы считаете это ошибкой.",
  "store/b2b-auth.signup": "Зарегистрироваться",
  "store/b2b-supplier.creating-buyer-org": "Создание организации-покупателя у поставщика"
}

```


[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 b2b-supplier/messages/pl.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Twoja organizacja nie jest obecnie zatwierdzona do składania zamówień w tym sklepie. Jeśli tak jest od jakiegoś czasu i uważasz, że to błąd, prosimy o kontakt.",
  "store/b2b-auth.signup": "Zarejestruj się",
  "store/b2b-supplier.creating-buyer-org": "Tworzenie organizacji nabywcy w dostawcy"
}

```


[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 b2b-supplier/messages/uk.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Наразі ваша організація не має права розміщувати замовлення в цьому магазині. Зв’яжіться з нами, якщо така ситуація триває доволі довго, і ви вважаєте це помилкою.",
  "store/b2b-auth.signup": "Зареєструватися",
  "store/b2b-supplier.creating-buyer-org": "Створення організації-покупця у постачальника"
}

```


[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 b2b-supplier/messages/fi.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Organisaatiosi ei ole saanut hyväksyntää tehdä tilauksia tässä kaupassa juuri nyt. Jos tilanne on kestänyt jo hetken ja uskot tämän olevan virhe, ota meihin yhteyttä.",
  "store/b2b-auth.signup": "Rekisteröidy",
  "store/b2b-supplier.creating-buyer-org": "Ostajaorganisaation luonti toimittajalle"
}

```


[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 b2b-supplier/messages/sk.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Vaša organizácia momentálne nie je schválená na zadávanie objednávok v tomto obchode. Ak je to tak už nejaký čas a myslíte si, že ide o chybu, kontaktujte nás.",
  "store/b2b-auth.signup": "Registrovať sa",
  "store/b2b-supplier.creating-buyer-org": "Vytvorenie organizácie nákupcu u dodávateľa"
}

```


[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 b2b-supplier/messages/pt.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Sua organização não foi aprovada para fazer pedidos nesta loja. Se essa situação já está assim há algum tempo e você acha que pode ser um erro, entre em contato conosco.",
  "store/b2b-auth.signup": "Cadastre-se",
  "store/b2b-supplier.creating-buyer-org": "Criando organização de compradores no fornecedor"
}

```


[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 b2b-supplier/messages/en.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Your organization is not approved to place orders in this store right now. If it’s been like this for a while and you think this is a mistake, please contact us.",
  "store/b2b-auth.signup": "Sign Up",
  "store/b2b-supplier.creating-buyer-org": "Creating buyer organization in supplier"
}

```


[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 b2b-supplier/messages/it.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Al momento, la tua azienda non è autorizzata a effettuare ordini su questo negozio. Se la situazione si protrae da tempo e pensi a un errore, ti preghiamo di contattarci.",
  "store/b2b-auth.signup": "Registrati",
  "store/b2b-supplier.creating-buyer-org": "Creazione di un'organizzazione di acquirenti presso i fornitori"
}

```


[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 b2b-supplier/messages/fr.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Votre organisation n'est pas autorisée à passer des commandes sur ce magasin pour le moment. Si cela a été comme ça pendant un certain temps et que vous pensez que c'est une erreur, veuillez nous contacter.",
  "store/b2b-auth.signup": "S'inscrire",
  "store/b2b-supplier.creating-buyer-org": "Créer une organisation d'acheteurs dans fournisseur"
}

```


[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 b2b-supplier/messages/el.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Ο οργανισμός σας δεν είναι εγκεκριμένος για παραγγελίες σε αυτό το κατάστημα αυτή τη στιγμή. Εάν αυτό συμβαίνει εδώ και καιρό και πιστεύετε ότι πρόκειται για λάθος, παρακαλούμε επικοινωνήστε μαζί μας.",
  "store/b2b-auth.signup": "Εγγραφή",
  "store/b2b-supplier.creating-buyer-org": "Δημιουργία οργάνωσης αγοραστών στον προμηθευτή"
}

```


[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 b2b-supplier/messages/bg.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Организацията ви не е одобрена да прави поръчки в този магазин в момента. Ако това е така от известно време и смятате, че става въпрос за грешка, моля, свържете се с нас.",
  "store/b2b-auth.signup": "Регистриране",
  "store/b2b-supplier.creating-buyer-org": "Създаване на организация на купувача при доставчика"
}

```


[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 b2b-supplier/messages/ro.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "În acest moment, organizația ta nu are aprobare să plaseze comenzi în acest magazin. În cazul în care acest lucru persistă de mai mult timp, te rugăm să ne contactezi.",
  "store/b2b-auth.signup": "Înregistrare",
  "store/b2b-supplier.creating-buyer-org": "Crearea unei organizații de cumpărători în furnizor"
}

```


[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 b2b-supplier/messages/ca.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "La vostra empresa no disposa de l'aprovació necessària per fer comandes a aquesta botiga ara mateix. Si aquesta situació fa temps que es produeix i creieu que es tracta d'un error, poseu-vos en contacte amb nosaltres.",
  "store/b2b-auth.signup": "Registra't",
  "store/b2b-supplier.creating-buyer-org": "S'està creant l'empresa del comprador a la base de dades del proveïdor"
}

```


[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 b2b-supplier/messages/ko.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "귀하의 조직은 현재 이 스토어에서 주문하도록 승인되지 않았습니다. 한동안 이러다가 실수라고 생각되시면 연락주세요.",
  "store/b2b-auth.signup": "등록",
  "store/b2b-supplier.creating-buyer-org": "공급자에서 구매자 조직 생성"
}

```


[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 b2b-supplier/messages/cs.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Vaše organizace aktuálně nemůže zadávat objednávky v tomto obchodě. Pokud se tak děje již delší dobu a myslíte si, že se jedná o chybu, kontaktujte nás.",
  "store/b2b-auth.signup": "Zaregistrujte se",
  "store/b2b-supplier.creating-buyer-org": "Vytvoření organizace odběratelů u dodavatele"
}

```


[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 b2b-supplier/messages/id.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Organisasi Anda tidak disetujui untuk membuat pesanan di toko ini saat ini. Jika hal ini telah lama terjadi dan menurut Anda ini kesalahan, harap hubungi kami.",
  "store/b2b-auth.signup": "Daftar",
  "store/b2b-supplier.creating-buyer-org": "Membuat organisasi pembeli di pemasok"
}

```


[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 b2b-supplier/messages/no.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Organisasjonen din er ikke godkjent for å legge inn bestillinger i denne butikken akkurat nå. Ta kontakt med oss hvis det har vært slik en stund og du tror dette er en feil.",
  "store/b2b-auth.signup": "Registrer deg",
  "store/b2b-supplier.creating-buyer-org": "Oppretter innkjøperorganisasjon i leverandør"
}

```


[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 b2b-supplier/messages/da.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Din organisation er ikke godkendt til at placere ordrer i denne butik lige nu. Hvis det har været sådan i et stykke tid, og du mener, at der er tale om en fejl, bedes du kontakte os.",
  "store/b2b-auth.signup": "Tilmeld",
  "store/b2b-supplier.creating-buyer-org": "Oprettelse af en køberorganisation hos leverandøren"
}

```


[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 b2b-supplier/messages/th.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "ขณะนี้ องค์กรของคุณไม่ได้รับอนุญาตให้ออกคำสั่งซื้อในร้านค้าแห่งนี้ หากเป็นเช่นนี้นานเกินไปและคุณคิดว่าระบบมีข้อผิดพลาด โปรดติดต่อเรา",
  "store/b2b-auth.signup": "ลงชื่อ",
  "store/b2b-supplier.creating-buyer-org": "การสร้างองค์กรผู้ซื้อสำหรับซัพพลายเออร์"
}

```


[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 b2b-supplier/messages/sv.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Din organisation är inte godkänd att göra beställningar i denna butik just nu. Om det har varit så här ett tag och du anser att detta är ett misstag, vänligen kontakta oss.",
  "store/b2b-auth.signup": "Skapa konto",
  "store/b2b-supplier.creating-buyer-org": "Skapar köparorganisation i leverantör"
}

```


[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 b2b-supplier/messages/es.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Tu organización no está aprobada para realizar pedidos en esta tienda en este momento. Si ha sido así por un tiempo y crees que es un error, ponte en contacto con nosotros.",
  "store/b2b-auth.signup": "Regístrate",
  "store/b2b-supplier.creating-buyer-org": "Creando una organización de compradores en el proveedor"
}
```


[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 b2b-supplier/messages/ar.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "لم تتم الموافقة على مؤسستك لوضع الطلبات على هذا المتجر الآن. إذا كانت مثل هذه لفترة من الوقت وتعتقد أن هذا خطأ، يرجى الاتصال بنا.",
  "store/b2b-auth.signup": "التسجيل",
  "store/b2b-supplier.creating-buyer-org": "إنشاء منظمة للمشترين في المورد"
}

```


[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 b2b-supplier/messages/es-MX.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Tu organización no está aprobada para realizar pedidos en esta tienda en este momento. Si ha sido así por un tiempo y crees que es un error, ponte en contacto con nosotros.",
  "store/b2b-auth.signup": "Regístrate",
  "store/b2b-supplier.creating-buyer-org": "Creando una organización de compradores en el proveedor"
}

```


[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 b2b-supplier/docs/README.md from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```markdown
📢 Use this project, [contribute](https://github.com/{OrganizationName}/{AppName}) to it or open issues to help evolve it using [Store Discussion](https://github.com/vtex-apps/store-discussion).

# B2B Supplier

<!-- DOCS-IGNORE:start -->
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<!-- DOCS-IGNORE:end -->

The **B2B Supplier** app allows you, as a supplier, to enable customers to sign up and log in as Buyer Organizations in your store. It enables components related to authentication and authorization of users and Buyer Organizations.

## Installation

To install the **B2B Supplier** app, you must follow the steps below.

1. Run the following command on your CLI:

    ```
    vtex install vtex.b2b-supplier
    ```

2. Add the app as a dependency in your theme’s `manifest.json` file, as follows:

    ```json
    "dependencies": {
    "vtex.b2b-supplier": "0.x"
    }
    ```

3. Declare the following blocks in a given theme template or inside another block from the theme.

| Block name | Description |
| ----------- |  ----------- |
| `b2b-supplier.sign-up-button` | Renders a `Sign up` button that leads users to the form where they can sign up as a Buyer Organization. |
| `b2b-supplier.approved-status` | Renders an alert informing the Buyer Organization user of their approval status in your store. |

After the installation, it will be possible for buyers to Sign up as a Buyer Organization in your store or for you to create and manage Buyer Organizations via API.

>⚠ Remember that every time a new Buyer Organization signs up, it is necessary for the supplier to approve their access on Master Data.

## Customization

In order to apply CSS customizations in this and other blocks, follow the instructions given in the recipe on [Using CSS Handles for store customization](https://developers.vtex.com/vtex-developer-docs/docs/vtex-io-documentation-using-css-handles-for-store-customization).

| CSS Handles |
| ----------- |
| `container` |
| `button` |
| `label` |

<!-- DOCS-IGNORE:start -->

## Contributors ✨

Thanks goes to these wonderful people:

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!

<!-- DOCS-IGNORE:end -->

```


[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 b2b-supplier/node/service.json from the b2b-supplier VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 60,
  "timeout": 120,
  "minReplicas": 2,
  "maxReplicas": 5,
  "routes": {
    "keep-alive": {
      "path": "/_v/vtex.b2b-supplier/keep-alive",
      "public": true,
      "policies": [
        {
          "effect": "allow",
          "actions": ["get"]
        }
      ]
    }
  }
}
```