[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 giftcard-ui/react/cards.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { intlShape, injectIntl } from 'react-intl'
import { withRuntimeContext } from 'render'

import { getCards, createCard } from './actions/cards'

import Card from './card'
import AdminLoading from './components/AdminLoading'

import { PageHeader, Table, Badge } from 'vtex.styleguide'

class Cards extends Component {
  static contextTypes = {
    culture: PropTypes.object,
  }

  constructor() {
    super()

    this.state = {
      cards: [],
      searchValue: '',
      showCardForm: false,
      isCardCreation: false,
      cardData: {},
    }
  }

  static contextTypes = {
    culture: PropTypes.object,
  }

  componentDidMount() {
    window.postMessage({ action: { type: 'STOP_LOADING' } }, '*')

    const data = {
      account: this.props.runtime.account,
      workspace: this.props.runtime.workspace,
    }
    this.props.getCards(data)
  }

  componentDidUpdate(prevProps) {
    if (this.props.cards !== prevProps.cards) {
      this.setState({ cards: this.props.cards })
    }
  }

  handleInputSearchChange = e => {
    this.setState({ searchValue: e.target.value })
  }

  handleInputSearchClear = () => {
    this.setState({ searchValue: '' })
  }

  handleInputSearchSubmit = e => {
    e.preventDefault()
    console.log('handleInputSearchSubmit')
  }

  handleNextClick = () => {}
  handlePrevClick = () => {}

  handleNewCard = () => {
    this.setState({ showCardForm: true, isCardCreation: true, cardData: {} })
  }

  handleCloseAddCard = () => {
    this.setState({ showCardForm: false })
  }

  handleRowClick = data => {
    this.setState({
      cardData: data.rowData,
      showCardForm: true,
      isCardCreation: false,
    })
  }

  handleCardCreation = data => {
    const d = {
      account: this.props.runtime.account,
      workspace: this.props.runtime.workspace,
    }
    this.props.createCard(d, data)
    this.handleCloseAddCard()
  }

  render() {
    const { culture } = this.context
    const { intl, isLoading } = this.props
    const { showCardForm } = this.state

    const schema = {
      properties: {
        id: {
          type: 'string',
          title: 'Id',
          width: 60,
          cellRenderer: ({ cellData }) => (
            <div className="ph4 pre truncate hidden">{cellData}</div>
          ),
        },
        balance: {
          type: 'string',
          headerRenderer: () => (
            <div className="ph4 tr">
              {intl.formatMessage({ id: 'cards.table.header.balance' })}
            </div>
          ),
          cellRenderer: ({ cellData }) => (
            <div className="ph4 tr">
              {intl.formatNumber(cellData, {
                style: 'currency',
                currency: culture.currency,
              })}
            </div>
          ),
        },
        emissionDate: {
          type: 'date-time',
          title: intl.formatMessage({ id: 'cards.table.header.emissionDate' }),
          cellRenderer: ({ cellData }) => (
            <div className="ph4">
              {intl.formatDate(cellData, {
                day: 'numeric',
                month: 'short',
                year: 'numeric',
              })}
            </div>
          ),
        },
        expiringDate: {
          type: 'date-time',
          title: intl.formatMessage({ id: 'cards.table.header.expiringDate' }),
          cellRenderer: ({ cellData }) => (
            <div className="ph4">
              {intl.formatDate(cellData, {
                day: 'numeric',
                month: 'short',
                year: 'numeric',
              })}
            </div>
          ),
        },
        active: {
          type: 'string',
          title: intl.formatMessage({ id: 'cards.table.header.status' }),
          cellRenderer: ({ cellData }) => (
            <div className="ph4">
              {cellData === 'true' ? (
                <Badge type="success">
                  {intl.formatMessage({ id: 'active' })}
                </Badge>
              ) : (
                <Badge>{intl.formatMessage({ id: 'inactive' })}</Badge>
              )}
            </div>
          ),
        },
      },
    }

    return (
      <div
        className={`bg-muted-5 h-100 relative ${
          showCardForm ? 'overflow-hidden' : ''
        }`}
      >
        {isLoading && <AdminLoading />}

        <PageHeader title={intl.formatMessage({ id: 'cards.title' })} />

        <div className="pa7">
          <div className="bg-base pa7 br3">
            <Table
              schema={schema}
              items={this.state.cards}
              onRowClick={this.handleRowClick}
              toolbar={{
                inputSearch: {
                  value: this.state.searchValue,
                  placeholder: intl.formatMessage({ id: 'search.by.id' }),
                  onChange: this.handleInputSearchChange,
                  onClear: this.handleInputSearchClear,
                  onSubmit: this.handleInputSearchSubmit,
                },
                newLine: {
                  label: intl.formatMessage({ id: 'new' }),
                  handleCallback: this.handleNewCard,
                },
              }}
              pagination={{
                onNextClick: this.handleNextClick,
                onPrevClick: this.handlePrevClick,
                currentItemFrom: 1,
                currentItemTo: 10,
                textOf: intl.formatMessage({ id: 'textOf' }),
                textShowRows: intl.formatMessage({ id: 'textShowRows' }),
                totalItems: this.state.cards.length,
                rowsOptions: [5, 10, 15, 20],
              }}
            />
          </div>
        </div>

        {showCardForm && (
          <Card
            onOverlayClick={this.handleCloseAddCard}
            onCreateCardClick={this.handleCardCreation}
            cardData={this.state.cardData}
            isCardCreation={this.state.isCardCreation}
          />
        )}
      </div>
    )
  }
}

Cards.defaultProps = {
  isLoading: true,
  cards: [],
}

Cards.propTypes = {
  intl: intlShape.isRequired,
  getCards: PropTypes.func.isRequired,
  createCard: PropTypes.func.isRequired,
  isLoading: PropTypes.bool,
  cards: PropTypes.array,
  runtime: PropTypes.any,
}

const mapStateToProps = state => ({
  isLoading: state.cardsReducer.isLoading,
  cards: state.cardsReducer.cards,
})

export default injectIntl(
  connect(
    mapStateToProps,
    { getCards, createCard },
  )(withRuntimeContext(Cards)),
)

```


[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 giftcard-ui/react/root.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import PropTypes from 'prop-types'
import { Provider } from 'react-redux'
import configureStore from './store/configureStore'
import Cards from './cards'

const store = configureStore()

export default class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Cards />
      </Provider>
    )
  }
}

Root.propTypes = {
  children: PropTypes.node,
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.giftcard",
  "version": null,
  "scripts": {},
  "dependencies": {
    "axios": "^0.18.0",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.2.2",
    "redux": "^3.7.2",
    "redux-devtools-extension": "^2.13.2",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.2.0"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-eslint": "^8.2.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "eslint": "^4.19.1",
    "eslint-config-vtex": "^8.0.0",
    "eslint-config-vtex-react": "^3.0.1",
    "eslint-plugin-import": "^2.10.0",
    "eslint-plugin-react": "^7.0.0",
    "prop-types": "^15.5.10",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "react-intl": "^2.4.0",
    "redux-mock-store": "^1.5.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 giftcard-ui/react/card.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { intlShape, injectIntl } from 'react-intl'

import { fields } from './constants'
import { Input, Button } from 'vtex.styleguide'

class Card extends Component {
  constructor(props) {
    super(props)

    const cardData = props.cardData

    this.state = {
      relationName: cardData.relationName || '',
      emissionDate: cardData.emissionDate || '',
      expiringDate: cardData.expiringDate || '',
      caption: cardData.caption || '',
      redemptionCode: cardData.redemptionCode || '',
      userdocument: cardData.userdocument || '',
      conditions: cardData.conditions || '',
      balance: cardData.balance || '',
      group: cardData.group || '',
      active: cardData.active || '',
    }
  }

  handleInputChange = e => {
    const name = `${e.target.name}`
    const value = e.target.value
    this.setState({ [name]: value })
  }

  handleCardCreation = () => {
    this.props.onCreateCardClick(this.state)
  }

  render() {
    const { intl, onOverlayClick, isCardCreation } = this.props

    return (
      <div className="absolute bottom-0 right-0 left-0 top-0 w-100 h-100 z-999">
        <div
          style={{ zIndex: '1001', background: 'rgba(0, 0, 0, 0.75)' }}
          className="flex absolute items-stretch justify-end w-50 bottom-0 right-0 left-0 top-0"
          onClick={onOverlayClick}
        />
        <div
          style={{
            zIndex: '1002',
            boxShadow: '0 12px 15px 0 rgba(0,0,0,0.25)',
          }}
          className="absolute w-50 pa6 bottom-0 right-0 top-0 overflow-x-auto bg-white"
        >
          <h1>
            {intl.formatMessage({
              id: isCardCreation ? 'newCard.title' : 'cardDetails.title',
            })}
          </h1>

          {fields.map(field => (
            <div key={field} className="mb5">
              {isCardCreation ? (
                <Input
                  onChange={this.handleInputChange}
                  value={this.state[field].toString()}
                  name={field}
                  label={intl.formatMessage({ id: `newCard.label.${field}` })}
                />
              ) : (
                <div>
                  <label>
                    {intl.formatMessage({ id: `newCard.label.${field}` })}
                  </label>
                  <div>{this.state[field]}</div>
                </div>
              )}
            </div>
          ))}

          {isCardCreation && (
            <div className="flex flex-row justify-end">
              <div className="mr4">
                <Button onClick={onOverlayClick} variation="tertiary">
                  {intl.formatMessage({ id: 'cancel' })}
                </Button>
              </div>
              <Button onClick={this.handleCardCreation}>
                {intl.formatMessage({ id: 'create' })}
              </Button>
            </div>
          )}
        </div>
      </div>
    )
  }
}

Card.defaultProps = {
  cardData: {},
}

Card.propTypes = {
  intl: intlShape,
  cardData: PropTypes.object,
  isCardCreation: PropTypes.bool,
  onOverlayClick: PropTypes.func.isRequired,
  onCreateCardClick: PropTypes.func.isRequired,
}

export default injectIntl(Card)

```


[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 giftcard-ui/react/locales/pt.json from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "cancel": "cancelar",
  "create": "gerar",
  "new": "novo",
  "active": "Ativo",
  "inactive": "Inativo",

  "search.by.id": "Pesquisa por ID de cartão",
  "textOf": "de",
  "textShowRows": "mostrar linhas",

  "cards.title": "Gift Cards",
  "cards.table.header.balance": "Saldo",
  "cards.table.header.emissionDate": "Data de emissão",
  "cards.table.header.expiringDate": "Data de vencimento",
  "cards.table.header.status": "Estado",

  "newCard.title": "Novo Gift Card",
  "newCard.label.relationName": "Nome da relação",
  "newCard.label.emissionDate": "Data de emissão",
  "newCard.label.expiringDate": "Data de vencimento",
  "newCard.label.caption": "Caption",
  "newCard.label.redemptionCode": "Código de redenção",
  "newCard.label.userdocument": "Documento do usuário",
  "newCard.label.conditions": "Condições",
  "newCard.label.balance": "Saldo",
  "newCard.label.group": "Groupo",
  "newCard.label.active": "Ativo",

  "cardDetails.title": "Detalhes do Gift Card"
}

```


[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 giftcard-ui/react/locales/en.json from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "cancel": "cancel",
  "create": "create",
  "new": "new",
  "active": "Active",
  "inactive": "Inactive",

  "search.by.id": "Search by card id",
  "textOf": "de",
  "textShowRows": "show rows",

  "cards.title": "Gift Cards",
  "cards.table.header.balance": "Balance",
  "cards.table.header.emissionDate": "Emission date",
  "cards.table.header.expiringDate": "Expiring date",
  "cards.table.header.status": "Status",

  "newCard.title": "New Card",
  "newCard.label.relationName": "Relation name",
  "newCard.label.emissionDate": "Emission date",
  "newCard.label.expiringDate": "Expiring date",
  "newCard.label.caption": "Caption",
  "newCard.label.redemptionCode": "Redemption code",
  "newCard.label.userdocument": "User document",
  "newCard.label.conditions": "Conditions",
  "newCard.label.balance": "Balance",
  "newCard.label.group": "Group",
  "newCard.label.active": "Active",

  "cardDetails.title": "Gift Card Details"
}

```


[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 giftcard-ui/react/locales/es.json from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "cancel": "cancelar",
  "create": "crear",
  "new": "nuevo",
  "active": "Activo",
  "inactive": "Inactivo",

  "search.by.id": "Búsqueda por identificación de tarjeta",
  "textOf": "de",
  "textShowRows": "mostrar filas",

  "cards.title": "Gift Cards",
  "cards.table.header.balance": "Saldo",
  "cards.table.header.emissionDate": "Fecha de emisión",
  "cards.table.header.expiringDate": "Fecha de vencimiento",
  "cards.table.header.status": "Estado",

  "newCard.title": "Nuevo Gift Card",
  "newCard.label.relationName": "Nombre de la relación",
  "newCard.label.emissionDate": "Fecha de emisión",
  "newCard.label.expiringDate": "Fecha de caducidad",
  "newCard.label.caption": "Caption",
  "newCard.label.redemptionCode": "Codigo de redención",
  "newCard.label.userdocument": "Documento de usuario",
  "newCard.label.conditions": "Condiciones",
  "newCard.label.balance": "Saldo",
  "newCard.label.group": "Groupo",
  "newCard.label.active": "Activo",

  "cardDetails.title": "Detalles de lo Gift Card"
}

```


[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 giftcard-ui/react/constants/index.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
export const fields = [
  'relationName',
  'emissionDate',
  'expiringDate',
  'caption',
  'redemptionCode',
  'userdocument',
  'conditions',
  'balance',
  'group',
  'active',
]

```


[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 giftcard-ui/react/components/AdminLoading.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'

class AdminLoading extends React.Component {
  componentDidMount() {
    window.postMessage({ action: { type: 'START_LOADING' } }, '*')
  }

  componentWillUnmount() {
    window.postMessage({ action: { type: 'STOP_LOADING' } }, '*')
  }

  render() {
    return null
  }
}
export default AdminLoading

```


[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 giftcard-ui/react/actions/types.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
export const REQUEST_CARDS = 'REQUEST_CARDS'
export const RECEIVE_CARDS_SUCCESS = 'RECEIVE_CARDS_SUCCESS'
export const RECEIVE_CARDS_ERROR = 'RECEIVE_CARDS_ERROR'

export const REQUEST_CARD_CREATION = 'REQUEST_CARD_CREATION'
export const RECEIVE_CARD_CREATION_SUCCESS = 'RECEIVE_CARD_CREATION_SUCCESS'
export const RECEIVE_CARD_CREATION_ERROR = 'RECEIVE_CARD_CREATION_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 giftcard-ui/react/reducers/index.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { combineReducers } from 'redux'

import cardsReducer from './cards'

const rootReducer = combineReducers({
  cardsReducer,
})

export default rootReducer

```


[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 giftcard-ui/react/store/configureStore.prod.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from '../reducers'

const finalCreateStore = compose(applyMiddleware(thunk))(createStore)

const configureStore = initialState =>
  finalCreateStore(rootReducer, initialState)

export default configureStore

```


[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 giftcard-ui/react/store/configureStore.dev.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { createStore, applyMiddleware } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import thunk from 'redux-thunk'
import logger from 'redux-logger'
import rootReducer from '../reducers'

const finalCreateStore = composeWithDevTools(
  applyMiddleware(thunk),
  applyMiddleware(logger),
)(createStore)

const configureStore = initialState =>
  finalCreateStore(rootReducer, initialState)

export default configureStore

```


[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 giftcard-ui/react/store/configureStore.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
if (process.env.NODE_ENV === 'production') {
  module.exports = require('./configureStore.prod')
} else {
  module.exports = require('./configureStore.dev')
}

```


[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 giftcard-ui/react/actions/cards/index.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import * as TYPES from '../types'
import axios from 'axios'

const localApiBase = ({ workspace, account }) =>
  `https://${workspace}--${account}.myvtex.com/_v`

// #region getCards
const requestGetCards = () => ({
  type: TYPES.REQUEST_CARDS,
})

const receiveGetCardsSuccess = cards => ({
  type: TYPES.RECEIVE_CARDS_SUCCESS,
  cards,
})

const receiveGetCardsError = data => ({
  type: TYPES.RECEIVE_CARDS_ERROR,
  data,
})

export const getCards = data => dispatch => {
  dispatch(requestGetCards(data))

  const { account, workspace } = data
  const url = `${localApiBase({ account, workspace })}/getgiftcards`

  return axios(url)
    .then(response => dispatch(receiveGetCardsSuccess(response.data)))
    .catch(error =>
      dispatch(
        receiveGetCardsError(
          (error && error.response && error.response.data) || null,
        ),
      ),
    )
}
// #endregion

// #region create card
const requestCardCreation = (data, cardData) => ({
  type: TYPES.REQUEST_CARD_CREATION,
  data,
  cardData,
})

const receiveCardCreationSuccess = response => ({
  type: TYPES.RECEIVE_CARD_CREATION_SUCCESS,
  response,
})

const receiveCardCreationError = data => ({
  type: TYPES.RECEIVE_CARD_CREATION_ERROR,
  data,
})

export const createCard = (data, cardData) => dispatch => {
  dispatch(requestCardCreation(data, cardData))

  const { account, workspace } = data
  const url = `${localApiBase({ account, workspace })}/postgiftcard`

  return axios
    .post(url, cardData)
    .then(response => {
      if (response.status === 200) {
        dispatch(receiveCardCreationSuccess(response))
      } else {
        dispatch(receiveCardCreationError(response.status))
      }
    })
    .catch(error =>
      dispatch(
        receiveCardCreationError(
          (error && error.response && error.response.data) || null,
        ),
      ),
    )
}
// #endregion

```


[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 giftcard-ui/react/reducers/cards/index.js from the giftcard-ui VTEX app.

[Assistant]
Here's the implementation:

```javascript
import * as TYPES from '../../actions/types'

const initialState = {
  isLoading: false,
}

const cardsReducer = (state = initialState, action) => {
  switch (action.type) {
    case TYPES.REQUEST_CARDS: {
      return {
        ...state,
        isLoading: true,
      }
    }
    case TYPES.RECEIVE_CARDS_SUCCESS: {
      return {
        ...state,
        isLoading: false,
        cards: action.cards,
      }
    }
    case TYPES.RECEIVE_CARDS_ERROR: {
      return {
        ...state,
        isLoading: false,
      }
    }

    case TYPES.REQUEST_CARD_CREATION: {
      return {
        ...state,
        isLoading: true,
      }
    }
    case TYPES.RECEIVE_CARD_CREATION_SUCCESS: {
      return {
        ...state,
        isLoading: false,
      }
    }
    case TYPES.RECEIVE_CARD_CREATION_ERROR: {
      return {
        ...state,
        isLoading: false,
      }
    }

    default:
      return state
  }
}

export default cardsReducer

```


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

[Assistant]
Here's the implementation:

```markdown
# Instore Form Fields

This is an VTEX IO app that provides the tooling for adding extra fields on your Instore Customer Profile Registration Form.

It is as simple as creating a new IO React App and adding

```
    "registration-container/{{whatever-name}}": {
      "component": "vtex.instore-form-fields/FormInput",
      "props": {
        "ffor": "{{key on Masterdata}}",
        "nameKey": "{{locale key to label the input}}",
        "initialValue": "{{if any, it is optional}}"
      }
    },
```

And also, don't forget to [add the same key on Masterdata](http://help.vtex.com/pt/faq/como-crio-um-campo-no-master-data) you mentioned on your app, otherwise it won't save a thing.
```


[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 instore-form-fields/react/FormInput.js from the instore-form-fields VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React, { Component } from 'react'
import { FormattedMessage } from 'react-intl'
import PropTypes from 'prop-types'

class FormInput extends Component {
  static propTypes = {
    for: PropTypes.string,
    nameKey: PropTypes.string,
    initialValue: PropTypes.string,
    handleInputChange: PropTypes.func,
    isRequired: PropTypes.bool,
  }

  static defaultTypes = {
    initialValue: ""
  }

  render () {
    const { ffor, nameKey, initialValue, handleInputChange, isRequired } = this.props
    return (
      <div className="ph5 pt4">
        <label className="db f6 f5-ns mb4 gray" htmlFor={ffor}>
          <FormattedMessage id={nameKey} />
        </label>
        <input
          type="text"
          placeholder=""
          id={ffor}
          autoComplete="off"
          autoCorrect="off"
          autoCapitalize="off"
          spellCheck="false"
          className="db ba b--black-20 w-100 w-100-ns pa4 pa5-ns lh-copy f4-ns mb5 mb6-ns"
          defaultValue={initialValue}
          onChange={handleInputChange}
          required={isRequired}
        />
      </div>
    )
  }

}

export default FormInput

```


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

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "react-intl": "^2.7.2"
  }
}

```


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

[User] Show me the implementation of cybersource-ui/messages/en.json from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/cybersource.title": "Cybersource",
  "admin/cybersource.saveSettings.success": "Settings saved successfully",
  "admin/cybersource.saveSettings.failure": "Settings could not be saved, see console for details",
  "admin/cybersource.settings.introduction": "{cybersourceLink}",
  "admin/cybersource.saveSettings.buttonText": "Save settings",
  "admin/cybersource.settings.isLive.label": "Production mode",
  "admin/cybersource.settings.merchantId.label": "Merchant id",
  "admin/cybersource.settings.merchantKey.label": "Merchant key",
  "admin/cybersource.settings.sharedSecretKey.label": "Shared secret key",
  "admin/cybersource.settings.customNsu.label": "Custom NSU",
  "admin/cybersource.settings.orderSuffix.label": "Reference Suffix",
  "admin/cybersource.settings.enableTransactionPosting.label": "Enable transaction posting",
  "admin/cybersource.settings.salesChannelExclude.label": "Sales Channels to Exclude from Cybersource.",
  "admin/cybersource.settings.nexusRegions.label": "Tax Nexus Regions.",
  "admin/cybersource.settings.shippingProductCode.label": "Shipping Product Code.",
  "admin/cybersource.settings.isLive.helpText": "Disable this toggle if using a sandbox API key.",
  "admin/cybersource.settings.merchantId.helpText": "Write your merchant Id",
  "admin/cybersource.settings.merchantKey.helpText": "Write your merchant Key",
  "admin/cybersource.settings.sharedSecretKey.helpText": "Write your shared secret key",
  "admin/cybersource.settings.customNsu.helpText": "Override default NSU with custom value",
  "admin/cybersource.settings.UseOrderIdForFingerprint.label": "Use Order Id For Device Fingerprint",
  "admin/cybersource.settings.UseOrderIdForFingerprint.helpText": "Use Order Id For Device Fingerprint in place of the Session Id",
  "admin/cybersource.settings.orderSuffix.helpText": "Optional Order Reference Suffix",
  "admin/cybersource.settings.EnableTax.label": "Enable Tax Calculations",
  "admin/cybersource.settings.EnableTax.helpText": "Enable Tax Placeholder",
  "admin/cybersource.settings.enableTransactionPosting.helpText": "Enable transaction posting",
  "admin/cybersource.settings.salesChannelExclude.helpText": "Comma separated list of sales channel ids to exclude.",
  "admin/cybersource.settings.nexusRegions.helpText": "Comma separated list of states where tax is to be collected.  If none, tax will be calculated for all regions.",
  "admin/cybersource.settings.shippingProductCode.helpText": "Shipping Product Code.",
  "admin/cybersource.settings.successfulPortion": "Successful Portion",
  "admin/cybersource.settings.userInput": "User Input",
  "admin/cybersource.settings.isValid": "Valid",
  "admin/cybersource.settings.valid": "Valid",
  "admin/cybersource.settings.invalid": "Invalid",
  "admin/cybersource.settings.showRefenceWords": "Show All Referencable Words",
  "admin/cybersource.settings.merchantDefinedInfo": "Merchant Defined Information",
  "admin/cybersource.settings.merchantDefinedFields": "Merchant Defined Fields",
  "admin/cybersource.settings.merchantFieldsReadme": "Adding Merchant Defined Fields",
  "admin/cybersource.settings.readmeContent": "You can create merchant defined fields on this page that will be included when sending VTEX orders to CyberSource.{lineBreak}{lineBreak}Each line of the text area will be treated as a new merchant defined field; multiple values on a single line will be sent as part of the same field. See the app's documentation for further instructions.{lineBreak}{lineBreak}Any characters outside of double curly brackets will be interpreted as a static value.{lineBreak}Meanwhile any values inside double curly brackets must be in the following format: Reference Word|Modification Word|Values",
  "admin/cybersource.settings.readmeLink": "Full Documentation Link",
  "admin/cybersource.settings.reports.reports.label": "Reports",
  "admin/cybersource.settings.reports.reportsDay.label": "Reports Day",
  "admin/cybersource.settings.reports.conversionTime.label": "Conversion Time",
  "admin/cybersource.settings.reports.merchantReferenceNumber.label": "Merchant Reference Number",
  "admin/cybersource.settings.reports.newDecision.label": "New Decision",
  "admin/cybersource.settings.reports.originalDecision.label": "Original Decision",
  "admin/cybersource.settings.reports.reviewer.label": "Reviewer",
  "admin/cybersource.settings.reports.reviewerComments.label": "Reviewer Comments",
  "admin/cybersource.settings.reports.noReports.label": "There is no reports here!"
}

```


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

[User] Show me the implementation of cybersource-ui/messages/context.json from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/cybersource.title": "Cybersource",
  "admin/cybersource.saveSettings.success": "Settings saved successfully",
  "admin/cybersource.saveSettings.failure": "Settings could not be saved, see console for details",
  "admin/cybersource.settings.introduction": "{cybersourceLink}",
  "admin/cybersource.saveSettings.buttonText": "Save settings",
  "admin/cybersource.settings.isLive.label": "Production mode",
  "admin/cybersource.settings.merchantId.label": "Merchant id",
  "admin/cybersource.settings.merchantKey.label": "Merchant key",
  "admin/cybersource.settings.sharedSecretKey.label": "Shared secret key",
  "admin/cybersource.settings.customNsu.label": "Custom NSU",
  "admin/cybersource.settings.orderSuffix.label": "Reference Suffix",
  "admin/cybersource.settings.enableTransactionPosting.label": "Enable transaction posting",
  "admin/cybersource.settings.salesChannelExclude.label": "Sales Channels to Exclude from Cybersource.",
  "admin/cybersource.settings.nexusRegions.label": "Tax Nexus Regions.",
  "admin/cybersource.settings.shippingProductCode.label": "Shipping Product Code.",
  "admin/cybersource.settings.isLive.helpText": "Disable this toggle if using a sandbox API key.",
  "admin/cybersource.settings.merchantId.helpText": "Write your merchant Id",
  "admin/cybersource.settings.merchantKey.helpText": "Write your merchant Key",
  "admin/cybersource.settings.sharedSecretKey.helpText": "Write your shared secret key",
  "admin/cybersource.settings.customNsu.helpText": "Override default NSU with custom value",
  "admin/cybersource.settings.UseOrderIdForFingerprint.label": "Use Order Id For Device Fingerprint",
  "admin/cybersource.settings.UseOrderIdForFingerprint.helpText": "Use Order Id For Device Fingerprint in place of the Session Id",
  "admin/cybersource.settings.orderSuffix.helpText": "Optional Order Reference Suffix",
  "admin/cybersource.settings.EnableTax.label": "Enable Tax Calculations",
  "admin/cybersource.settings.EnableTax.helpText": "Enable Tax Placeholder",
  "admin/cybersource.settings.enableTransactionPosting.helpText": "Enable transaction posting",
  "admin/cybersource.settings.salesChannelExclude.helpText": "Comma separated list of sales channel ids to exclude.",
  "admin/cybersource.settings.nexusRegions.helpText": "Comma separated list of states where tax is to be collected.  If none, tax will be calculated for all regions.",
  "admin/cybersource.settings.shippingProductCode.helpText": "Shipping Product Code.",
  "admin/cybersource.settings.successfulPortion": "Successful Portion",
  "admin/cybersource.settings.userInput": "User Input",
  "admin/cybersource.settings.isValid": "Valid",
  "admin/cybersource.settings.valid": "Valid",
  "admin/cybersource.settings.invalid": "Invalid",
  "admin/cybersource.settings.showRefenceWords": "Show All Referencable Words",
  "admin/cybersource.settings.merchantDefinedInfo": "Merchant Defined Information",
  "admin/cybersource.settings.merchantDefinedFields": "Merchant Defined Fields",
  "admin/cybersource.settings.merchantFieldsReadme": "Adding Merchant Defined Fields",
  "admin/cybersource.settings.readmeContent": "You can create merchant defined fields on this page that will be included when sending VTEX orders to CyberSource.{lineBreak}{lineBreak}Each line of the text area will be treated as a new merchant defined field; multiple values on a single line will be sent as part of the same field. See the app's documentation for further instructions.{lineBreak}{lineBreak}Any characters outside of double curly brackets will be interpreted as a static value.{lineBreak}Meanwhile any values inside double curly brackets must be in the following format: Reference Word|Modification Word|Values",
  "admin/cybersource.settings.readmeLink": "Full Documentation Link",
  "admin/cybersource.settings.reports.reports.label": "Reports",
  "admin/cybersource.settings.reports.reportsDay.label": "Reports Day",
  "admin/cybersource.settings.reports.conversionTime.label": "Conversion Time",
  "admin/cybersource.settings.reports.merchantReferenceNumber.label": "Merchant Reference Number",
  "admin/cybersource.settings.reports.newDecision.label": "New Decision",
  "admin/cybersource.settings.reports.originalDecision.label": "Original Decision",
  "admin/cybersource.settings.reports.reviewer.label": "Reviewer",
  "admin/cybersource.settings.reports.reviewerComments.label": "Reviewer Comments",
  "admin/cybersource.settings.reports.noReports.label": "There is no reports here!"
}

```


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

[User] Show me the implementation of cybersource-ui/admin/navigation.json from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "LMProductId": "6",
  "section": "transactions",
  "path": "/admin/cybersource",
  "icon": "extensions-ic",
  "titleId": "admin/cybersource.title"
}

```


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

[User] Show me the implementation of cybersource-ui/admin/routes.json from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin.app.cybersource": {
    "component": "Admin",
    "path": "/admin/app/cybersource"
  }
}

```


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

[User] Show me the implementation of cybersource-ui/docs/README.md from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

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

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)

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

# CyberSource IO

This app uses the CyberSource REST API to process payments, risk management, and taxes.

## Configuration

1. [Install](https://developers.vtex.com/vtex-developer-docs/docs/vtex-io-documentation-installing-an-app) `vtex.cybersource` and `vtex.cybersource-ui` in the desired account.

2. In Cybersource EBC, generate authentication keys.
	- Payment Configuration -> Key Management -> Generate Key
	- Choose `REST - Shared Secret` and Generate Key

3. In VTEX Admin, search for "Cybersource" to find the admin panel as shown below:
	![image](https://user-images.githubusercontent.com/47258865/178300211-3d3eadf2-6f44-4db4-95dd-76fae2bfebc4.png)

  - Enter your `Merchant ID`
  - Enter your `Merchant Key` and `Shared Secret Key` from step 2
  - Select a `Processor` (choose "Other" if your processor does not appear in the list)
  - Select a `Region` (choose "Other" if your region does not appear in the list)
  - Optionally enter a `Reference Suffix` (by default, orders in CyberSource's system will be associated with the VTEX order group ID, but this setting can be used to append a suffix such as "-01")
  - Optionally enter a `Custom NSU`
  - Choose whether to `Enable Tax Calculations` if you wish to use CyberSource as your tax calculation provider in checkout
  - Choose whether to `Enable Transaction Posting` to post completed transactions for tax reporting
  - Optionally enter any `Sales Channels to Exclude from CyberSource`
  - Optionally enter a `Shipping Product Code` for purposes of shipping tax calculation
  - Optionally enter a list of `Tax Nexus Regions`
  - Click `Save Settings`

4. In VTEX Admin, navigate to Payment Settings (`/admin/pci-gateway/#/rules`)
	- Select the Gateway Affiliations tab and click the green plus to add a new affiliation
	- From the list of gateways, select `Cybersource IO`
	- Configure the affiliation as follows:
    - Leave `Application Key` & `Application Token` blank (they are not used)
	  - Select the desired `Payment settlement` behavior:
      - "Use Behavior Recommended By The Payment Processor" will result in authorized payments being automatically captured after 4 days (or if the order is invoiced, whichever comes first)
      - "Deactivated" will result in payments being captured only when the VTEX order is invoiced
	  - Enter your `Company Name` and `Company Tax Id`
    - `Capture Setting`: if set to "Immediate Capture", the connector will send a single "Auth and Capture" request to CyberSource when the order is placed; otherwise it will follow standard VTEX behavior (separate calls for auth and capture)
    - `Merchant Id`, `Merchant Key`, and `Shared Secret Key` are optional overrides; if left blank, the connector will read these values from the settings entered in step 3
  - Click `Save`
	![image](https://user-images.githubusercontent.com/47258865/178299999-a27149a6-f937-4602-96ed-d232d8795095.png)

5. In VTEX Admin, still in the Payment Settings interface
	- Select the Payment Conditions tab
  - Click the green plus to add a new payment condition for the desired credit card type (ex. Visa)
  - In `Process with affiliation`, choose `Cybersource IO` (or if you have customized the name of the affiliation, select the name you entered)
  - Click `Save`
  - Repeat as needed for other credit card types
  - If you previously created credit card payment rules for other gateways (including the legacy CyberSource connector), you may set these rules to `Inactive`. Transactions in progress that were started on that connector will still be processed by it even if it is inactive; only new transactions will be processed by the new connector.
    - If you need to roll back to the previous connector for any reason, simply set its payment rule(s) to `Active` and set the `Cybersource IO` payment rule(s) to `Inactive`.

### Optional: Device Fingerprint

Add the following code to your checkout custom JS and replace `{{ORG_ID}}` and `{{MERCHANT_ID}}` with the appropriate values.
```
function addsDeviceFingerPrint() {
  if (!window.vtex) return;
  if (window.vtex.deviceFingerprint) return;
  $.ajax({
    type: 'get',
    async: true,
    url: rootPath() + '/api/sessions?items=*'
  }).then(function(response) {
    var ORG_ID = "{{ORG_ID}}";
    var MERCHANT_ID = "{{MERCHANT_ID}}";
    console.log('session', response);
    window.vtex.deviceFingerprint = response.id;
    var sessionId = response.id || "CYBERSOURCE";
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = `https://h.online-metrix.net/fp/tags.js?org_id=${ORG_ID}&session_id=${MERCHANT_ID}${sessionId}`;
    document.head.appendChild(script);
    var noScript = document.createElement("noscript");
    var iframe = document.createElement("iframe");
    iframe.style = "width: 100px; height: 100px; border: 0; position: absolute; top: -5000px;";
    iframe.src = `https://h.online-metrix.net/fp/tags?org_id=${ORG_ID}&session_id=${MERCHANT_ID}${sessionId}`;
    noScript.appendChild(iframe);
    document.body.appendChild(noScript);
  })
}
```

### Optional: Merchant Defined Fields

- In VTEX Admin, search for "Cybersource" to navigate to the app's admin panel.
- In the `Merchant Defined Fields` tab, users can define custom fields.
- The text input follows these rules:
    1. Any values outside of **{{}}** curly brackets will be taken at direct value
    2. Any values between the **{{}}** must be in the following format `Reference Word|Modification Word|Values`
        1. All reference words can be found in the `Show All Referencable Words` dropdown
            1. Reference words can be left blank if `Modification Word` and `Values` are present
            2. Reference word is case sensitive
        2. Modification Words are either `Pad` or `date`
        3. If using `Pad`, the `Values` must be either in the format of a `number` or `desired length:fill character`
            1. `fill character` must be a single value. For example, `9:x` will result in a desired length of 9, and filling empty spaces with x
        4. If using `date`, the `Values` must be in the format of `dd/MM/yyyy` or any combination of it.
            1. `M` for month must be capitalized. This format can be scrambled to your liking, such as `yyyy/MM` or `yyyy` or `dd/yyyy/MM`
    3. Every new line is a new Merchant Defined Field
- Examples

| Input  | Is it Valid? | Reason |
| ------------- | ------------- | ------------- |
| {{MiniCart.Buyer.LastName}},{{MiniCart.Buyer.FirstName}}  | Valid  | Reference words are valid |
| 26940{{\|date\|yy}  | Invalid  | Missing second closing bracket |
| 26940{{\|date\|yy}}  | Valid  | Valid |
| currency{{notaword}}  | Invalid  | Invalid reference word |

## Contributors ✨

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

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

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

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

```


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

[User] Show me the implementation of cybersource-ui/react/package.json from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "cybersource-ui",
  "version": "0.8.0",
  "description": "Cybersource UI",
  "repository": "https://github.com/vtex-apps/cybersource",
  "devDependencies": {
    "@apollo/react-testing": "^3.1.3",
    "@types/jest": "^26.0.4",
    "@types/node": "^14.0.14",
    "@types/react": "^16.9.41",
    "@vtex/test-tools": "^3.1.0",
    "@vtex/tsconfig": "^0.5.6",
    "apollo-cache-inmemory": "^1.6.5",
    "graphql": "^14.6.0",
    "typescript": "3.9.7",
    "vtex.apps-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.apps-graphql@2.8.0/public/@types/vtex.apps-graphql",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.132.3/public/@types/vtex.render-runtime",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.145.2/public/@types/vtex.styleguide"
  },
  "dependencies": {
    "@vtex/admin-ui": "latest",
    "axios": "^0.19.2",
    "graphql": "^15.3.0",
    "react-apollo": "^3.1.5",
    "react-intl": "^5.0.2"
  }
}

```


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

[User] Show me the implementation of cybersource-ui/react/Admin.tsx from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable @typescript-eslint/no-unused-vars */
// react/adminExample.tsx
import type { FC } from 'react'
import React, { useState, useEffect } from 'react'
import {
  ToastProvider,
  ToastConsumer,
  Layout,
  PageHeader,
  PageBlock,
  Button,
  Toggle,
  Input,
  Dropdown,
  Spinner,
  Tab,
  Tabs,
} from 'vtex.styleguide'
import { FormattedMessage, useIntl } from 'react-intl'
import { Link } from 'vtex.render-runtime'
import { useQuery, useMutation } from 'react-apollo'

import MerchantDictionary from './components/merchantDictionary'
import Reports from './components/Reports'
import M_INIT_CONFIG from './mutations/InitConfiguration.gql'
import RemoveConfiguration from './mutations/RemoveConfiguration.gql'
import AppSettings from './queries/appSettings.gql'
import SaveAppSettings from './mutations/saveAppSettings.gql'

const Admin: FC = () => {
  const { formatMessage } = useIntl()
  const [saveSettings] = useMutation(SaveAppSettings)
  const [initConfig] = useMutation(M_INIT_CONFIG)
  const [removeConfig] = useMutation(RemoveConfiguration)
  const [settingsLoading, setSettingsLoading] = useState(false)
  const [settingsState, setSettingsState] = useState({
    IsLive: false,
    MerchantId: '',
    MerchantKey: '',
    SharedSecretKey: '',
    Processor: '',
    Region: '',
    OrderSuffix: '',
    CustomNsu: '',
    EnableTransactionPosting: false,
    SalesChannelExclude: '',
    ShippingProductCode: '',
    NexusRegions: '',
    EnableTax: false,
    MerchantDictionary: [],
    UseOrderIdForFingerprint: false,
  })

  const [initialAdminState, setAdminState] = useState({
    currentTab: 1,
  })

  const { data } = useQuery(AppSettings, {
    variables: {
      version: process.env.VTEX_APP_VERSION,
    },
    ssr: false,
  })

  const processorOptions = [
    { value: 'Braspag', label: 'Braspag' },
    { value: 'VPC', label: 'VPC' },
    { value: 'Izipay', label: 'Izipay' },
    { value: 'eGlobal', label: 'eGlobal' },
    { value: 'BBVA', label: 'BBVA' },
    { value: 'Banorte', label: 'Banorte' },
    { value: 'Prosa', label: 'Prosa' },
    { value: 'Santander', label: 'Santander' },
    { value: 'Amex Direct', label: 'American Express Direct' },
    { value: 'Other', label: 'Other' },
  ]

  const regionOptions = [
    { value: 'CO', label: 'Colombia' },
    { value: 'PE', label: 'Peru' },
    { value: 'MX', label: 'Mexico' },
    { value: 'BR', label: 'Brasil' },
    { value: 'EC', label: 'Ecuador' },
    { value: 'Other', label: 'Other' },
  ]

  const handleSaveSettings = async (showToast: any) => {
    setSettingsLoading(true)

    try {
      if (settingsState.EnableTax) {
        await initConfig()
      } else {
        await removeConfig()
      }

      await saveSettings({
        variables: {
          version: process.env.VTEX_APP_VERSION,
          settings: JSON.stringify(settingsState),
        },
      }).then(() => {
        showToast({
          message: formatMessage({
            id: 'admin/cybersource.saveSettings.success',
          }),
          duration: 5000,
        })
        setSettingsLoading(false)
      })
    } catch (error) {
      console.error(error)
      showToast({
        message: formatMessage({
          id: 'admin/cybersource.saveSettings.failure',
        }),
        duration: 5000,
      })
      setSettingsLoading(false)
    }
  }

  useEffect(() => {
    if (!data?.getAppSettings) return

    setSettingsState({
      ...settingsState,
      CustomNsu: data.getAppSettings.customNsu,
      EnableTax: data.getAppSettings.enableTax,
      EnableTransactionPosting: data.getAppSettings.enableTrasactionPosting,
      IsLive: data.getAppSettings.isLive,
      MerchantId: data.getAppSettings.merchantId,
      MerchantKey: data.getAppSettings.merchantKey,
      NexusRegions: data.getAppSettings.nexusRegions,
      OrderSuffix: data.getAppSettings.orderSuffix,
      Processor: data.getAppSettings.processor,
      Region: data.getAppSettings.region,
      SalesChannelExclude: data.getAppSettings.salesChannelExclude,
      SharedSecretKey: data.getAppSettings.sharedSecretKey,
      ShippingProductCode: data.getAppSettings.shippingProductCode,
      MerchantDictionary: data.getAppSettings.merchantDictionary,
      UseOrderIdForFingerprint: data.getAppSettings.useOrderIdForFingerprint,
    })
  }, [data])

  if (!data) {
    return (
      <Layout
        pageHeader={
          <PageHeader
            title={<FormattedMessage id="admin/cybersource.title" />}
          />
        }
        fullWidth
      >
        <PageBlock>
          <Spinner />
        </PageBlock>
      </Layout>
    )
  }

  return (
    <ToastProvider positioning="window">
      <ToastConsumer>
        {({ showToast }: { showToast: any }) => (
          <Layout
            pageHeader={
              <PageHeader
                title={<FormattedMessage id="admin/cybersource.title" />}
              />
            }
            fullWidth
          >
            <div>
              <Tabs fullWidth>
                <Tab
                  label="Admin Settings"
                  active={initialAdminState.currentTab === 1}
                  onClick={() => setAdminState({ currentTab: 1 })}
                >
                  <div className="pt7">
                    <PageBlock
                      subtitle={
                        <FormattedMessage
                          id="admin/cybersource.settings.introduction"
                          values={{
                            cybersourceLink: (
                              // eslint-disable-next-line react/jsx-no-target-blank
                              <Link
                                to="https://www.cybersource.com/"
                                target="_blank"
                              >
                                https://www.cybersource.com/
                              </Link>
                            ),
                            lineBreak: <br />,
                          }}
                        />
                      }
                    >
                      <section className="pv4">
                        <Toggle
                          semantic
                          label={formatMessage({
                            id: 'admin/cybersource.settings.isLive.label',
                          })}
                          size="large"
                          checked={settingsState.IsLive}
                          onChange={() => {
                            setSettingsState({
                              ...settingsState,
                              IsLive: !settingsState.IsLive,
                            })
                          }}
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.isLive.helpText',
                          })}
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.merchantId.label',
                          })}
                          value={settingsState.MerchantId}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              MerchantId: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.merchantId.helpText',
                          })}
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.merchantKey.label',
                          })}
                          value={settingsState.MerchantKey}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              MerchantKey: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.merchantKey.helpText',
                          })}
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.sharedSecretKey.label',
                          })}
                          value={settingsState.SharedSecretKey}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              SharedSecretKey: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.sharedSecretKey.helpText',
                          })}
                        />
                      </section>
                      <section className="mb5">
                        <Dropdown
                          label="Processor"
                          options={processorOptions}
                          value={settingsState.Processor}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              Processor: e.currentTarget.value,
                            })
                          }
                        />
                      </section>
                      <section className="mb5">
                        <Dropdown
                          label="Region"
                          options={regionOptions}
                          value={settingsState.Region}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              Region: e.currentTarget.value,
                            })
                          }
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.orderSuffix.label',
                          })}
                          value={settingsState.OrderSuffix}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              OrderSuffix: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.orderSuffix.helpText',
                          })}
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.customNsu.label',
                          })}
                          value={settingsState.CustomNsu}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              CustomNsu: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.customNsu.helpText',
                          })}
                        />
                      </section>
                      <section className="pv4">
                        <Toggle
                          semantic
                          label={formatMessage({
                            id: 'admin/cybersource.settings.UseOrderIdForFingerprint.label',
                          })}
                          size="large"
                          checked={settingsState.UseOrderIdForFingerprint}
                          onChange={() => {
                            setSettingsState({
                              ...settingsState,
                              UseOrderIdForFingerprint:
                                !settingsState.UseOrderIdForFingerprint,
                            })
                          }}
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.UseOrderIdForFingerprint.helpText',
                          })}
                        />
                      </section>
                      <section className="pv4">
                        <Toggle
                          semantic
                          label={formatMessage({
                            id: 'admin/cybersource.settings.EnableTax.label',
                          })}
                          size="large"
                          checked={settingsState.EnableTax}
                          onChange={() => {
                            setSettingsState({
                              ...settingsState,
                              EnableTax: !settingsState.EnableTax,
                            })
                          }}
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.EnableTax.helpText',
                          })}
                        />
                      </section>
                      <section className="pv4">
                        <Toggle
                          semantic
                          label={formatMessage({
                            id: 'admin/cybersource.settings.enableTransactionPosting.label',
                          })}
                          size="large"
                          checked={settingsState.EnableTransactionPosting}
                          onChange={() => {
                            setSettingsState({
                              ...settingsState,
                              EnableTransactionPosting:
                                !settingsState.EnableTransactionPosting,
                            })
                          }}
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.enableTransactionPosting.helpText',
                          })}
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.salesChannelExclude.label',
                          })}
                          value={settingsState.SalesChannelExclude}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              SalesChannelExclude: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.salesChannelExclude.helpText',
                          })}
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.shippingProductCode.label',
                          })}
                          value={settingsState.ShippingProductCode}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              ShippingProductCode: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.shippingProductCode.helpText',
                          })}
                        />
                      </section>
                      <section className="pb4 mt4">
                        <Input
                          label={formatMessage({
                            id: 'admin/cybersource.settings.nexusRegions.label',
                          })}
                          value={settingsState.NexusRegions}
                          onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setSettingsState({
                              ...settingsState,
                              NexusRegions: e.currentTarget.value,
                            })
                          }
                          helpText={formatMessage({
                            id: 'admin/cybersource.settings.nexusRegions.helpText',
                          })}
                        />
                      </section>
                      <section className="pt4">
                        <Button
                          variation="primary"
                          onClick={() => handleSaveSettings(showToast)}
                          isLoading={settingsLoading}
                        >
                          <FormattedMessage id="admin/cybersource.saveSettings.buttonText" />
                        </Button>
                      </section>
                    </PageBlock>
                  </div>
                </Tab>
                <Tab
                  label={formatMessage({
                    id: 'admin/cybersource.settings.merchantDefinedFields',
                  })}
                  active={initialAdminState.currentTab === 2}
                  onClick={() => setAdminState({ currentTab: 2 })}
                >
                  <div className="pt7">
                    <MerchantDictionary
                      handleSaveSettings={handleSaveSettings}
                      showToast={showToast}
                      settingsState={settingsState}
                      setSettingsState={setSettingsState}
                      settingsLoading={settingsLoading}
                    />
                  </div>
                </Tab>
                <Tab
                  label={formatMessage({
                    id: 'admin/cybersource.settings.reports.reports.label',
                  })}
                  active={initialAdminState.currentTab === 3}
                  onClick={() => setAdminState({ currentTab: 3 })}
                >
                  <div className="pt7">
                    <Reports />
                  </div>
                </Tab>
              </Tabs>
            </div>
          </Layout>
        )}
      </ToastConsumer>
    </ToastProvider>
  )
}

export default Admin

```


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

[User] Show me the implementation of cybersource-ui/react/types/index.tsx from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
export interface Report {
  conversionTime: string
  merchantReferenceNumber: string
  newDecision: string
  originalDecision: string
  reviewer: string
  reviewerComments: string
}
export interface ReportsTableProps {
  reports: Report[]
  loading: boolean
}
export interface ReportsState {
  selectedDay: any
  loading: boolean
  reports: Report[]
}

```


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

[User] Show me the implementation of cybersource-ui/react/mutations/InitConfiguration.gql from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation InitConfiguration {
  initConfiguration
}

```


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

[User] Show me the implementation of cybersource-ui/react/mutations/RemoveConfiguration.gql from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation RemoveConfiguration {
  removeConfiguration
}

```


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

[User] Show me the implementation of cybersource-ui/react/mutations/saveAppSettings.gql from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation SaveAppSettings($version: String, $settings: String) {
  saveAppSettings(
    app: "vtex.cybersource-ui"
    settings: $settings
    version: $version
  ) @context(provider: "vtex.apps-graphql") {
    message
  }
}

```


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

[User] Show me the implementation of cybersource-ui/react/typings/png.d.ts from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.png' {
  const path: string
  export default path
}

```


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

[User] Show me the implementation of cybersource-ui/react/typings/css.d.ts from the cybersource-ui 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 cybersource-ui/react/typings/graphql.d.ts from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

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

  const value: DocumentNode
  export default value
}

declare module '*.gql' {
  import type { 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 cybersource-ui/react/typings/vtex.styleguide.d.ts from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.styleguide' {
  export const PageHeader
  export const Alert
  export const Modal
  export const Box
  export const Card
  export const Dropdown
  export const Spinner
  export const Table
  export const Button
  export const ButtonPlain
  export const IconWarning
  export const IconCheck
  export const Input
  export const InputSearch
  export const IconCaretDown
  export const IconCaretUp
  export const IconArrowDown
  export const IconArrowBack
  export const IconArrowUp
  export const IconClose
  export const IconExternalLink
  export const IconSearch
  export const IconSuccess
  export const IconCopy
  export const IconCog
  export const Tooltip
  export const ToastConsumer
  export const ToastProvider
  export const withToast
  export const ButtonWithIcon
  export const Pagination
  export const Collapsible
  export const Textarea
  export const NumericStepper
  export const EmptyState
  export const Tab
  export const Tag
  export const Layout
  export const Tabs
  export const Divider
  export const PageBlock
  export const Toggle
  export const Link
}

```


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

[User] Show me the implementation of cybersource-ui/react/queries/reports.gql from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Reports($startDate: String, $endDate: String) {
  conversionReport(startDate: $startDate, endDate: $endDate) {
    conversionDetails {
      conversionTime
      merchantReferenceNumber
      newDecision
      originalDecision
      reviewer
      reviewerComments
    }
  }
}

```


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

[User] Show me the implementation of cybersource-ui/react/queries/appSettings.gql from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```graphql
query AppSettings($version: String) {
  getAppSettings{
    isLive
    merchantId
    merchantKey
    sharedSecretKey
    processor
    region
    orderSuffix
    customNsu
    useOrderIdForFingerprint
    enableTax
    enableTransactionPosting
    salesChannelExclude
    shippingProductCode
    nexusRegions
    merchantDictionary{
      userInput
      isValid
      goodPortion
    }
  }
}
```


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

[User] Show me the implementation of cybersource-ui/react/queries/merchantDefinedFields.gql from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```graphql
query MerchantDefinedFields {
  merchantDefinedFields
}

```


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

[User] Show me the implementation of cybersource-ui/react/components/Reports.tsx from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable no-console */
import React, { useState, useEffect } from 'react'
import { defineMessages, useIntl } from 'react-intl'
import { useApolloClient } from 'react-apollo'
import { createSystem } from '@vtex/admin-ui'
import { DatePicker } from 'vtex.styleguide'

import type { Report } from '../types'
import ReportsTable from './ReportsTable'
import reportsQuery from '../queries/reports.gql'

const messages = defineMessages({
  reportsDay: {
    defaultMessage: 'Reports Day',
    id: 'admin/cybersource.settings.reports.reportsDay.label',
  },
  reports: {
    defaultMessage: 'Reports',
    id: 'admin/cybersource.settings.reports.reports.label',
  },
})

const Reports = () => {
  const [SystemProvider] = createSystem({ key: 'cybersource' })
  const client = useApolloClient()
  const { formatDate, formatMessage } = useIntl()
  const [state, setState] = useState({
    selectedDay: new Date(),
    loading: true,
    reports: [],
  })

  const handleChange = (date: any) => {
    setState(prev => ({
      ...prev,
      selectedDay: date,
      reports: [],
    }))
  }

  useEffect(() => {
    setState(prev => ({
      ...prev,
      loading: true,
    }))
    const { selectedDay } = state
    const nextDay = new Date(selectedDay.getTime() + 24 * 60 * 60 * 1000)
    const formatedDate = formatDate(selectedDay, {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
    })

    const nextfdayFormatedDate = formatDate(nextDay, {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric',
    })

    console.log('date::', selectedDay)
    console.log('nextDay::', nextDay)
    console.log('formatedDate::', formatedDate)
    console.log('nextDayFormatedDate::', nextfdayFormatedDate)

    // last report: 03/17/2022
    client
      .query({
        query: reportsQuery,
        variables: {
          startDate: formatedDate,
          endDate: nextfdayFormatedDate,
        },
      })
      .then((response: any) => {
        console.log('report::', response)
        const reports =
          response?.data?.conversionReport?.conversionDetails ?? []

        setState(prev => ({
          ...prev,
          loading: false,
          reports: reports.map((report: Report) => ({
            ...report,
            conversionTime: formatDate(report.conversionTime, {
              day: '2-digit',
              month: '2-digit',
              year: 'numeric',
              hour: 'numeric',
              minute: 'numeric',
            }),
          })),
        }))
      })
      .catch((err: any) => {
        console.log('no reports:', err)
        setState(prev => ({
          ...prev,
          loading: false,
        }))
      })
  }, [state.selectedDay])

  return (
    <SystemProvider>
      <div className="mb5">
        <DatePicker
          label={formatMessage(messages.reportsDay)}
          value={state.selectedDay}
          onChange={(date: any) => handleChange(date)}
          locale="en-US"
        />
      </div>
      <div className="mb5">
        <ReportsTable reports={state.reports} loading={state.loading} />
      </div>
    </SystemProvider>
  )
}

export default Reports

```


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

[User] Show me the implementation of cybersource-ui/react/components/merchantDictionary.tsx from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FunctionComponent } from 'react'
import React, { useState, useEffect } from 'react'
import { useQuery } from 'react-apollo'
import { FormattedMessage, useIntl } from 'react-intl'
import {
  Button,
  Collapsible,
  PageBlock,
  Table,
  Tag,
  Textarea,
  Link,
} from 'vtex.styleguide'

import MerchantDefinedFields from '../queries/merchantDefinedFields.gql'

const MerchantDictionary: FunctionComponent<any> = (props: any) => {
  const { formatMessage } = useIntl()

  const defaultSchema = {
    properties: {
      userInput: {
        title: formatMessage({
          id: 'admin/cybersource.settings.userInput',
        }),
        width: 300,
      },
      isValid: {
        title: formatMessage({
          id: 'admin/cybersource.settings.isValid',
        }),
        minWidth: 100,
        cellRenderer: ({ cellData }: any) => {
          return cellData ? (
            <Tag type="success" variation="low">
              {formatMessage({
                id: 'admin/cybersource.settings.valid',
              })}
            </Tag>
          ) : (
            <Tag type="error" variation="low">
              {formatMessage({
                id: 'admin/cybersource.settings.invalid',
              })}
            </Tag>
          )
        },
      },
      goodPortion: {
        title: formatMessage({
          id: 'admin/cybersource.settings.successfulPortion',
        }),
        minWidth: 100,
      },
    },
  }

  const [state, setState] = useState<{
    textInput: string
    lookupSet: Set<string>
    keyWords: Set<string>
    inputMapping: any
    ruleCharacters: any
    dateLengthRules: any
    validatedResult: Array<{
      userInput: string
      isValid: boolean
      goodPortion: string
    }>
    isOpen: boolean
  }>({
    textInput:
      props?.settingsState?.MerchantDictionary?.length > 0
        ? props.settingsState.MerchantDictionary.reduce(
            (prev: any, curr: any) => {
              return { userInput: `${prev.userInput}\n${curr.userInput}` }
            }
          ).userInput
        : '',
    lookupSet: new Set([]),
    keyWords: new Set(['PAD', 'DATE', 'AGE', 'EQUALS']),
    inputMapping: {},
    ruleCharacters: { '{': '}', '}': '{' },
    dateLengthRules: {
      d: 2,
      M: 4,
      y: 4,
    },
    validatedResult: props.settingsState.MerchantDictionary ?? [],
    isOpen: false,
  })

  const { data } = useQuery(MerchantDefinedFields, {
    ssr: false,
  })

  useEffect(() => {
    if (data?.merchantDefinedFields.length > 0) {
      setState((prevState: any) => ({
        ...prevState,
        lookupSet: new Set(data.merchantDefinedFields),
      }))
    }
  }, [data])

  const validateInputMap = (textInput: string) => {
    const textInputArr = textInput.split('\n')

    const validatedResult = []

    for (const text of textInputArr) {
      let goodPortion = ''
      const stack: string[] = []

      for (const char of text) {
        // If there is no opening bracket, just add to it
        if (stack.length === 0 && !(char in state.ruleCharacters)) {
          goodPortion += char
        } else if (stack.length < 2 && char === '{') {
          // If there is an opening bracket
          stack.push(char)
          goodPortion += char
        } else if (stack.length >= 1 && char === '}') {
          // If there is a closing bracket
          // Pops the whole word, if there are no pipe between two sets of brackets
          if (state.lookupSet.has(stack[stack.length - 1])) {
            const poppedWord: string = stack.pop() ?? ''

            goodPortion += poppedWord
          } else {
            const splitBracketString = stack[stack.length - 1].split('|')

            if (
              splitBracketString.length === 3 &&
              (state.lookupSet.has(splitBracketString[0]) ||
                splitBracketString[0].length === 0) &&
              state.keyWords.has(splitBracketString[1].toUpperCase())
            ) {
              const poppedWord: string = stack.pop() ?? ''

              goodPortion += poppedWord
            }
          }

          // Pops the bottom layer bracket
          if (stack[stack.length - 1] === '{') {
            stack.pop()
            goodPortion += '}'
          }
        } else if (
          stack[0] === stack[1] &&
          stack[0] === '{' &&
          !(char in state.ruleCharacters)
        ) {
          // Adds to the stack if there are previous brackets, otherwise, append to it
          stack.length === 2
            ? stack.push(char)
            : (stack[stack.length - 1] += char)
        }
      }

      validatedResult.push({
        userInput: text,
        goodPortion,
        isValid: stack.length === 0,
      })
    }

    setState({ ...state, validatedResult, textInput })

    props.setSettingsState({
      ...props.settingsState,
      MerchantDictionary: state.validatedResult,
    })
  }

  return (
    <div>
      <div className="pa3 bg-muted-5">
        <PageBlock
          variation="annotated"
          title={formatMessage({
            id: 'admin/cybersource.settings.merchantFieldsReadme',
          })}
          subtitle={
            <Link
              target="_blank"
              href="https://developers.vtex.com/vtex-developer-docs/docs/vtex-cybersource-ui"
            >
              {formatMessage({
                id: 'admin/cybersource.settings.readmeLink',
              })}
            </Link>
          }
        >
          <div className="pv2">
            <FormattedMessage
              id="admin/cybersource.settings.readmeContent"
              values={{ lineBreak: <br /> }}
            />
          </div>
        </PageBlock>
      </div>
      <div className="mb6">
        <div className="pa3">
          <Collapsible
            header={
              <span className="c-action-primary hover-c-action-primary fw5">
                {formatMessage({
                  id: 'admin/cybersource.settings.showRefenceWords',
                })}
              </span>
            }
            onClick={(e: any) => {
              setState({ ...state, isOpen: e.target.isOpen })
            }}
            isOpen={state.isOpen}
          >
            {Array.from(state.lookupSet).map((keyword: string) => {
              return (
                <span key={keyword} className="pa3">
                  <Tag type="success" variation="low">
                    {keyword}
                  </Tag>
                </span>
              )
            })}
          </Collapsible>
        </div>
        <Textarea
          label={formatMessage({
            id: 'admin/cybersource.settings.merchantDefinedInfo',
          })}
          onChange={(e: any) => {
            validateInputMap(e.target.value)
          }}
          value={state.textInput}
        />
        <div className="mb5">
          <Table
            fullWidth
            schema={defaultSchema}
            items={state.validatedResult}
            density="high"
          />
        </div>
      </div>
      <Button
        variation="primary"
        onClick={() => {
          props.handleSaveSettings(props.showToast)
        }}
        isLoading={props.settingsLoading}
      >
        <FormattedMessage id="admin/cybersource.saveSettings.buttonText" />
      </Button>
    </div>
  )
}

export default MerchantDictionary

```


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

[User] Show me the implementation of cybersource-ui/react/components/ReportsTable.tsx from the cybersource-ui VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useEffect } from 'react'
import {
  useDataGridState,
  useDataViewState,
  DataGrid,
  DataView,
} from '@vtex/admin-ui'
import { defineMessages, useIntl } from 'react-intl'

import type { ReportsTableProps } from '../types'

const messages = defineMessages({
  conversionTime: {
    defaultMessage: 'Conversion Time',
    id: 'admin/cybersource.settings.reports.conversionTime.label',
  },
  merchantReferenceNumber: {
    defaultMessage: 'Merchant Reference Number',
    id: 'admin/cybersource.settings.reports.merchantReferenceNumber.label',
  },
  newDecision: {
    defaultMessage: 'New Decision',
    id: 'admin/cybersource.settings.reports.newDecision.label',
  },
  originalDecision: {
    defaultMessage: 'Original Decision',
    id: 'admin/cybersource.settings.reports.originalDecision.label',
  },
  reviewer: {
    defaultMessage: 'Reviewer',
    id: 'admin/cybersource.settings.reports.reviewer.label',
  },
  reviewerComments: {
    defaultMessage: 'Reviewer Comments',
    id: 'admin/cybersource.settings.reports.reviewerComments.label',
  },
  noReports: {
    defaultMessage: 'There is no reports here!',
    id: 'admin/cybersource.settings.reports.noReports.label',
  },
})

const ReportsTable = ({ reports, loading }: ReportsTableProps) => {
  const { formatMessage } = useIntl()
  const view = useDataViewState()
  const state = useDataGridState({
    view,
    length: 6,
    columns: [
      {
        id: 'conversionTime',
        header: () => <strong>{formatMessage(messages.conversionTime)}</strong>,
      },
      {
        id: 'merchantReferenceNumber',
        header: () => (
          <strong>{formatMessage(messages.merchantReferenceNumber)}</strong>
        ),
      },
      {
        id: 'newDecision',
        header: () => <strong>{formatMessage(messages.newDecision)}</strong>,
      },
      {
        id: 'originalDecision',
        header: () => (
          <strong>{formatMessage(messages.originalDecision)}</strong>
        ),
      },
      {
        id: 'reviewer',
        header: () => <strong>{formatMessage(messages.reviewer)}</strong>,
      },
      {
        id: 'reviewerComments',
        header: () => (
          <strong>{formatMessage(messages.reviewerComments)}</strong>
        ),
      },
    ],
    items: reports,
  })

  useEffect(() => {
    if (loading) {
      view.setStatus({
        type: 'loading',
      })
    }

    if (reports.length === 0 && !loading) {
      view.setStatus({
        type: 'empty',
        message: formatMessage(messages.noReports),
      })
    }

    if (reports.length > 0 && !loading) {
      view.setStatus({
        type: 'ready',
      })
    }
  }, [loading])

  return (
    <DataView state={view}>
      <DataGrid state={state} />
    </DataView>
  )
}

export default ReportsTable

```


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

[User] Show me the implementation of b2b-orders-history/messages/sl.json from the b2b-orders-history VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "a11y.orderHeader.shippingModal": "Odpri pojavni naslov",
  "commons.hello": "Živijo",
  "commons.continue": "Nadaljuj",
  "commons.free": "Brezplačno",
  "commons.other": "Drug",
  "commons.reasonOtherExplanation": "Povejte nam zakaj preklicujete to naročilo",
  "commons.save": "Shrani",
  "commons.close": "Zapri",
  "commons.no": "Ne",
  "commons.yes": "Da",
  "commons.reload": "Ponovno nalaganje",
  "commons.cancel": "Prekliči",
  "myo.commons.back": "Nazaj",
  "goBackToMyOrders": "pojdi nazaj na Moja naročila",
  "order": "Naročilo",
  "seeOrder": "Oglej si naročilo",
  "greeting.replaced": "Vaše #{value} naročilo je bilo uspešno zamenjano!",
  "greeting.cancelled": "Naročilo #{value} je bilo oddano za preklic in bo končano kmalu!",
  "greeting.edit": "Vaša naročnina je bila uspešno posodobljena!",
  "pages.editOrder.greeting": "Dobrodošli v samopostrežbo. Vaše naročilo se pripravlja za dostavo. Kaj lahko storimo za vas?",
  "pages.editOrder.changeUnavailable": "To naročilo ni na voljo za spremembe izdelka.",
  "pages.cancelOrder.greeting": "Dobrodošli v samopostrežbo. Zakaj želite preklicati vaše naročilo?",
  "orders.toggle.ordersThatArentFinished": "Naročila v teku",
  "orders.toggle.ordersThatAreFinished": "Zaključena naročila",
  "orders.notFound": "Nič še niste naročili!",
  "orders.finishedNotFound": "Nimate zaključenih naročil",
  "orders.ongoingNotFound": "Nimate naročil v teku",
  "order.dateIs": "Datum naročila",
  "order.shipsTo": "Odpošiljanje",
  "order.total": "Skupaj",
  "order.moreOptions": "Več možnosti",
  "orders.title": "Naročila",
  "orders.edit": "Uredi naročila #{orderNumber}",
  "order.history": "Spremeni zgodovino",
  "order.change.date": "{date} ob {hour}",
  "order.change.quantity": "Količina: {quantity}",
  "order.change.originalOrder": "Izvorno naročilo",
  "order.change.currentOrder": "Trenutno naročilo",
  "order.viewAllItems": "Poglej vse predmete",
  "order.printBankInvoice": "Tiskaj bančni izpisek",
  "order.cancelOrder": "Zahtevaj preklic",
  "order.changeOrder": "Spremeni naročilo",
  "order.orderAgain": "Naroči ponovno",
  "order.goToOrderDetails": "Poglej podrobnosti naročila",
  "order.confirmCancellation": "Potrdi preklic",
  "order.estimatedDeliveryTo": "Predvidena dobava v",
  "order.navigationArrowTitle": "Puščica za vrnitev",
  "order.seeInvoice": "Oglej si račun",
  "order.trackingData.clickHereToGoToExternalPage": "Poglej informacije o sledenju na spletni strani ponudnika",
  "order.trackingData.shipping": "Sledenje #{trackingNumber}",
  "order.stepsFlow.placed": "Naročilo oddano",
  "order.stepsFlow.approved": "Naročilo potrjeno",
  "order.stepsFlow.sent": "Naročilo odposlano",
  "order.stepsFlow.shipping": "Odpošiljanje naročila",
  "order.stepsFlow.finished": "Naročilo zaključeno",
  "order.stepsFlow.cancelled": "Naročilo preklicano",
  "order.state.unknown": "Obdelujem",
  "order.state.waiting-for-seller-confirmation": "Obdelujem",
  "order.state.order-created": "Obdelujem",
  "order.state.order-completed": "Obdelujem",
  "order.state.on-order-completed": "Obdelujem",
  "order.state.payment-pending": "Obdelujem plačilo",
  "order.state.window-to-cancel": "Obravnavanje odpošiljanja",
  "order.state.approve-payment": "Obravnavanje odpošiljanja",
  "order.state.payment-approved": "Plačilo odobreno",
  "order.state.request-cancel": "Zahteva za preklic",
  "order.state.cancel": "Obdelujem preklic",
  "order.state.canceled": "Preklicano",
  "order.state.waiting-for-seller-decision": "Preklic zahtevan",
  "order.state.invoice": "Odpošiljanje",
  "order.state.invoiced": "Odposlano",
  "order.state.replaced": "Zamenjano",
  "order.state.cancellation-requested": "Preklic zahtevan",
  "order.state.ready-for-handling": "Obravnavanje odpošiljanja",
  "order.state.handling": "Obravnavanje odpošiljanja",
  "order.state.authorize-fullfilment": "Obdelujem plačilo",
  "order.state.release-to-fulfillment": "Obravnavanje odpošiljanja",
  "order.state.delivered": "Dobavljeno",
  "order.state.ready-for-pickup": "Pripravljeno za prevzem",
  "order.state.pickedUp": "Prevzeto",
  "order.state.handlingPickup": "Obravnavanje naročila",
  "order.progress.pickup": "Prevzemi",
  "order.progress.confirmOrder": "Oddaj naročilo",
  "order.progress.confirmingOrder": "Oddajanje naročila",
  "order.progress.orderConfirmed": "Naročilo oddano",
  "order.progress.approvePayment": "Odobri plačilo",
  "order.progress.approvingPayment": "Odobravanje plačila",
  "order.progress.paymentApproved": "Plačilo odobreno",
  "order.progress.handleShipping": "Obravnaj naročilo",
  "order.progress.handlingShipping": "Obravnavanje naročila",
  "order.progress.shippingHandled": "Paket obravnan",
  "order.progress.deliverToCarrier": "Dobava ponudniku",
  "order.progress.delivering": "Dobavavljanje naročila",
  "order.progress.delivered": "Naročilo dobavljeno",
  "order.progress.deliverToPickup": "Odpošlji na točko prevzema",
  "order.progress.deliveringToPickup": "Pošiljanje na točko prevzema",
  "order.progress.deliveredToPickup": "Poslano na točko prevzema",
  "order.progress.ship": "Odpošlji naročilo",
  "order.progress.shipping": "Odpošiljanje naročila",
  "order.progress.shipped": "Naročilo odposlano",
  "package.progress.handleShipping": "Obravnavaj paket",
  "package.progress.handlingShipping": "Obravnavanje paketa",
  "package.progress.shippingHandled": "Paket obravnan",
  "package.progress.deliverToCarrier": "Dobavi naročilo",
  "package.progress.delivering": "Na poti k prevozniku",
  "package.progress.delivered": "Naročilo dobavljeno",
  "package.progress.ship": "Odpošlji paket",
  "package.progress.shipping": "Odpošiljanje paketa",
  "package.progress.shipped": "Paket odposlan",
  "order.summary.title": "Povzetek",
  "order.summary.total": "Skupaj",
  "order.shippingInfo": "Naslov",
  "order.paymentInfo": "Podatki o plačilu",
  "order.package.heading": "Paket",
  "order.package.numbering": "od",
  "order.package.day": "dan",
  "order.package.product": "Izdelek",
  "order.package.price": "Cena",
  "order.package.quantity": "Količina",
  "order.package.total": "Skupaj",
  "order.shippingEstimate.bd": "{timeAmount, plural, =0 {Isti dan} one {Pripravljeno v # delovnem dnevu} two {Pripravljeno v # delovnih dneh} few {Pripravljeno v # delovnih dneh} other {Pripravljeno v # delovnih dneh}}",
  "order.shippingEstimate.d": "{timeAmount, plural, =0 {Isti dan} one {Dobavljeno v # dnevu} two {Dobavljeno v # delovnih dneh} few {Dobavljeno v # delovnih dneh} other {Dobavljeno v # delovnih dneh}}",
  "order.shippingEstimate.h": "{timeAmount, plural, =0 {Zdaj} one {Dobavljeno v # uri} two {Dobavljeno v # urah} few {Dobavljeno v # urah} other {Dobavljeno v # urah}}",
  "order.shippingEstimate.m": "{timeAmount, plural, =0 {Zdaj} one {Dobavljeno v # minuti} two {Dobavljeno v # minutah} few {Dobavljeno v # minutah} other {Dobavljeno v # minutah}}",
  "order.shippingEstimate.withTime": "Dobava do {date} ob {hour}",
  "order.shippingEstimate.noTime": "Dobava do {date}",
  "order.shippingEstimate.window": "Dobava {date}, med {startHour} in {endHour}",
  "order.shippingEstimate.pickup.withTime": "Prevzem mogoč do {date} ob {hour}",
  "order.shippingEstimate.pickup.noTime": "Prevzem mogoč do {date}",
  "order.shippingEstimate.pickup.window": "Prevzem mogoč do {date}, med {startHour} in {endHour}",
  "order.tracking.date": "Datum",
  "order.tracking.time": "Čas",
  "order.tracking.status": "Stanje",
  "order.tracking.showMore": "Pokaži več",
  "paymentData.additionalInfo": "Dodatne informacije",
  "paymentData.paymentGroup.MercadoPago.name": "MercadoPago",
  "paymentData.paymentGroup.payPal.name": "PayPal",
  "paymentData.paymentGroup.stelo.name": "Stelo",
  "paymentData.paymentGroup.safetypay.name": "Spletna bremenitev",
  "paymentData.paymentGroup.Bcash.name": "Bcash",
  "paymentData.paymentGroup.giftCard.name": "Darilna kartica",
  "paymentData.paymentGroup.debit.name": "Spletna bremenitev",
  "paymentData.paymentGroup.debitCard.name": "Debetna kartica",
  "paymentData.paymentGroup.creditDirectSale.name": "Plačilo s PIN številčnico",
  "paymentData.paymentGroup.creditCard.name": "Kreditna kartica",
  "paymentData.paymentGroup.creditCard.endingIn": "poteče na",
  "paymentData.paymentGroup.bankInvoice.name": "Račun",
  "paymentData.paymentGroup.evolucard.name": "Evolucard",
  "paymentData.paymentGroup.promissory.name": "Zadolžnica",
  "paymentData.paymentGroup.alignet.name": "Alignet",
  "paymentData.paymentGroup.pagSeguro.name": "PagSeguro",
  "paymentData.paymentGroup.pagosWeb.name": "Načini plačila",
  "paymentData.paymentGroup.peela.name": "Peela",
  "paymentData.paymentGroup.koin.name": "Koin Pós-Pago",
  "paymentData.giftCard.loyalty-program.name": "Program zvestobe",
  "reasons.shipping": "Sprememba podatkov odpošiljanja",
  "reasons.payment": "Sprememba podatkov plačila",
  "reasons.profile": "Sprememba osebnih podatkov",
  "reasons.unknown": "Razlogi niso določeni",
  "global.unknownError": "Pojavila se je nepričakovana napaka, poskušamo jo rešiti. Poskusite znova kasneje",
  "global.errorServer": "Pojavila se je napaka v naših serverjih. Poskusite znova kasneje.",
  "global.loginNeeded": "Morate se prijaviti.",
  "global.unauthorized": "Niste pooblaščeni za dostop do tega.",
  "global.notFound": "Ni bilo najdeno",
  "order.subscription": "Naročnina",
  "order.subscription.key.frequency": "Frekvenca",
  "product.quantity": "{qtd, plural, one {# e} two {# e} few {# e} other {# e}}"
}

```