[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 admin-ley-gondolas-arg/react/utils/listOfLawCategories.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
export const listOfLawCategories: string[] = [
  'Leches',
  'Cremas de leche, mantecas y margarinas',
  'Quesos untables y ricotas',
  'Postres lácteos y yogures',
  'Masas frescas y levaduras',
  'Fiambres, embutidos y encurtidos',
  'Quesos excepto untables y ricotas',
  'Hamburguesas, milanesas y bocaditos de carne, pollo, cerdo y/o pescado congelados',
  'Vegetales congelados, milanesas y medallones sin carne congelados',
  'Comidas preparadas y panificados congelados',
  'Helados y postres congelados',
  'Frutas y verduras',
  'Salsas y aderezos',
  'Especias y condimentos',
  'Polvo para postres y repostería, y productos de repostería',
  'Conservas y salsas de tomate',
  'Otras conservas',
  'Pastas secas',
  'Arroz',
  'Sopas, caldos y puré',
  'Legumbres secas, otras harinas, granos y semillas',
  'Aceites',
  'Panes rallados y rebozadores',
  'Harinas de trigo y premezclas',
  'Golosinas, alfajores y chocolates',
  'Panificados y cereales',
  'Galletitas',
  'Infusiones',
  'Mermeladas, dulces y miel',
  'Dulce de leche',
  'Endulzantes',
  'Snacks',
  'Jugos',
  'Aguas saborizadas',
  'Gaseosas',
  'Aguas',
  'Bebidas sin alcohol refrigeradas',
  'Cervezas y aperitivos',
  'Vinos y espumantes',
  'Espirituosas, destilados y licores',
  'Bebidas con alcohol refrigeradas',
  'Afeitado y depilación',
  'Colonias y desodorantes corporales, polvos pédicos y talcos',
  'Jabones de tocador, geles y sales de baño, artículos de baño',
  'Cremas decolorantes y coloración para el cabello',
  'Champúes, Acondicionadores, fijadores y productos para el tratamiento capilar',
  'Cuidado facial y artículos de farmacia',
  'Cremas corporales',
  'Protectores solares y bronceadores',
  'Cuidado oral',
  'Productos para la higiene del bebé, accesorios para el bebé y alimentación infantil',
  'Pañales y ropa interior descartable',
  'Productos de gestión menstrual, toallas para la incontinencia y cuidado materno',
  'Accesorios de limpieza',
  'Accesorios de cocina',
  'Jabón en pan, prelavado, quitamanchas y perfumes para la ropa',
  'Jabones en polvo, jabones líquidos y suavizantes para la ropa',
  'Desodorantes y desinfectantes ambientales',
  'Lavandinas',
  'Lavavajillas',
  'Limpieza de pisos y muebles',
  'Limpiadores cremosos, de cocina, de baño y multiuso',
  'Insecticidas y repelentes',
  'Papeles',
  'Alimentos y accesorios para mascotas',
]

```


[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 admin-ley-gondolas-arg/react/utils/intl.ts from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

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

const prefix = 'admin/admin.app.ley-gondolas-arg.'

export const titlesIntl = defineMessages({
  pageTitle: { id: `${prefix}pageTitle` },
  textOf: { id: `${prefix}textOf` },
  textShowRows: { id: `${prefix}textShowRows` },
  filterClear: { id: `${prefix}filterClear` },
  filterAll: { id: `${prefix}filterAll` },
  filterNone: { id: `${prefix}filterNone` },
  filterAny: { id: `${prefix}filterAny` },
  filterIs: { id: `${prefix}filterIs` },
  filterIsNot: { id: `${prefix}filterIsNot` },
  filterContains: { id: `${prefix}filterContains` },
  filterApply: { id: `${prefix}filterApply` },
  categoriesTableCategorieLaw: { id: `${prefix}categoriesTableCategorieLaw` },
  categoriesTableCategorieCatalog: {
    id: `${prefix}categoriesTableCategorieCatalog`,
  },
  categoriesTableBestLowerProduct: {
    id: `${prefix}categoriesTableBestLowerProduct`,
  },
  selectCategory: {
    id: `${prefix}selectCategory`,
  },
  changeCategory: {
    id: `${prefix}changeCategory`,
  },
  currentCategory: {
    id: `${prefix}currentCategory`,
  },
  cancel: {
    id: `${prefix}cancel`,
  },
  saveSelectedCategory: {
    id: `${prefix}saveSelectedCategory`,
  },
  productsTableImage: {
    id: `${prefix}productsTableImage`,
  },
  productsTableProductId: {
    id: `${prefix}productsTableProductId`,
  },
  productsTableProductName: {
    id: `${prefix}productsTableProductName`,
  },
  productsTableBrand: {
    id: `${prefix}productsTableBrand`,
  },
  productsTablePricePerUnit: {
    id: `${prefix}productsTablePricePerUnit`,
  },
  productsTablePyMEs: {
    id: `${prefix}productsTablePyMEs`,
  },
  productsTableMejorMenorPrecio: {
    id: `${prefix}productsTableMejorMenorPrecio`,
  },
  currentProduct: {
    id: `${prefix}currentProduct`,
  },
  showProduct: {
    id: `${prefix}showProduct`,
  },
  lastSeen: {
    id: `${prefix}lastSeen`,
  },
  showInCatalog: {
    id: `${prefix}showInCatalog`,
  },
  warningSelectCategory: {
    id: `${prefix}warningSelectCategory`,
  },
  tryLater: {
    id: `${prefix}tryLater`,
  },
  noProducts: {
    id: `${prefix}noProducts`,
  },
})

```


[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 admin-ley-gondolas-arg/react/style/Loading.global.css from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```css
.loading-container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

```


[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 admin-ley-gondolas-arg/react/components/ProductSearch.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable @typescript-eslint/prefer-optional-chain */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useState, useEffect, useContext } from 'react'
import { Modal /* , Tag */ } from 'vtex.styleguide'
import { useQuery, useLazyQuery } from 'react-apollo'
import { useIntl } from 'react-intl'

import { titlesIntl } from '../utils/intl'
import getCategoryTree from '../graphql/getCategoryTree.gql'
import getProductsOfCategory from '../graphql/getProductsOfCategory.gql'
import getPaginationData from '../graphql/getPaginationData.gql'
import LoadingSpinner from './LoadingSpinner'
import ProductsTable from './ProductsTable'
import '../style/Modal.global.css'
import { ProductContext } from '../store/context/ProductContext'

export default function ProductSearch({
  idRow,
  // nameProduct,
  items,
  setItems,
  closeModal,
}: ProductSearchProps) {
  const intl = useIntl()
  const [categoryTree, setCategoryTree] = useState('')
  const [listOfProducts, setListOfProducts] = useState<ProductToTable[]>([])
  const { state, dispatch } = useContext(ProductContext)

  const [
    getProductsOfCategoryQuery,
    { data: dataProducts, loading: loadingProducts, error: errorProducts },
  ] = useLazyQuery(getProductsOfCategory)

  const [
    getPaginationDataQuery,
    { data: dataPagination },
  ] = useLazyQuery(getPaginationData)

  useEffect(() => {
    if (categoryTree) {
      getProductsOfCategoryQuery({ variables: { categoryTree, from: state.from, to: state.to, params: state.params } })
      getPaginationDataQuery({
        variables: {
          filters: { categoryId: categoryTree },
          page: state.currentPage,
          pageSize: state.limit,
          term: state.params,
        }
      })
    }

  }, [state.to, state.from, state.limit, state.params, categoryTree, getProductsOfCategoryQuery])

  const responseFromGetCategoryTree = useQuery(getCategoryTree, {
    ssr: false,
  })

  const idCategoryOfRow = items[idRow].categorieCatalog.id

  const dataFromGetCategoryTree: CategoryChildenListProps[] =
    responseFromGetCategoryTree.data?.getCategoryTree?.data

  dataFromGetCategoryTree?.forEach(
    (c: CategoryChildenListProps) => !categoryTree && findCategoryTree(c)
  )

  function findCategoryTree(
    categoryToCheck: CategoryChildenListProps,
    parents = ''
  ): any {
    if (categoryToCheck.children.some((c) => c.id === idCategoryOfRow)) {
      setCategoryTree(
        `${!parents ? categoryToCheck.id : parents}/${idCategoryOfRow}`
      )
    } else if (categoryToCheck.id === idCategoryOfRow) {
      setCategoryTree(`${!parents ? categoryToCheck.id : parents}`)
    } else {
      return categoryToCheck.children.some(
        (c) =>
          c.id === idCategoryOfRow ||
          findCategoryTree(
            c,
            `${!parents ? categoryToCheck.id : parents}/${c.id}`
          )
      )
    }
  }

  /*   useEffect(() => {
      if (categoryTree) {
        getProductsOfCategoryQuery({ variables: { categoryTree } })
      }
    }, [categoryTree, getProductsOfCategoryQuery]) */

  useEffect(() => {
    if (dataPagination) {
      dispatch({ type: "SET_TOTAL_ITEMS", payload: dataPagination.products.paging.total })
      dispatch({ type: "SET_TOTAL_PAGES", payload: dataPagination.products.paging.pages })
      dispatch({ type: "SET_CURRENT_PAGE", payload: dataPagination.products.paging.page })
    }
  }, [dataPagination])

  useEffect(() => {
    if (errorProducts) {
      console.info('errorProducts', errorProducts)
    }

    // eslint-disable-next-line vtex/prefer-early-return
    if (dataProducts) {
      const listOfProductsTemp: ProductToTable[] =
        dataProducts.getProductsOfCategory.data.map(
          (p: ProductFromQuery, index: number) => {
            return {
              id: index,
              catalog: {
                idRow,
                productId: p.productId,
                name: p.productName,
              },
              image: {
                imageId: p.items[0].images[0].imageId,
                imageUrl: p.items[0].images[0].imageUrl,
                imageText: p.items[0].images[0].imageText,
              },
              productId: p.productId,
              productName: {
                name: p.productName,
                link: p.linkText,
              },
              brand: p.brand,
              categoryId: p.categoryId,
              pricePerUnit: p.pricePerUnit && p.pricePerUnit[0],
              bestLowerPrice: p.leyDeGondolas,
              pymes: p.leyDeGondolas,
            }
          }
        )

      listOfProductsTemp.sort(
        (a, b) =>
          (a.pricePerUnit != null ? a.pricePerUnit : Infinity) -
          (b.pricePerUnit != null ? b.pricePerUnit : Infinity)
      )

      setListOfProducts(listOfProductsTemp)
    }
  }, [dataProducts, loadingProducts, errorProducts, idRow])
  return (
    <Modal
      centered
      isOpen
      onClose={() => closeModal({ id: '', idRow: -1, name: '' })}
    >
      <div>
        {idCategoryOfRow !== -1 &&
          dataProducts && (
            <ProductsTable
              listOfProducts={listOfProducts}
              setListOfProducts={setListOfProducts}
              items={items}
              setItems={setItems}
            />
          )}
        {loadingProducts && <LoadingSpinner />}
        {errorProducts && (
          <div className="w-100">
            <p className="f3 fw3 gray">
              {intl.formatMessage(titlesIntl.tryLater)}
            </p>
          </div>
        )}
        {idCategoryOfRow === -1 && (
          <div className="w-100">
            <p className="f3 fw3 gray">
              {intl.formatMessage(titlesIntl.warningSelectCategory)}
            </p>
          </div>
        )}
      </div>
    </Modal>
  )
}

```


[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 admin-ley-gondolas-arg/react/components/RecurviseChildenList.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable @typescript-eslint/prefer-optional-chain */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useState, useEffect } from 'react'

import Expandable from './Expandable'

export default function RecursiveChildenList({
  category,
  selectedCategory,
  setSelectedCategory,
  setSelectedIdCategory,
}: RecursiveChildenListProps) {
  const [checked, setChecked] = useState<string>(selectedCategory)

  useEffect(() => {
    setSelectedCategory(checked)
  }, [checked, setSelectedCategory])

  function createRecursiveChildenList(
    categoryRecursive: CategoryChildenListProps[]
  ) {
    function doCheckOpen(categoryToCheck: CategoryChildenListProps): boolean {
      return categoryToCheck.children.some(
        (c) => c.name === checked || doCheckOpen(c)
      )
    }

    return categoryRecursive.map((categoryOfList: CategoryChildenListProps) => (
      <Expandable
        key={`${categoryOfList.id}`}
        id={`${categoryOfList.id}`}
        title={categoryOfList.name}
        checked={checked}
        setChecked={setChecked}
        setCheckedId={setSelectedIdCategory}
        open={doCheckOpen(categoryOfList)}
        content={
          categoryOfList.children.length > 0 &&
          createRecursiveChildenList(categoryOfList.children)
        }
      />
    ))
  }

  return <div>{createRecursiveChildenList(category)}</div>
}

```


[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 admin-ley-gondolas-arg/react/components/CategorieTree.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable @typescript-eslint/prefer-optional-chain */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useState } from 'react'
import { Button, Modal, Tag } from 'vtex.styleguide'
import { useQuery, useMutation } from 'react-apollo'
import { useIntl } from 'react-intl'

import { titlesIntl } from '../utils/intl'
import getCategoryTree from '../graphql/getCategoryTree.gql'
import RecurviseChildenList from './RecurviseChildenList'
import LoadingSpinner from './LoadingSpinner'
import SaveInMasterdata from './SaveInMasterdata'
import updateDocument from '../graphql/updateDocument.gql'
import createDocument from '../graphql/createDocument.gql'

export default function CategoriesTree({
  idRow,
  nameCategory,
  items,
  setItems,
  closeModal,
}: CategoriesTreeProps) {
  const intl = useIntl()
  const [selectedCategory, setSelectedCategory] = useState('')
  const [selectedIdCategory, setSelectedIdCategory] = useState(-1)
  const [updateDocumentMutation] = useMutation(updateDocument)

  const [createDocumentMutation] = useMutation(createDocument)

  const responseFromGetCategoryTree = useQuery(getCategoryTree, {
    ssr: false,
  })

  const dataFromGetCategoryTree: CategoryChildenListProps[] =
    responseFromGetCategoryTree.data?.getCategoryTree?.data

  const handleChangeCategory = async () => {
    closeModal({ id: -1, idRow: -1, name: '' })

    const tempItems: CategoriesRow[] = items

    tempItems[idRow].categorieCatalog.name = selectedCategory
    tempItems[idRow].categorieCatalog.id = selectedIdCategory

    const response = await SaveInMasterdata(
      tempItems,
      idRow,
      updateDocumentMutation,
      createDocumentMutation
    )

    if (response.data.createDocument) {
      tempItems[idRow].idDocument = response.data.createDocument.data.DocumentId
    }

    setItems(tempItems)
  }

  return (
    <Modal
      centered
      isOpen
      onClose={() => closeModal({ id: -1, idRow: -1, name: '' })}
      bottomBar={
        <div className="nowrap">
          {nameCategory && (
            <span className="mr4">
              <Tag bgColor="#F71963">{`${intl.formatMessage(
                titlesIntl.currentCategory
              )}: ${nameCategory}`}</Tag>
            </span>
          )}
          <span className="mr4">
            <Button
              variation="tertiary"
              onClick={() => closeModal({ id: -1, idRow: -1, name: '' })}
            >
              {`${intl.formatMessage(titlesIntl.cancel)}`}
            </Button>
          </span>
          <span>
            <Button
              variation="primary"
              size="small"
              onClick={() => handleChangeCategory()}
            >
              {`${intl.formatMessage(titlesIntl.saveSelectedCategory)}`}
            </Button>
          </span>
        </div>
      }
    >
      <div>
        {dataFromGetCategoryTree && (
          <RecurviseChildenList
            category={dataFromGetCategoryTree}
            selectedCategory={nameCategory}
            setSelectedCategory={setSelectedCategory}
            setSelectedIdCategory={setSelectedIdCategory}
          />
        )}
        {!dataFromGetCategoryTree && <LoadingSpinner />}
      </div>
    </Modal>
  )
}

```


[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 admin-ley-gondolas-arg/react/components/ProductsTable.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
  EXPERIMENTAL_Table as Table,
  Input,
  Link,
  ButtonWithIcon,
} from 'vtex.styleguide'
import Edit from '@vtex/styleguide/lib/icon/Edit'
import Check from '@vtex/styleguide/lib/icon/Check'
import useTableMeasures from '@vtex/styleguide/lib/EXPERIMENTAL_Table/hooks/useTableMeasures'
import React, { useState, useEffect, useCallback, useContext } from 'react'
import { useIntl } from 'react-intl'
import { useRuntime } from 'vtex.render-runtime'
import { useMutation } from 'react-apollo'

import updateDocument from '../graphql/updateDocument.gql'
import createDocument from '../graphql/createDocument.gql'
import { titlesIntl } from '../utils/intl'
import SaveInMasterdata from './SaveInMasterdata'
import { ProductContext } from '../store/context/ProductContext'

export default function ProductsTable({
  listOfProducts,
  items,
  setItems,
}: ProductTableProps) {
  const intl = useIntl()
  const { workspace, account } = useRuntime()
  const { state, dispatch } = useContext(ProductContext)

  const [updateDocumentMutation] = useMutation(updateDocument)

  const [createDocumentMutation] = useMutation(createDocument)
  const columns = [
    {
      id: 'image',
      title: intl.formatMessage(titlesIntl.productsTableImage),
      cellRenderer: ({ data }: any) => {
        return (
          <img id={data.imageId} src={data.imageUrl} alt={data.imageText} />
        )
      },
    },
    {
      id: 'catalog',
      title: intl.formatMessage(titlesIntl.showInCatalog),
      cellRenderer: ({ data }: any) => {
        const editIcon = <Edit />

        return (
          <div className="flex justify-center">
            <ButtonWithIcon
              href={`/admin/Site/ProdutoForm.aspx?id=${data.productId}`}
              target="_blank"
              variation="secondary"
              // eslint-disable-next-line @typescript-eslint/no-use-before-define
              onClick={() => handleClickSeeCatalog(data)}
              icon={editIcon}
            />
          </div>
        )
      },
    },
    {
      id: 'productName',
      title: intl.formatMessage(titlesIntl.productsTableProductName),
      cellRenderer: ({ data }: any) => {
        const domain =
          workspace === 'master'
            ? `https://${account}.myvtex.com/`
            : `https://${workspace}--${account}.myvtex.com/`

        return (
          <Link href={`${domain}${data.link}/p`} target="_blank" mediumWeigth>
            {data.name}
          </Link>
        )
      },
    },
    {
      id: 'pricePerUnit',
      title: intl.formatMessage(titlesIntl.productsTablePricePerUnit),
    },
    {
      id: 'bestLowerPrice',
      title: intl.formatMessage(titlesIntl.productsTableMejorMenorPrecio),
      cellRenderer: ({ data }: any) => {
        const checkIcon = <Check />

        const checkData = data ? data.includes('Mejor Menor Precio') : false

        return (
          <div className="flex justify-center">
            {checkData && (
              <div className="flex pa2 br2 bg-action-primary c-on-action-primary active-c-on-action-primary dib">
                {checkIcon}
              </div>
            )}
            {!checkData && (
              <div className="flex pa2 br2 c-action-primary active-c-action-primary dib mv0 ba b--action-primary">
                <svg
                  viewBox="0 0 12 12"
                  width="16"
                  height="16"
                  className="vtex__icon-check"
                />
              </div>
            )}
          </div>
        )
      },
    },
    {
      id: 'pymes',
      title: intl.formatMessage(titlesIntl.productsTablePyMEs),
      cellRenderer: ({ data }: any) => {
        const checkIcon = <Check />

        const checkData = data ? data.includes('PyMEs') : false

        return (
          <div className="flex justify-center">
            {checkData && (
              <div className="flex pa2 br2 bg-action-primary c-on-action-primary active-c-on-action-primary dib">
                {checkIcon}
              </div>
            )}
            {!checkData && (
              <div className="flex pa2 br2 c-action-primary active-c-action-primary dib mv0 ba b--action-primary">
                <svg
                  viewBox="0 0 12 12"
                  width="16"
                  height="16"
                  className="vtex__icon-check"
                />
              </div>
            )}
          </div>
        )
      },
    },
    {
      id: 'brand',
      title: intl.formatMessage(titlesIntl.productsTableBrand),
    },
  ]

  const handleClickSeeCatalog = async (product: Catalog) => {
    const tempItems: CategoriesRow[] = items

    tempItems[product.idRow].bestLowerProduct.id = product.productId
    tempItems[product.idRow].bestLowerProduct.name = product.name
    setItems(tempItems)
    SaveInMasterdata(
      tempItems,
      product.idRow,
      updateDocumentMutation,
      createDocumentMutation
    )

    const response = await SaveInMasterdata(
      tempItems,
      product.idRow,
      updateDocumentMutation,
      createDocumentMutation
    )

    if (response.data.createDocument) {
      tempItems[product.idRow].idDocument =
        response.data.createDocument.data.DocumentId
    }

    setItems(tempItems)
  }

  const [filteredItems, setFilteredItems] = useState(listOfProducts)

  useEffect(() => {
    setFilteredItems(listOfProducts)
  }, [listOfProducts])

  // const [filterStatements, setFilterStatements] = useState(state.statements)
  const { state: paginationState } = useContext(ProductContext)
  const ITEMS_PER_PAGE = paginationState.limit

  const { slicedItems, ...paginationProps } = usePagination(
    ITEMS_PER_PAGE,
    filteredItems
  )

  const listOfRowsOptions: number[] = [5]

  if (filteredItems.length >= 5) {
    listOfRowsOptions.push(10)
    if (filteredItems.length >= 10) {
      listOfRowsOptions.push(15)
    }
  }

  const pagination = {
    ...paginationProps,
    textOf: intl.formatMessage(titlesIntl.textOf),
    rowsOptions: listOfRowsOptions,
    textShowRows: intl.formatMessage(titlesIntl.textShowRows),
    totalItems: paginationState.totalItems,
  }

  const measures = useTableMeasures({
    size:
      pagination.totalItems < pagination.tableSize
        ? pagination.totalItems
        : pagination.tableSize,
    density: 'comfortable',
  })

  function handleFiltersChange(statements = []) {
    let newData = listOfProducts.slice()
    if (statements.length === 0) {
      dispatch({ type: 'SET_STATEMENTS', payload: statements })
      dispatch({ type: 'SET_PARAMS', payload: "" })
    }

    statements.forEach((st: any) => {
      if (!st || !st.object) return
      const { subject, verb, object } = st

      switch (subject) {
        case 'productName':
          if (verb === 'contains') {
            dispatch({ type: 'SET_STATEMENTS', payload: statements })
            dispatch({ type: 'SET_PARAMS', payload: object })
          }

          break

        default:
          break
      }
    })
    setFilteredItems(newData)
  }

  const filterClear = intl.formatMessage(titlesIntl.filterClear)
  const filterAny = intl.formatMessage(titlesIntl.filterAny)
  const filterIs = intl.formatMessage(titlesIntl.filterIs)
  const filterIsNot = intl.formatMessage(titlesIntl.filterIsNot)
  const filterContains = intl.formatMessage(titlesIntl.filterContains)
  const filterApply = intl.formatMessage(titlesIntl.filterApply)

  const filters = {
    alwaysVisibleFilters: [/* 'productId', */ 'productName'],
    statements: state.statements,
    onChangeStatements: handleFiltersChange,
    clearAllFiltersButtonLabel: filterClear,
    collapseLeft: true,
    submitFilterLabel: filterApply,
    options: {
      productName: {
        label: intl.formatMessage(titlesIntl.productsTableProductName),
        ...simpleInputVerbsAndLabel(),
      },
    },
  }

  function simpleInputObject({ values, onChangeObjectCallback }: any) {
    return (
      <Input
        value={values || ''}
        onChange={(e: any) => onChangeObjectCallback(e.target.value)}
      />
    )
  }

  function simpleInputVerbsAndLabel() {
    return {
      renderFilterLabel: (st: any) => {
        if (!st || !st.object) {
          // you should treat empty object cases only for alwaysVisibleFilters
          return filterAny
        }

        return `${st.verb === '='
          ? filterIs
          : st.verb === '!='
            ? filterIsNot
            : filterContains
          } ${st.object}`
      },
      verbs: [
        {
          label: filterContains,
          value: 'contains',
          object: {
            renderFn: simpleInputObject,
            extraParams: {},
          },
        },
      ],
    }
  }

  const density = {
    label: 'Line density',
    compactLabel: 'Compact',
    regularLabel: 'Regular',
    comfortableLabel: 'Comfortable',
  }

  const customEmptyState = {
    label: intl.formatMessage(titlesIntl.noProducts),

  }

  return (
    <div>
      <Table
        measures={measures}
        columns={columns}
        items={slicedItems}
        empty={slicedItems.length === 0}
        emptyState={customEmptyState}
      >
        <Table.Pagination {...pagination} />
        <Table.Toolbar>
          <Table.FilterBar {...filters} />
          <Table.Toolbar.ButtonGroup>
            <Table.Toolbar.ButtonGroup.Density {...density} />
          </Table.Toolbar.ButtonGroup>
        </Table.Toolbar>
      </Table>
    </div>
  )
}

function usePagination(initialSize: number, itemsToPaginate: any) {
  const { dispatch, state: paginationState } = useContext(ProductContext)
  const state = ({
    tableSize: initialSize,
    currentPage: paginationState.currentPage,
    currentItemFrom: paginationState.from,
    currentItemTo: paginationState.to,
    selectedOption: paginationState.limit,
    slicedItems: [...itemsToPaginate]
  })

  /** gets the next page */
  const onNextClick = useCallback(() => {
    dispatch({ type: 'INCREASE_PAGE' })
  }, [state, itemsToPaginate])

  /** gets the previous page */
  const onPrevClick = useCallback(() => {

    if (state.currentPage === 0) return
    dispatch({ type: 'DECREASE_PAGE' })

  }, [state, itemsToPaginate])

  /** deals rows change of Pagination component */
  const onRowsChange = useCallback(
    (_, value) => {
      const rowValue = parseInt(value, 10)
      dispatch({ type: 'SET_LIMIT', payload: rowValue })
    },
    [state, itemsToPaginate]
  )

  return {
    onNextClick,
    onPrevClick,
    onRowsChange,
    ...state,
  }
}

```


[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 admin-ley-gondolas-arg/react/components/Expandable.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import React, { useState } from 'react'
import useCollapse from 'react-collapsed'
import { Checkbox } from 'vtex.styleguide'

// import arrow from '../../assets/categoryTree/arrowCategoryTree.svg'

const Expandable = ({
  id,
  title,
  content,
  checked,
  setChecked,
  setCheckedId,
  open,
}: // eslint-disable-next-line @typescript-eslint/no-explicit-any
any) => {
  const { getCollapseProps, getToggleProps } = useCollapse({
    defaultExpanded: open,
  })

  const [rotation, setRotation] = useState<number>(open ? 90 : 0)
  const [isRotate, setIsRotate] = useState<boolean>(open)

  const rotate = () => {
    const angle = !isRotate ? 90 : -90
    let newRotation = rotation + angle

    if (newRotation >= 360) {
      newRotation = -360
    }

    setIsRotate(!isRotate)
    setRotation(newRotation)
  }

  const titleElement = (
    <li className="flex items-center">
      <span className="flex mb1 pa3 br2 c-emphasis hover-c-emphasis active-c-emphasis dib mr5 mv0 ba b--emphasis hover-b-emphasis active-b-emphasis">
        <div className="mr3 mt1">
          <Checkbox
            id={title}
            checked={checked === title}
            onChange={() => {
              setChecked(title)
              setCheckedId(parseInt(id, 0))
            }}
          />
        </div>
        <div aria-hidden="true" onClick={() => rotate()}>
          <div {...getToggleProps()}>{title}</div>
        </div>
      </span>
      <div {...getToggleProps()}>
        {content && (
          <div
            tabIndex={id}
            role="button"
            id={title}
            style={{ transform: `rotate(${rotation}deg)` }}
            onClick={() => rotate()}
          >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 477.175 477.175"
              width="1rem"
            >
              <path d="M360.731 229.075l-225.1-225.1c-5.3-5.3-13.8-5.3-19.1 0s-5.3 13.8 0 19.1l215.5 215.5-215.5 215.5c-5.3 5.3-5.3 13.8 0 19.1 2.6 2.6 6.1 4 9.5 4 3.4 0 6.9-1.3 9.5-4l225.1-225.1c5.3-5.2 5.3-13.8.1-19z" />
            </svg>
          </div>
        )}
      </div>
    </li>
  )

  const contentUl = <ul {...getCollapseProps()}>{content}</ul>

  return (
    <>
      {title && titleElement}
      {content && contentUl}
    </>
  )
}

export default Expandable

```


[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 admin-ley-gondolas-arg/react/components/LoadingSpinner.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { Spinner } from 'vtex.styleguide'
import React from 'react'
import '../style/Loading.global.css'

export default function LoadingSpinner() {
  return (
    <div className="loading-container">
      <Spinner />
    </div>
  )
}

```


[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 admin-ley-gondolas-arg/react/components/CategoriesTable.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable react/jsx-handler-names */
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
  EXPERIMENTAL_Table as Table,
  Input,
  Button,
  Tag,
} from 'vtex.styleguide'
import useTableMeasures from '@vtex/styleguide/lib/EXPERIMENTAL_Table/hooks/useTableMeasures'
import React, { useState, useEffect, useCallback } from 'react'
import { useIntl } from 'react-intl'

import { titlesIntl } from '../utils/intl'
import CategoriesTree from './CategorieTree'
import ProductSearch from './ProductSearch'
import { ProductProvider } from '../store/context/ProductContext'

export default function CategoriesTable({
  categoriesList,
}: CategoriesTableProps) {
  const intl = useIntl()
  const [items, setItems] = useState<CategoriesRow[]>(categoriesList)
  const [isCategoryModalOpen, setIsCategoryModalOpen] = useState(false)
  const [nameCategoryClick, setNameCategoryClick] = useState('')
  const [rowCategoryClick, setRowCategoryClick] = useState(-1)
  const [isProductModalOpen, setIsProductModalOpen] = useState(false)
  const [nameProductClick, setNameProductClick] = useState('')
  const [idProductClick, setIdProductClick] = useState('')
  const [rowProductClick, setRowProductClick] = useState(-1)
  const columns = [
    {
      id: 'categorieLaw',
      title: intl.formatMessage(titlesIntl.categoriesTableCategorieLaw),
    },
    {
      id: 'categorieCatalog',
      title: intl.formatMessage(titlesIntl.categoriesTableCategorieCatalog),
      cellRenderer: ({ data }: any) => {
        return (
          <div>
            <div className="flex justify-left">
              {data.name && <Tag bgColor="#F71963">{data.name}</Tag>}
            </div>
            <div className="mt1">
              <Button
                variation="secondary"
                size="small"
                onClick={() => handleModalCategorieCatalog(data)}
              >
                {!data.name &&
                  `${intl.formatMessage(titlesIntl.selectCategory)}`}
                {data.name &&
                  `${intl.formatMessage(titlesIntl.changeCategory)}`}
              </Button>
            </div>
          </div>
        )
      },
    },
    {
      id: 'bestLowerProduct',
      title: intl.formatMessage(titlesIntl.categoriesTableBestLowerProduct),
      cellRenderer: ({ data }: any) => {
        return (
          <div>
            <div className="flex justify-left">
              {data.name && (
                <Tag bgColor="#F71963">{`${intl.formatMessage(
                  titlesIntl.lastSeen
                )}: ${data.name}`}</Tag>
              )}
            </div>
            <div className="mt1">
              <Button
                variation="secondary"
                size="small"
                onClick={() => handleModalProducts(data)}
              >
                {intl.formatMessage(titlesIntl.showProduct)}
              </Button>
            </div>
          </div>
        )
      },
    },
  ]

  const handleModalCategorieCatalog = (categorieCatalog: any) => {
    setRowCategoryClick(categorieCatalog.idRow)
    setNameCategoryClick(categorieCatalog.name)
    setIsCategoryModalOpen(!isCategoryModalOpen)
  }

  const handleModalProducts = (product: any) => {
    setRowProductClick(product.idRow)
    setIdProductClick(product.id)
    setNameProductClick(product.name)
    setIsProductModalOpen(!isProductModalOpen)
  }

  const [filteredItems, setFilteredItems] = useState(items)
  const [filterStatements, setFilterStatements] = useState([])

  const ITEMS_PER_PAGE = 5

  const { slicedItems, ...paginationProps } = usePagination(
    ITEMS_PER_PAGE,
    filteredItems
  )

  const listOfRowsOptions: number[] = [5]

  if (filteredItems.length >= 5) {
    listOfRowsOptions.push(10)
    if (filteredItems.length >= 10) {
      listOfRowsOptions.push(15)
    }
  }

  const pagination = {
    ...paginationProps,
    textOf: intl.formatMessage(titlesIntl.textOf),
    rowsOptions: listOfRowsOptions,
    textShowRows: intl.formatMessage(titlesIntl.textShowRows),
    totalItems: filteredItems.length,
  }

  const measures = useTableMeasures({
    size:
      pagination.totalItems < pagination.tableSize
        ? pagination.totalItems
        : pagination.tableSize,
    density: 'comfortable',
  })

  function handleFiltersChange(statements = []) {
    let newData = items.slice()

    statements.forEach((st: any) => {
      if (!st || !st.object) return
      const { subject, verb, object } = st

      switch (subject) {
        case 'categorieLaw':
          if (verb === 'contains') {
            newData = newData.filter((item: any) => {
              return item[subject].includes(object)
            })
          } else if (verb === '=') {
            newData = newData.filter((item: any) => item[subject] === object)
          } else if (verb === '!=') {
            newData = newData.filter((item: any) => item[subject] !== object)
          }

          break

        default:
          break
      }
    })
    setFilteredItems(newData)
    setFilterStatements(statements)
  }

  const filterClear = intl.formatMessage(titlesIntl.filterClear)
  const filterAny = intl.formatMessage(titlesIntl.filterAny)
  const filterIs = intl.formatMessage(titlesIntl.filterIs)
  const filterIsNot = intl.formatMessage(titlesIntl.filterIsNot)
  const filterContains = intl.formatMessage(titlesIntl.filterContains)
  const filterApply = intl.formatMessage(titlesIntl.filterApply)

  const filters = {
    alwaysVisibleFilters: ['categorieLaw'],
    statements: filterStatements,
    onChangeStatements: handleFiltersChange,
    clearAllFiltersButtonLabel: filterClear,
    collapseLeft: true,
    submitFilterLabel: filterApply,
    options: {
      categorieLaw: {
        label: intl.formatMessage(titlesIntl.categoriesTableCategorieLaw),
        ...simpleInputVerbsAndLabel(),
      },
    },
  }

  function simpleInputObject({ values, onChangeObjectCallback }: any) {
    return (
      <Input
        value={values || ''}
        onChange={(e: any) => onChangeObjectCallback(e.target.value)}
      />
    )
  }

  function simpleInputVerbsAndLabel() {
    return {
      renderFilterLabel: (st: any) => {
        if (!st || !st.object) {
          // you should treat empty object cases only for alwaysVisibleFilters
          return filterAny
        }

        return `${st.verb === '='
          ? filterIs
          : st.verb === '!='
            ? filterIsNot
            : filterContains
          } ${st.object}`
      },
      verbs: [
        {
          label: filterIs,
          value: '=',
          object: {
            renderFn: simpleInputObject,
            extraParams: {},
          },
        },
        {
          label: filterIsNot,
          value: '!=',
          object: {
            renderFn: simpleInputObject,
            extraParams: {},
          },
        },
        {
          label: filterContains,
          value: 'contains',
          object: {
            renderFn: simpleInputObject,
            extraParams: {},
          },
        },
      ],
    }
  }

  const density = {
    label: 'Line density',
    compactLabel: 'Compact',
    regularLabel: 'Regular',
    comfortableLabel: 'Comfortable',
  }

  useEffect(() => {
    const filterBar = document.getElementById('vtex-table-v2__filter-bar')

    filterBar?.classList.remove('mb5')
  }, [])

  return (
    <div>
      <Table measures={measures} columns={columns} items={slicedItems}>
        <Table.Pagination {...pagination} />
        <Table.Toolbar>
          <Table.FilterBar {...filters} />
          <Table.Toolbar.ButtonGroup>
            <Table.Toolbar.ButtonGroup.Density {...density} />
          </Table.Toolbar.ButtonGroup>
        </Table.Toolbar>
      </Table>
      {isCategoryModalOpen && (
        <CategoriesTree
          idRow={rowCategoryClick}
          nameCategory={nameCategoryClick}
          items={items}
          setItems={setItems}
          closeModal={handleModalCategorieCatalog}
        />
      )}

      {isProductModalOpen && (
        <ProductProvider>
          <ProductSearch
            idRow={rowProductClick}
            nameProduct={nameProductClick}
            idProduct={idProductClick}
            items={items}
            setItems={setItems}
            closeModal={handleModalProducts}
          />
        </ProductProvider>
      )}
    </div>
  )
}

function usePagination(initialSize: number, itemsToPaginate: any) {
  const [state, setState] = useState({
    tableSize: initialSize,
    currentPage: 1,
    currentItemFrom: 1,
    currentItemTo: initialSize,
    slicedItems: [...itemsToPaginate].slice(0, initialSize),
  })

  /** resets state on items change */
  useEffect(() => {
    setState({
      tableSize: initialSize,
      currentPage: 1,
      currentItemFrom: 1,
      currentItemTo: initialSize,
      slicedItems: [...itemsToPaginate].slice(0, initialSize),
    })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [itemsToPaginate])

  /** gets the next page */
  const onNextClick = useCallback(() => {
    const newPage = state.currentPage + 1
    const itemFrom = state.currentItemTo + 1
    const itemTo = state.tableSize * newPage
    const newItems = [...itemsToPaginate].slice(itemFrom - 1, itemTo)

    setState({
      ...state,
      currentPage: newPage,
      currentItemFrom: itemFrom,
      currentItemTo: itemTo,
      slicedItems: newItems,
    })
  }, [state, itemsToPaginate])

  /** gets the previous page */
  const onPrevClick = useCallback(() => {
    if (state.currentPage === 0) return
    const newPage = state.currentPage - 1
    const itemFrom = state.currentItemFrom - state.tableSize
    const itemTo = state.currentItemFrom - 1
    const newItems = [...itemsToPaginate].slice(itemFrom - 1, itemTo)

    setState({
      ...state,
      currentPage: newPage,
      currentItemFrom: itemFrom,
      currentItemTo: itemTo,
      slicedItems: newItems,
    })
  }, [state, itemsToPaginate])

  /** deals rows change of Pagination component */
  const onRowsChange = useCallback(
    (_, value) => {
      const rowValue = parseInt(value, 10)

      setState({
        ...state,
        tableSize: rowValue,
        currentItemTo: rowValue,
        slicedItems: [...itemsToPaginate].slice(
          state.currentItemFrom - 1,
          rowValue
        ),
      })
    },
    [state, itemsToPaginate]
  )

  return {
    onNextClick,
    onPrevClick,
    onRowsChange,
    ...state,
  }
}

```


[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 admin-ley-gondolas-arg/react/components/SaveInMasterdata.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable @typescript-eslint/no-explicit-any */
// import { useIntl } from 'react-intl'

// import { titlesIntl } from '../utils/intl'
/* import { useState, useEffect } from 'react'
import { useMutation } from 'react-apollo'

import updateDocument from '../graphql/updateDocument.gql'
import createDocument from '../graphql/createDocument.gql' */

// eslint-disable-next-line max-params
export default async function SaveInMasterdata(
  items: CategoriesRow[],
  rowId: number,
  updateDocumentMutation: any,
  createDocumentMutation: any
) {
  const { idDocument, categorieLaw, categorieCatalog, bestLowerProduct } =
    items[rowId]

  const { id: idCategory, name: nameCategorieCatalog } = categorieCatalog

  const { id: idBestLowerProduct, name: nameBestLowerProduct } =
    bestLowerProduct

  const bodyMasterdata: BodySaveDocumentMasterData = {
    categorieLaw,
    categorieCatalog: nameCategorieCatalog,
    idCategory,
    nameBestLowerProduct,
    idBestLowerProduct,
  }

  let response

  try {
    if (idDocument) {
      response = await updateDocumentMutation({
        variables: { documentId: idDocument, body: bodyMasterdata },
      })
    } else {
      response = await createDocumentMutation({
        variables: { body: bodyMasterdata },
      })
    }

    return response
  } catch (error) {
    console.error(error)
  }
}

```


[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 admin-ley-gondolas-arg/react/graphql/getPaginationData.gql from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```graphql
query getPaginationData($term: String!, $page: Int!, $pageSize: Int!, $filters: ProductFilter) {
  products(pageSize: $pageSize, page: $page, term: $term, filters: $filters)
    @context(provider: "vtex.catalog-graphql") {
    paging{
      page
      perPage
      total
      pages
    }
  }
}

```


[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 admin-ley-gondolas-arg/react/graphql/updateDocument.gql from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation updateDocument(
  $documentId: String
  $body: BodyUpdateDocumentMasterData
) {
  updateDocument(documentId: $documentId, body: $body) {
    status
  }
}

```


[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 admin-ley-gondolas-arg/react/graphql/createDocument.gql from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation createDocument($body: BodyCreateDocumentMasterData) {
  createDocument(body: $body) {
    status
    data {
      Id
      Href
      DocumentId
    }
  }
}

```


[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 admin-ley-gondolas-arg/react/graphql/getProductsOfCategory.gql from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```graphql
query getProductsOfCategory($categoryTree: String, $from: Int!, $to: Int!, $params: String ) {
  getProductsOfCategory(categoryTree: $categoryTree, from: $from, to: $to, params: $params) {
    status
    data {
      productId
      productName
      brand
      categoryId
      pricePerUnit
      leyDeGondolas
      linkText
      items {
        itemId
        name
        images {
          imageId
          imageUrl
          imageText
        }
      }
    }
  }
}

```


[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 admin-ley-gondolas-arg/react/graphql/getCategoryTree.gql from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```graphql
query getCategoryTree {
  getCategoryTree {
    status
    data {
      id
      name
      hasChildren
      children {
        id
        name
        hasChildren
        children {
          id
          name
          hasChildren
          children {
            id
            name
            hasChildren
            children {
              id
              name
              hasChildren
              children {
                id
                name
                hasChildren
                children {
                  id
                  name
                  hasChildren
                  children {
                    id
                    name
                    hasChildren
                    children {
                      id
                      name
                      hasChildren
                      children {
                        id
                        name
                        hasChildren
                        children {
                          id
                          name
                          hasChildren
                          children {
                            id
                            name
                            hasChildren
                            children {
                              id
                              name
                              hasChildren
                              children {
                                id
                                name
                                hasChildren
                                children {
                                  id
                                  name
                                  hasChildren
                                  children {
                                    id
                                    name
                                    hasChildren
                                    children {
                                      id
                                      name
                                      hasChildren
                                      children {
                                        id
                                        name
                                        hasChildren
                                        children {
                                          id
                                          name
                                          hasChildren
                                          children {
                                            id
                                            name
                                            hasChildren
                                            children {
                                              id
                                              name
                                              hasChildren
                                              children {
                                                id
                                                name
                                                hasChildren
                                                children {
                                                  id
                                                  name
                                                  hasChildren
                                                  children {
                                                    id
                                                    name
                                                    hasChildren
                                                    children {
                                                      id
                                                      name
                                                      hasChildren
                                                      children {
                                                        id
                                                        name
                                                        hasChildren
                                                        children {
                                                          id
                                                          name
                                                          hasChildren
                                                          children {
                                                            id
                                                            name
                                                            hasChildren
                                                          }
                                                        }
                                                      }
                                                    }
                                                  }
                                                }
                                              }
                                            }
                                          }
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

```


[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 admin-ley-gondolas-arg/react/graphql/getData.gql from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```graphql
query getData {
  getData {
    status
    data {
      id
      categorieCatalog
      idCategory
      categorieLaw
      idBestLowerProduct
      nameBestLowerProduct
    }
  }
}

```


[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 admin-ley-gondolas-arg/react/store/context/ProductContext.tsx from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { createContext, useReducer } from 'react';
import { ProductReducer } from './../reducers/ProductReducer';

const initialState = {
  from: 1,
  to: 5,
  currentPage: 1,
  totalPages: 1,
  totalItems: 1,
  limit: 5,
  params: "",
  statements: []
}

export const ProductContext = createContext<{
  state: ProductContext;
  dispatch: React.Dispatch<any>;
}>({
  state: initialState,
  dispatch: () => null
});

export const ProductProvider: React.FC = ({ children }: any) => {
  const [state, dispatch] = useReducer(ProductReducer, initialState);
  return (
    <ProductContext.Provider value={{ state, dispatch }}>
      {children}
    </ProductContext.Provider>
  )
}

```


[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 admin-ley-gondolas-arg/react/store/reducers/ProductReducer.ts from the admin-ley-gondolas-arg VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const ProductReducer = (state: ProductContext, action: any) => {

  switch (action.type) {
    case 'INCREASE_PAGE':
      return {
        ...state,
        from: state.from + state.limit,
        to: state.to + state.limit,
        currentPage: state.currentPage + 1,
      }
    case 'DECREASE_PAGE':
      return {
        ...state,
        from: state.from - state.limit,
        currentPage: state.currentPage - 1,
      }
    case 'SET_LIMIT':
      return {
        ...state,
        limit: action.payload,
        from: 1,
        to: action.payload,
      }
    case 'SET_TOTAL_ITEMS':
      return {
        ...state,
        totalItems: action.payload,
      }
    case 'SET_TOTAL_PAGES':
      return {
        ...state,
        totalPages: action.payload,
      }
    case 'SET_PARAMS':
      return {
        ...state,
        params: action.payload,
        currentPage: 1,
        from: 1,
        to: state.limit
      }
    case 'RESET_PAGINATION':
      return {
        ...state,
        params: "",
        from: 1,
        to: state.limit,
        currentPage: 1,
      }
    case 'SET_STATEMENTS':
      return {
        ...state,
        statements: action.payload,
      }
    default:
      return state;
  }
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "editor.base-store-component.title": "IO Base App",
  "editor.base-store-component.description": "Um componente de demonstração para apps do VTEX IO",
  "editor.base-store-component.title.title": "Título",
  "editor.base-store-component.title.description": "Especifique um título personalizado",
  "base.title": "Olá, Mundo!!",
  "base.change-value": "Troque seu valor: {value}",
  "example": "Isto é um exemplo"
}
```


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

[Assistant]
Here's the implementation:

```json
{
  "editor.base-store-component.title": "IO Base App",
  "editor.base-store-component.description": "A demo component for IO apps",
  "editor.base-store-component.title.title": "Title",
  "editor.base-store-component.title.description": "Specify a custom title",
  "base.title": "Hello, World!!",
  "base.change-value": "Change your value: {value}",
  "example": "This is an 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 blocks-inspector/messages/context.json from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "editor.base-store-component.title": "Title of IO Base App component",
  "editor.base-store-component.description": "Description of IO Base App component",
  "editor.base-store-component.title.title": "Title of title property",
  "editor.base-store-component.title.description": "Description of title property",
  "base.title": "Base title message to be shown when title is not provided via CMS",
  "base.change-value": "Text to be shown beside input component typed value"
}
```


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

[Assistant]
Here's the implementation:

```json
{
  "editor.base-store-component.title": "IO Base App",
  "editor.base-store-component.description": "Un componente de demostración para aplicaciones IO.",
  "editor.base-store-component.title.title": "Título",
  "editor.base-store-component.title.description": "Especifique un título personalizado",
  "base.title": "¡Hola Mundo!",
  "base.change-value": "Cambia tu valor: {value}",
  "example": "Esto es un ejemplo"
}
```


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

[Assistant]
Here's the implementation:

```markdown
# VTEX IO Store Component Template

This demo component shows you how to make a simple yet complete VTEX IO store component.

It shows a simple demonstration of the following features:

- Declaring a component interface in `store/interfaces.json`.
- Declaring a schema to receive props via Storefront.
- Using the `messages` feature to have localized strings.
- Using an NPM package like `react-intl`
- Using another VTEX IO App like `vtex.styleguide`.
- Using CSS Modules to make your component customizable via CSS on a store theme.
- Using tachyons tokens to quickly style your components.
- Creating tests for your VTEX IO app.

```


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

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "test": "vtex-test-tools test",
    "lint": "tsc --noEmit && eslint --ext ts,tsx ."
  },
  "dependencies": {
    "@vtex/css-handles": "^1.0.0",
    "classnames": "^2.2.6",
    "ramda": "^0.26.1",
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-intl": "^2.7.2"
  },
  "devDependencies": {
    "@types/classnames": "^2.2.7",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.7.5",
    "@types/prop-types": "^15.7.0",
    "@types/ramda": "^0.26.5",
    "@types/react": "^16.9.2",
    "@vtex/test-tools": "^1.1.0",
    "apollo-client": "^2.5.1",
    "eslint": "^5.16.0",
    "eslint-config-vtex-react": "^4.1.0",
    "prettier": "^1.18.2",
    "tslint-eslint-rules": "^5.4.0",
    "typescript": "3.5.2"
  },
  "version": "0.2.1"
}

```


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

[User] Show me the implementation of blocks-inspector/react/Example.tsx from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState } from 'react'
import { Input } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'

import TranslatedTitle from './components/TranslatedTitle'

import styles from './styles.css'

const Example: StorefrontFunctionComponent<ExampleProps> = ({ title }) => {
  const [inputValue, setValue] = useState<string | null>(null)

  return (
    <div className={`${styles.container} flex flex-column pv6 ph4`}>
      <TranslatedTitle title={title} />
      <div className="t-body pv4">
        <FormattedMessage
          id="base.change-value"
          values={{ value: inputValue || '' }}
        />
      </div>
      <Input
        value={inputValue}
        onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
          setValue(e.target.value)
        }
      />
    </div>
  )
}

interface ExampleProps {
  title?: string
}

Example.schema = {
  title: 'editor.base-store-component.title',
  description: 'editor.base-store-component.description',
  type: 'object',
  properties: {
    title: {
      title: 'editor.base-store-component.title.title',
      description: 'editor.base-store-component.title.description',
      type: 'string',
      default: null,
    },
  },
}

export default 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 blocks-inspector/store/interfaces.json from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "base-store-component": {
    "component": "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 blocks-inspector/react/typings/storefront.d.ts from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

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

declare global {
  interface StorefrontFunctionComponent<P = {}> extends FunctionComponent<P> {
    getSchema?(props: P): object
    schema?: object
  }

  interface StorefrontComponent<P = {}, S = {}> extends Component<P, S> {
    getSchema?(props: P): object
    schema: object
  }
}

```


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

[Assistant]
Here's the implementation:

```typescript
/* Typings for `render-runtime` */
declare module 'vtex.render-runtime' {
  import { Component, ComponentType, ReactElement, ReactType } from 'react'

  export interface NavigationOptions {
    page: string
    params?: any
  }

  export interface RenderContextProps {
    runtime: {
      navigate: (options: NavigationOptions) => void
    }
  }

  interface ExtensionPointProps {
    id: string
    [key: string]: any
  }

  export const ExtensionPoint: ComponentType<ExtensionPointProps>

  interface ChildBlockProps {
    id: string
  }

  export const ChildBlock: ComponentType<ChildBlockProps>
  export const useChildBlock = function({ id: string }): object {}

  export const Helmet: ReactElement
  export const Link: ReactType
  export const NoSSR: ReactElement
  export const RenderContextConsumer: ReactElement
  export const canUseDOM: boolean
  export const withRuntimeContext: <TOriginalProps extends {}>(
    Component: ComponentType<TOriginalProps & RenderContextProps>
  ) => ComponentType<TOriginalProps>
}

```


[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 blocks-inspector/react/typings/css.d.ts from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  const css: any
  export default css
}

```


[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 blocks-inspector/react/typings/graphql.d.ts from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const value: DocumentNode
  export default value
}

```


[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 blocks-inspector/react/typings/vtex.styleguide.d.ts from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.styleguide' {
  import { ComponentType } from 'react'

  export const Input: ComponentType<InputProps>

  interface InputProps {
    [key: string]: 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 blocks-inspector/react/components/index.tsx from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { FormattedMessage } from 'react-intl'

const HelloWorld: FunctionComponent = () => {
  return (
    <div>
      <FormattedMessage id="example" />
    </div>
  )
}

export default HelloWorld

```


[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 blocks-inspector/react/components/TranslatedTitle.tsx from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { FormattedMessage } from 'react-intl'

// The b-s token makes the `b` class be applied only on mobile devices.
const TranslatedTile: FunctionComponent<TranslatedTileProps> = ({ title }) => {
  const titleText = title || <FormattedMessage id="base.title" />
  return (
    <div className="flex flex-grow-1 justify-center b-s">
      <span className="t-heading-4">{titleText}</span>
    </div>
  )
}

interface TranslatedTileProps {
  title?: string
}

export default TranslatedTile

```


[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 blocks-inspector/react/__tests__/index.test.tsx from the blocks-inspector VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render } from '@vtex/test-tools/react'
import Component from '../components/index'

describe('HelloWorld Component', () => {
  const { getByText } = render(<Component />)

  it('should render the example in TypeScript', () => {
    expect(getByText(/This is an example/)).toBeDefined()
  })
})

```


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

[Assistant]
Here's the implementation:

```markdown
# Outbrain

Outbrain helps over 1 billion people discover content, products and services that may be of interest to them.
For more information please visit, [Outbrain](https://www.outbrain.com/) website.

## App Installation
Open the VTEX APP Store and install the Outbrain app on your store.

or

Run the following command:

```sh
vtex install vtex.outbrain@0.x
```

Next, open the app settings on your admin and fill the form with your Outbrain information.
```


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

[Assistant]
Here's the implementation:

```tsx
import { canUseDOM } from 'vtex.render-runtime'
import { PixelMessage } from './typings/events'

export function handleEvents(e: PixelMessage) {
  switch (e.data.eventName) {
    case 'vtex:pageView': {

    }
    default: {
      return
    }
  }
}

if (canUseDOM) {
  window.addEventListener('message', handleEvents)
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "ramda": "^0.26.1"
  },
  "devDependencies": {
    "@types/graphql": "^14.2.0",
    "@types/jest": "^24.0.11",
    "@types/node": "^11.13.0",
    "@types/ramda": "^0.26.5",
    "@vtex/test-tools": "^1.1.0",
    "eslint": "^5.16.0",
    "eslint-config-vtex-react": "^4.1.0",
    "prettier": "^1.18.2",
    "tslint-eslint-rules": "^5.4.0",
    "typescript": "3.5.2"
  },
  "version": "0.1.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 outbrain/store/interfaces.json from the outbrain VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "pixel.outbrain": {
    "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 outbrain/react/typings/events.d.ts from the outbrain VTEX app.

[Assistant]
Here's the implementation:

```typescript
export interface PixelMessage extends MessageEvent {
  data:
    | ProductViewData
    | ProductClickData
    | OrderPlacedData
    | PageViewData
    | ProductImpressionData
    | AddToCartData
    | RemoveToCartData
}

export interface EventData {
  event: string
  eventName: string
  currency: string
}

export interface PageViewData extends EventData {
  event: 'pageView'
  eventName: 'vtex:pageView'
  pageTitle: string
  pageUrl: string
  referrer: string
}

export interface AddToCartData extends EventData {
  event: 'addToCart'
  eventName: 'vtex:addToCart'
  items: CartItem[]
}

export interface RemoveToCartData extends EventData {
  event: 'removeFromCart'
  eventName: 'vtex:removeFromCart'
  items: CartItem[]
}

export interface OrderPlacedData extends Order, EventData {
  event: 'orderPlaced'
  eventName: 'vtex:orderPlaced'
}

export interface ProductViewData extends EventData {
  event: 'productView'
  eventName: 'vtex:productView'
  product: Product
}

export interface ProductClickData extends EventData {
  event: 'productClick'
  eventName: 'vtex:productClick'
  product: Product
}

export interface ProductImpressionData extends EventData {
  event: 'productImpression'
  eventName: 'vtex:productImpression'
  impressions: Impression[]
  product?: Product // deprecated, use impressions list!
  position?: number // deprecated, use impressions list!
  list: string
}

interface CartItem {
  skuId: string
  variant: string
  price: number
  name: string
  quantity: number
  productRefId: string
  brand: string
  category: string
}

export interface Order {
  currency: string
  accountName: string
  orderGroup: string
  salesChannel: string
  coupon: string
  visitorType: string
  visitorContactInfo: string[]
  visitorAddressState: string
  visitorAddressCountry: string
  visitorAddressPostalCode: string
  transactionId: string
  transactionDate: string
  transactionAffiliation: string
  transactionTotal: number
  transactionShipping: number
  transactionSubtotal: number
  transactionDiscounts: number
  transactionTax: number
  transactionCurrency: string
  transactionPaymentType: PaymentType[]
  transactionShippingMethod: ShippingMethod[]
  transactionProducts: ProductOrder[]
  transactionPayment: {
    id: string
  }
}

export interface Impression {
  product: Product
  position: number
}

interface PaymentType {
  group: string
  paymentSystemName: string
  installments: number
  value: number
}

interface ShippingMethod {
  itemId: string
  selectedSla: string
}

interface ProductOrder {
  id: string
  name: string
  sku: string
  skuRefId: string
  skuName: string
  productRefId: string
  ean: string
  slug: string
  brand: string
  brandId: string
  seller: string
  sellerId: string
  category: string
  categoryId: string
  categoryTree: string[]
  categoryIdTree: string[]
  priceTags: PriceTag[]
  originalPrice: number
  price: number
  sellingPrice: number
  tax: number
  quantity: number
  components: any[]
  measurementUnit: string
  unitMultiplier: number
}

interface PriceTag {
  identifier: string
  isPercentual: boolean
  value: number
}

interface Product {
  brand: string
  categoryId?: string // inconsistency
  categories: string[]
  productId: string
  productName: string
  selectedSku?: string // inconsistency
  items: Item[]
  sku: Item
  [key: string]: any
}

interface Item {
  itemId: string
  name: string
  seller?: Seller
  [key: string]: any
}

interface Seller {
  commertialOffer: CommertialOffer
  [key: string]: any
}

interface CommertialOffer {
  Price: number
  [key: string]: 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 outbrain/react/typings/vtex.render-runtime.d.ts from the outbrain VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.render-runtime' {
  export const canUseDOM: boolean
}

```


[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 outbrain/react/typings/global.d.ts from the outbrain VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface Window extends Window {
  dataLayer: 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 calling-commerce-apis-example/docs/README.md from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```markdown
# Service Example

Service Example used in Partner Training Session.
```


[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 calling-commerce-apis-example/node/service.json from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 2,
  "minReplicas": 2,
  "maxReplicas": 4,
  "workers": 1,
  "routes": {
    "validateSku": {
      "path": "/_v/validate-sku/:id",
      "public": true
    },
    "validateCollection": {
      "path": "/_v/validate-collection/:id",
      "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 calling-commerce-apis-example/node/package.json from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "@vtex/clients": "^2.18.0",
    "co-body": "^6.0.0",
    "ramda": "^0.25.0"
  },
  "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.6",
    "@vtex/test-tools": "^1.0.0",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "3.9.7"
  },
  "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 calling-commerce-apis-example/node/index.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

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

import { Clients } from './clients'
import { validateCollectionProps } from './middlewares/validateCollection'
import { validateProductTitle } from './middlewares/validateProductTitle'

const TIMEOUT_MS = 800

// 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,
    },
  },
}

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 {
    id: number
  }
}

// Export a service that defines route handlers and client options.
export default new Service({
  clients,
  routes: {
    validateSku: method({
      GET: [validateProductTitle],
    }),
    validateCollection: method({
      GET: [validateCollectionProps],
    }),
  },
})

```


[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 calling-commerce-apis-example/node/clients/collection.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

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

import type { Collection } from '../typings/collection'

export class CollectionClient extends JanusClient {
  public async getCollection(collectionId: string) {
    const collection = await this.http.get<Collection>(
      `/api/catalog/pvt/collection/${collectionId}`,
      {
        headers: { VtexIdclientAutCookie: this.context.authToken },
      }
    )

    return collection
  }
}

```


[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 calling-commerce-apis-example/node/clients/index.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

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

import { CollectionClient } from './collection'

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

  public get collection() {
    return this.getOrSet('collection', CollectionClient)
  }
}

```


[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 calling-commerce-apis-example/node/typings/collection.d.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
export interface Collection {
  Id: number
  Name: string
  Description: string
  Searchable: boolean
  Highlight: boolean
  DateFrom: string
  DateTo: string
  TotalProducts: number
  Type: string
}

```


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

[User] Show me the implementation of calling-commerce-apis-example/node/middlewares/validateProductTitle.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { validateSku } from '../utils/validateSku'

export async function validateProductTitle(
  ctx: Context,
  next: () => Promise<unknown>
) {
  const {
    vtex: {
      route: {
        params: { id },
      },
    },
    clients: { catalog },
  } = ctx

  console.info('Received sku id:', id)

  const sku = await catalog.getSkuById(id.toString())

  if (!sku) {
    ctx.status = 404

    return
  }

  console.info('Sku:', sku)

  ctx.status = 200
  ctx.body = {
    skuId: sku.Id,
    name: sku.Name,
    result: validateSku(sku),
  }
  ctx.set('Cache-Control', 'no-cache')

  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 calling-commerce-apis-example/node/middlewares/validateCollection.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { validateCollection } from '../utils/validateCollection'

export async function validateCollectionProps(
  ctx: Context,
  next: () => Promise<unknown>
) {
  const {
    vtex: {
      route: {
        params: { id },
      },
    },
    clients: { collection },
  } = ctx

  console.info('Received collection id:', id)

  const col = await collection.getCollection(id.toString())

  if (!col) {
    ctx.status = 404

    return
  }

  console.info('Collection:', col)

  ctx.status = 200
  ctx.body = {
    id: col.Id,
    description: col.Description,
    result: validateCollection(col),
  }
  ctx.set('Cache-Control', 'no-cache')

  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 calling-commerce-apis-example/node/utils/validateCollection.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Collection } from '../typings/collection'

export const validateCollection = (collection: Collection) => {
  if (collection.TotalProducts < 5) {
    return `A coleção é muito pequena, possui menos de 5 produtos! (${collection.TotalProducts} produtos).`
  }

  return 'A coleção está otimizada!'
}

```


[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 calling-commerce-apis-example/node/utils/validateSku.ts from the calling-commerce-apis-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { GetSkuResponse } from '@vtex/clients'

export const validateSku = (sku: GetSkuResponse) => {
  if (sku.Name.length < 20) {
    return `O nome do Sku está muito curto! (${sku.Name.length} characteres). O nome deve possuir entre 20 e 80 caracteres.`
  }

  if (sku.Name.length > 80) {
    return `O nome do Sku está muito longo! (${sku.Name.length} characteres). O nome deve possuir entre 20 e 80 caracteres.`
  }

  return 'O nome do Sku está otimizado!'
}

```


[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 calling-commerce-apis-example/node/__tests__/simple.test.ts from the calling-commerce-apis-example 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 graphql-example/docs/README.md from the graphql-example VTEX app.

[Assistant]
Here's the implementation:

```markdown
# GraphQL Example

A reference app implementing a VTEX IO service with GraphQL resolvers.

![GraphQL Server Architecture](https://user-images.githubusercontent.com/18706156/77382285-bf2d6c80-6d5e-11ea-9f39-2c30b3ec3672.jpg)

We use [**Apollo Server**](https://www.apollographql.com/docs/apollo-server/) as the underlying framework along with some tweaks for our platform.

For communicating with external services or other VTEX IO apps, we 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 `graphq/schema.graphql` and `node/index.ts` and follow the comments and imports!**

When _linking_ a GraphQL app, our CLI will automatically provide you a **[GraphiQL](https://github.com/graphql/graphiql) endpoint**, for you to test the functionalities. You can also access a specific app's GraphiQL through the **GraphQL IDE** section on the admin site (as long as the [admin-graphql-ide](https://github.com/vtex-apps/admin-graphql-ide) app is installed on that account).

Queries, mutations and types defined on the `schema.graphql` will have theirs implementation on the `Service` object exported on `node/index.ts`.

> For more information about our GraphQL services, check [**graphql-server**](https://github.com/vtex/graphql-server) and its _Wiki_ (VTEX internal only).

## About GraphQL

It's important to understand what GraphQL is and how it compares with other popular API standards, such as REST.

There are many resources out there that can help understand the basics, so let's list a few of them here:

- [GraphQL website](http://graphql.org/learn/)
- [How to GraphQL](https://www.howtographql.com/basics/1-graphql-is-the-better-rest/)

## Recipes

### Configuring cache for specific queries

Caching is one of the most important strategies for making applications **fast and responsive**. This is achieved by setting **cache control hints** in the GraphQL schema. Our GraphQL Server computes a cache expiration date by combining `@cacheControl` declarations from the fields returned by a specific request, whereas the props `maxAge` and `scope` can be defined. It errs on the safe side for requests with multiple `@cacheControl` declarations, so shorter `maxAge` results override longer, and `PRIVATE` scope overrides `PUBLIC`.

- There are currently tree possible `maxAge`s _(LONG, MEDIUM and SHORT)_ and two possible `scope`s _(PRIVATE and PUBLIC)_.

Suppose that we want to create a simple catalog app that has two types, `type Product` and `type Order`. Since products don't change quickly throughout the day and anyone can see them, they can be cached with a maxAge `LONG` in a `PUBLIC` scope. Order, on the other hand, is a per user entity and should have a PRIVATE scope. To achieve this behavior, the following annotations must be included to the schema

```graphql
type Product @cacheControl(maxAge: LONG, scope: PUBLIC) {
  id: ID!
  name: String
  description: String
}

type Order @cacheControl(scope: PRIVATE) {
  id: ID!
  statusDescription: String
  description: String
}

type Query {
  listOrders: [Order]
  listProducts: [Product]
}
```

> **Note** to know more on how these cache hints work, take a look at the [Apollo Server docs for caching](https://www.apollographql.com/docs/apollo-server/performance/caching/)

Since our GraphQL implementation uses a CDN (Cloud-Front) to cache query responses, `PRIVATE` queries should land in a different endpoint from `PUBLIC` ones. Each endpoint have some configurations tweaks in the CDN and may lead to different behaviors. For example, to receive cookies in the backend, you need to be in a private route.

### Caching requests when using public endpoint

Requests to `graphql-server` using public endpoints are not cacheable, so they are given `cache-control` with `no-cache`. The way to override this behavior is to send the header `'x-vtex-cacheable': 'true'` on request.

### Resolving conflicts (`@context` directive)

Let's say that another app called `rewards-graphql` also defines a field named `products` inside the `Query` type. If both apps live on the same workspace/account it will cause some requests to fail, since our GraphQL server won't be able to automatically figure out which app should resolve that query.

For this use case we support a special directive called `@context`, which GraphQL clients can use to provide additional information to resolve these kind of conflicts.

#### Specifying provider

If the client knows about a conflict (or in any case, for precaution), it can specify which app defined the field it's requesting. In the example we've mentioned above, with that new `rewards-graphql` app, the client could send the query like this:

```graphql
query getProducts {
  products @context(provider: "vtex.products-graphql") {
    name
  }
}
```

This declares that we want to use the definition of `products` from `products-graphql`, not from `rewards-graphql`, so that it can properly rename and execute it.

#### Specifying sender

In some cases it might be hard for a client to know that a conflict can happen, since an app doesn't know about all other apps that may be running on a workspace, it only knows about its own direct dependencies. At the same time, we'd like to restrict apps so that they can only access types/fields defined by apps they directly depend on.

Both these problems can be solved by using the `@context` directive again, but this time using the `sender` argument. Basically, apps sending requests to `graphql-server` should include this directive announcing their names, so that it can restrict which parts of the schema can be accessed. Note that restricting the access also makes it easier for apps to know exactly when they'd need to specify a `provider`, since conflicts with apps they don't know about will never happen.

So, let's say that an app called `client-app`, that depends only on `products-graphql` is sending a GraphQL request. Even if `rewards-graphql` is running in the current workspace it won't need to specify the provider anymore, just set the `sender`.

```graphql
{
  products @context(sender: "vtex.client-app@1.2.3") {
    name
  }
}
```

**Note:** If you are requesting GraphQL data from React apps that uses the `react` builder the `sender` argument **is already baked** into every request it makes.

## 🗎 GraphQL documentation

This project use as dependency the [graphql-markdown](https://github.com/exogen/graphql-markdown) project, to generate markdown documentation based on GraphQL schema.

Do you need run this command below, in your terminal, to generate the documentation:

```bash
yarn graphql-markdown
```

## Splunk Dashboard

We have an (for now, VTEX-only, internal) Splunk dashboard to show all metrics related to your app. You can find it at:

https://splunk72.vtex.com/en-US/app/vtex_io_apps/node_app_metrics

After linking this app and making some requests, you can select `vtex.graphql-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**.

```


[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 graphql-example/graphql/schema.graphql from the graphql-example VTEX app.

[Assistant]
Here's the implementation:

```graphql
# To really understand GraphQL, go to https://graphql.org/learn/

type Book {
  authors: [String!]
  cacheId: ID!
  id: ID!
  name: String
}

# It is necessary to generate input types for creating books
# ref: http://graphql.org/graphql-js/mutations-and-input-types/
input BookInput {
  authors: [String!]
  cacheId: ID
  id: ID
  name: String
}

type Query {
  # Cache control can only be set at root fields
  book(id: ID!): Book
  @auth(scope: PUBLIC)
  books(from: Int = 0, to: Int = 4): [Book] @cacheControl(scope: PUBLIC, maxAge: SHORT)
  @auth(scope: PUBLIC)
  total: Int
  @auth(scope: PUBLIC)

  """
  Returns a markdown source given an id
  """
  source(id: ID!): String
  @auth(scope: PUBLIC)
}

type Mutation {
  # You should always return the whole object in a mutation, not only a boolean. This will help in browser caching
  delete(id: String): Boolean
  @auth(scope: PUBLIC)
  editBook(id: ID!, book: BookInput!): Book
  @auth(scope: PUBLIC)
  newBook(book: BookInput!): Book
  @auth(scope: PUBLIC)
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 1,
  "minReplicas": 2,
  "maxReplicas": 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 graphql-example/node/package.json from the graphql-example VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "ramda": "^0.26.1"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",
    "@types/ramda": "types/npm-ramda#dist",
    "@vtex/api": "^7.0.0",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "5.5.3"
  },
  "scripts": {
    "lint": "tsc --noEmit && tslint -c tslint.json './**/*.ts'"
  },
  "version": "0.4.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 graphql-example/node/index.ts from the graphql-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ParamsContext, RecorderState, ServiceContext } from '@vtex/api'
import { Service } from '@vtex/api'
import { prop } from 'ramda'

import { Clients } from './clients'
import { book } from './resolvers/book'
import { books } from './resolvers/books'
import { deleteBook } from './resolvers/delete'
import { editBook } from './resolvers/editBook'
import { newBook } from './resolvers/newBook'
import { source } from './resolvers/source'
import { total } from './resolvers/total'

const MEDIUM_TIMEOUT_MS = 2 * 1000

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>
}

// Export a service that defines resolvers and clients' options
export default new Service<Clients, RecorderState, ParamsContext>({
  clients: {
    implementation: Clients,
    options: {
      default: {
        timeout: MEDIUM_TIMEOUT_MS,
      },
    },
  },
  graphql: {
    resolvers: {
      Book: {
        cacheId: prop('id'),
      },
      Mutation: {
        delete: deleteBook,
        editBook,
        newBook,
      },
      Query: {
        book,
        books,
        source,
        total,
      },
    },
  },
})

```


[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 graphql-example/node/clients/index.ts from the graphql-example VTEX app.

[Assistant]
Here's the implementation:

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

import { BookClient } from './book'
import { MarkdownClient } from './markdown'

export class Clients extends IOClients {
  public get book() {
    return this.getOrSet('book', BookClient)
  }

  public get markdown() {
    return this.getOrSet('markdown', MarkdownClient)
  }
}

```


[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 graphql-example/node/typings/markdown.d.ts from the graphql-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.md' {
  const content = ''

  export default content
}

```


[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 graphql-example/node/typings/custom.d.ts from the graphql-example VTEX app.

[Assistant]
Here's the implementation:

```typescript
export interface Book {
  authors: string[]
  cacheId?: string
  id: string
  name: string
}

export interface BookInput {
  name: Book['name']
  authors: Book['authors']
}

export type Maybe<T> = T | void

```