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

[User] Show me the implementation of pwa-gtm-pixel/react/modules/push.ts from the pwa-gtm-pixel VTEX app.

[Assistant]
Here's the implementation:

```typescript
window.dataLayer = window.dataLayer || []

export default function push(event: any) {
  window.dataLayer.push(event)
}
```


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

[User] Show me the implementation of order-configuration/messages/pt.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/form.error.required": "Este campo é necessário",
  "store/form.error.maxLength": "Este campo deve ter até {value} caracteres",
  "store/form.error.minLength": "Este campo deve ter no mínimo {value} caracteres",
  "store/form.error.maxValue": "O valor máximo aceito neste campo é {value}",
  "store/form.error.minValue": "O valor mínimo aceito neste campo é {value}",
  "store/form.error.notFloat": "Deve ser um número",
  "store/form.error.notInteger": "Deve ser um número inteiro",
  "store/form.error.pattern": "Este texto não corresponde com o padrão esperado",
  "store/form.error.notInEnum": "Deve ser algum dos seguintes valores: {values}",
  "store/form.error.multipleOf": "Este campo deve ser um mútiplo de {value}",
  "store/form.error.undefinedError": "Valor inválido.",
  "store/form.submit.buttonLabel": "Salvar",
  "store/form.submit.error.userInputError": "Foram encontrados alguns erros nos dados fornecidos, revise os campos indicados e tente novamente.",
  "store/form.submit.error.serverError": "Erro interno do servidor! Por favor, tente novamente mais tarde!",
  "store/form.schema.loading": "Carregando o formulário...",
  "store/form.schema.error": "Erro carregando o formulário, tente de novo mais tarde!",
  "store/form.submit.success": "Preços atualizados com base na nova configuração de pedido",
  "admin/editor.custom-price-selector.title": "Configuração da ordem",
  "admin/editor.custom-price-selector.description": "Configuração de pedidos para usuários B2B",
  "admin/editor.custom-price-selector.formTitle.title": "Título do formulário",
  "admin/editor.custom-price-selector.formFields.title": "Campos do formulário",
  "admin/editor.custom-price-selector.formFields.name": "Nome do campo",
  "admin/editor.custom-price-selector.formFields.type": "Tipo de campo",
  "admin/editor.custom-price-selector.formFields.fieldType": "Tipo de entrada do campo",
  "admin/editor.custom-price-selector.formFields.label": "Legenda do campo",
  "admin/editor.custom-price-selector.formFields.required": "Requeridos",
  "admin/editor.custom-price-selector.formFields.showInTitle": "Mostrar no título",
  "admin/editor.custom-price-selector.formFields.format": "Formato de entrada",
  "admin/editor.custom-price-selector.formFields.options": "Opções de entrada",
  "admin/editor.custom-price-selector.formFields.options.description": "Opções em caso de seleção, rádio ou caixa de seleção",
  "admin/editor.custom-price-selector.formFields.options.label": "Etiqueta da opção",
  "admin/editor.custom-price-selector.formFields.options.value": "Valor da opção"
}

```


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

[User] Show me the implementation of order-configuration/messages/ar-SA.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/form.error.required": "هذا الحقل مطلوب",
  "store/form.error.maxLength": "هذا الحقل له حد أقصى من الطول هو: {value}",
  "store/form.error.minLength": "هذا الحقل له حد أدنى من الطول هو: {value}",
  "store/form.error.maxValue": "القيمة القصوى المقبولة من هذا الحقل هي {value}",
  "store/form.error.minValue": "القيمة الدنيا المقبولة من هذا الحقل هي {value}",
  "store/form.error.notFloat": "يجب أن يكون رقماً",
  "store/form.error.notInteger": "يجب أن يكون عدد صحيح",
  "store/form.error.pattern": "هذا النص لا يتطابق مع النمط المتوقع",
  "store/form.error.notInEnum": "يجب أن تكون واحدة من القيم التالية: {values}",
  "store/form.error.multipleOf": "يجب أن يكون من مضاعفات {value}",
  "store/form.error.undefinedError": "قيمة غير صالحة.",
  "store/form.submit.buttonLabel": "حفظ",
  "store/form.submit.error.userInputError": "تم العثور على بعض الأخطاء في البيانات المقدمة، يرجى مراجعة الحقول المشار إليها حاول مرة أخرى!",
  "store/form.submit.error.serverError": "خطأ داخلي في الخادم! الرجاء المحاولة مرة أخرى لاحقاً!",
  "store/form.schema.loading": "تحميل الاستمارة...",
  "store/form.schema.error": "خطأ في تحميل الاستمارة، حاول مرة أخرى لاحقاً!",
  "store/form.submit.success": "تم تحديث الأسعار على أساس إعداد الطلب الجديد",
  "admin/editor.custom-price-selector.title": "إعداد الطلب",
  "admin/editor.custom-price-selector.description": "إعداد الطلب لمستخدمي B2B",
  "admin/editor.custom-price-selector.formTitle.title": "عنوان الاستمارة",
  "admin/editor.custom-price-selector.formFields.title": "من الحقول",
  "admin/editor.custom-price-selector.formFields.name": "اسم الحقل",
  "admin/editor.custom-price-selector.formFields.type": "نوع الحقل",
  "admin/editor.custom-price-selector.formFields.fieldType": "نوع إدخال الحقل",
  "admin/editor.custom-price-selector.formFields.label": "تسمية الحقل",
  "admin/editor.custom-price-selector.formFields.required": "مطلوب",
  "admin/editor.custom-price-selector.formFields.showInTitle": "عرض في العنوان",
  "admin/editor.custom-price-selector.formFields.format": "تنسيق الإدخال",
  "admin/editor.custom-price-selector.formFields.options": "خيارات الإدخال",
  "admin/editor.custom-price-selector.formFields.options.description": "خيارات في حالة الاختيار أو اللاسلكي أو مربع الاختيار",
  "admin/editor.custom-price-selector.formFields.options.label": "تسمية الخيار",
  "admin/editor.custom-price-selector.formFields.options.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 order-configuration/messages/en.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/form.error.required": "This field is required",
  "store/form.error.maxLength": "This field has a max length of: {value}",
  "store/form.error.minLength": "This field has a min length of: {value}",
  "store/form.error.maxValue": "The maximum value accepted by this field is {value}",
  "store/form.error.minValue": "The minimum value accepted by this field is {value}",
  "store/form.error.notFloat": "Must be a number",
  "store/form.error.notInteger": "Must be an integer",
  "store/form.error.pattern": "This text does not match the expected pattern",
  "store/form.error.notInEnum": "Must one of the following values: {values}",
  "store/form.error.multipleOf": "Must be a multiple of {value}",
  "store/form.error.undefinedError": "Invalid value.",
  "store/form.submit.buttonLabel": "Save",
  "store/form.submit.error.userInputError": "Found some errors in the data provided, please review the indicated fields try again!",
  "store/form.submit.error.serverError": "Internal Server Error! Please, try again later!",
  "store/form.schema.loading": "Loading form...",
  "store/form.schema.error": "Error loading form, try again later!",
  "store/form.submit.success": "Prices updated based on new order configuration",
  "admin/editor.custom-price-selector.title": "Order Configuration",
  "admin/editor.custom-price-selector.description": "Order configuration for B2B users",
  "admin/editor.custom-price-selector.formTitle.title": "Form Title",
  "admin/editor.custom-price-selector.formFields.title": "Form Fields",
  "admin/editor.custom-price-selector.formFields.name": "Field Name",
  "admin/editor.custom-price-selector.formFields.type": "Field Type",
  "admin/editor.custom-price-selector.formFields.fieldType": "Field Input Type",
  "admin/editor.custom-price-selector.formFields.label": "Field Label",
  "admin/editor.custom-price-selector.formFields.required": "Required",
  "admin/editor.custom-price-selector.formFields.showInTitle": "Show in Title",
  "admin/editor.custom-price-selector.formFields.format": "Input Format",
  "admin/editor.custom-price-selector.formFields.options": "Input Options",
  "admin/editor.custom-price-selector.formFields.options.description": "Options in case of select, radio or checkbox",
  "admin/editor.custom-price-selector.formFields.options.label": "Option Label",
  "admin/editor.custom-price-selector.formFields.options.value": "Option 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 order-configuration/messages/context.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/form.error.required": "This field is required",
  "store/form.error.maxLength": "This field has a max length of: {value}",
  "store/form.error.minLength": "This field has a min length of: {value}",
  "store/form.error.maxValue": "The maximum value accepted by this field is {value}",
  "store/form.error.minValue": "The minimum value accepted by this field is {value}",
  "store/form.error.notFloat": "Must be a number",
  "store/form.error.notInteger": "Must be an integer",
  "store/form.error.pattern": "This text does not match the expected pattern",
  "store/form.error.notInEnum": "Must one of the following values: {values}",
  "store/form.error.multipleOf": "Must be a multiple of {value}",
  "store/form.error.undefinedError": "Invalid value.",
  "store/form.submit.buttonLabel": "Save",
  "store/form.submit.error.userInputError": "Found some errors in the data provided, please review the indicated fields try again!",
  "store/form.submit.error.serverError": "Internal Server Error! Please, try again later!",
  "store/form.schema.loading": "Loading form...",
  "store/form.schema.error": "Error loading form, try again later!",
  "store/form.submit.success": "Prices updated based on new order configuration",
  "admin/editor.custom-price-selector.title": "Order Configuration",
  "admin/editor.custom-price-selector.description": "Order configuration for B2B users",
  "admin/editor.custom-price-selector.formTitle.title": "Form Title",
  "admin/editor.custom-price-selector.formFields.title": "Form Fields",
  "admin/editor.custom-price-selector.formFields.name": "Field Name",
  "admin/editor.custom-price-selector.formFields.type": "Field Type",
  "admin/editor.custom-price-selector.formFields.fieldType": "Field Input Type",
  "admin/editor.custom-price-selector.formFields.label": "Field Label",
  "admin/editor.custom-price-selector.formFields.required": "Required",
  "admin/editor.custom-price-selector.formFields.showInTitle": "Show in Title",
  "admin/editor.custom-price-selector.formFields.format": "Input Format",
  "admin/editor.custom-price-selector.formFields.options": "Input Options",
  "admin/editor.custom-price-selector.formFields.options.description": "Options in case of select, radio or checkbox",
  "admin/editor.custom-price-selector.formFields.options.label": "Option Label",
  "admin/editor.custom-price-selector.formFields.options.value": "Option 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 order-configuration/messages/es.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/form.error.required": "Este campo es requerido",
  "store/form.error.maxLength": "Este campo tiene una longitud máxima de: {value}",
  "store/form.error.minLength": "Este campo tiene una longitud mínima de: {value}",
  "store/form.error.maxValue": "El valor máximo aceptado por este campo es {value}",
  "store/form.error.minValue": "El valor mínimo aceptado por este campo es {value}",
  "store/form.error.notFloat": "Debe ser un número",
  "store/form.error.notInteger": "Debe ser un entero",
  "store/form.error.pattern": "Este texto no coincide con el patrón esperado",
  "store/form.error.notInEnum": "Debe ser uno de los siguientes valores: {values}",
  "store/form.error.multipleOf": "Debe ser un mútiplo de {value}",
  "store/form.error.undefinedError": "Valor no válido.",
  "store/form.submit.buttonLabel": "Salvar",
  "store/form.submit.error.userInputError": "Encontrado algunos errores en los datos, revise los campos indicados e intente nuevamente.",
  "store/form.submit.error.serverError": "¡Error interno de servidor! ¡Por favor, inténtelo de nuevo más tarde!",
  "store/form.schema.loading": "Cargando formulario...",
  "store/form.schema.error": "Error al cargar el formulario¡Inténtalo de nuevo más tarde!",
  "store/form.submit.success": "Precios actualizados en función de la nueva configuración del pedido",
  "admin/editor.custom-price-selector.title": "Configuración de pedido",
  "admin/editor.custom-price-selector.description": "Configuración de pedidos para usuarios B2B",
  "admin/editor.custom-price-selector.formTitle.title": "Título del formulario",
  "admin/editor.custom-price-selector.formFields.title": "Campos de formulario",
  "admin/editor.custom-price-selector.formFields.name": "Nombre del campo",
  "admin/editor.custom-price-selector.formFields.type": "Tipo de campo",
  "admin/editor.custom-price-selector.formFields.fieldType": "Tipo de entrada de campo",
  "admin/editor.custom-price-selector.formFields.label": "Etiqueta de campo",
  "admin/editor.custom-price-selector.formFields.required": "Necesario",
  "admin/editor.custom-price-selector.formFields.showInTitle": "Mostrar en el título",
  "admin/editor.custom-price-selector.formFields.format": "Formato de entrada",
  "admin/editor.custom-price-selector.formFields.options": "Opciones de entrada",
  "admin/editor.custom-price-selector.formFields.options.description": "Opciones en caso de seleccionar, radio o casilla de verificación",
  "admin/editor.custom-price-selector.formFields.options.label": "Etiqueta de opción",
  "admin/editor.custom-price-selector.formFields.options.value": "Valor de la opción"
}

```


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

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

[Assistant]
Here's the implementation:

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

# Order Configuration

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

The **Order Configuration** app, designed for B2B scenarios, displays a form responsible for collecting order data in a modal.

![order-configuration-gif](https://user-images.githubusercontent.com/52087100/91925199-e5125200-ecaa-11ea-8734-f98921ddb384.gif)

Once the form is submitted, the order data collected will be available at Master Data and saved in the current VTEX session.

> ℹ This app can be used to enable customization of all kinds of behaviors, such as custom prices, custom products, etc. Keep in mind the Order Configuration app does not offer these functionalities, it only enables other apps to do so.

Follow the steps below to install and set up the **Order Configuration** app in your store.

### Step 1: Install the app

 First, you must add the `order-configuration` app to your theme's dependencies in the `manifest.json` file:

```json
dependencies: {
  "vtex.order-configuration": "2.x"
}
```

This will enable you to use the blocks exported by the `order-configuration` app. Check out the full list below:

| Block name     | Description                                     |
| -------------- | ----------------------------------------------- |
| `order-config` | Parent block only responsible for rendering its children blocks, that in turn build the Order Configuration component. |
| `order-config.title` | Renders the component title, that is, the message text displayed for users to present the component. On the image above, the component title is `Order Configuration`. |
| `order-config.modal` | Renders the modal responsible for displaying the component content. |
| `order-config.form` | Renders the component content, that is, a form to be filled out by users.  |

### Step 2: Declare the required blocks

Add the `order-config` block in the Header component, as shown in the example below.

```json
{
  "header-layout.desktop": {
    "children": [
      "flex-layout.row#1-desktop",
      "flex-layout.row#2-desktop",
      "flex-layout.row#3-desktop",
      "sticky-layout#4-desktop"
    ]
  },
  "flex-layout.row#3-desktop": {
    "props": {
      "blockClass": "menu-link",
      "horizontalAlign": "center",
      "preventHorizontalStretch": true,
      "preventVerticalStretch": true,
      "fullWidth": true
    },
    "children": [
      "vtex.menu@2.x:menu#websites",
      "flex-layout.col#spacer",
+     "order-config#header",
      "vtex.menu@2.x:menu#institutional"
    ]
  },
```

Then, declare the `order-config#header` block and its children blocks: `order-config.title` and `order-config.modal`. Example:

```json
{
  "order-config#header": {
    "children": [
      "order-config.title#header",
      "order-config.modal#header"
    ],
    "props": {
      "blockClass": "header",
      "formFields": [
        {
          "name": "orderType",
          "type": "string",
          "fieldType": "radio",
          "label": "Order Type",
          "defaultValue": "resale",
          "options": [
            {
              "label": "Resale",
              "value": "resale"
            },
            {
              "label": "Consumption",
              "value": "consumption"
            }
          ]
        },
        {
          "name": "state",
          "type": "string",
          "fieldType": "select",
          "label": "State",
          "showInTitle": true,
          "options": [
            {
              "label": "ES",
              "value": "ES"
            },
            {
              "label": "SP",
              "value": "SP"
            }
          ]
        }
      ]
    }
  },
  "order-config.modal#header": {
    "children": [
      "order-config.form"
    ]
  },
  "order-config.title#header": {
    "props": {
      "formTitle": "Order Configuration for Header"
    }
  },
}
```

> ℹ If the `order-config.form` block does not have any children configured, a default form will be rendered automatically based on the [React Hook Form JSON Schema](https://github.com/vtex/react-hook-form-jsonschema) library. To declare children blocks according to your business needs, check out the [Advanced configuration](#advanced-configuration) section below.

### Step 3: Create `main` schema in Master Data

You must create a schema named `main` in Master Data, using the `order_configuration` data entity.

You can place a request using the Save schema by name endpoint of the [Master Data API - v2](https://developers.vtex.com/vtex-rest-api/reference/schemas#saveschemabyname) to do so.

The schema should contain all the data that you added in the form above, otherwise the data will not be persisted.

#### Request body example

```json
{
    "v-cache": false,
    "properties": {
        "clientId": {
            "type": "string"
        },
        "orderType": {
            "type": "string"
        },
        "state": {
            "type": "string"
        }
    },
    "v-default-fields": [
        "clientId",
        "orderType",
        "state"
    ],
    "v-indexed": [
        "clientId",
        "orderType",
        "state"
    ]
}
```

Refer to [Master Data API - v2 documentation](https://developers.vtex.com/vtex-rest-api/reference/schemas#saveschemabyname) for more details.

### Step 4: Update orderForm configuration

It is also necessary to configure a new app in the `orderForm`.

First, place a `GET` [Get orderForm configuration](https://developers.vtex.com/vtex-developer-docs/reference/getorderformconfiguration) request to retrieve the current `orderForm` settings before updating them. By doing so you ensure that you will only change the properties you want in the next step.

Then, place a `POST` [Update orderForm configuration](https://developers.vtex.com/vtex-developer-docs/reference/updateorderformconfiguration) request, setting the following object inside the `apps` object in the request body:

```json
        {
            "fields": [
                "values"
            ],
            "id": "orderconfig",
            "major": 1
        }
```

#### Request body example

```json
{
    "paymentConfiguration": {
        "requiresAuthenticationForPreAuthorizedPaymentOption": false,
        "allowInstallmentsMerge": null,
        "blockPaymentSession": null,
        "paymentSystemToCheckFirstInstallment": null,
        "defaultPaymentSystemToApplyOnUserOrderForm": null
    },
    "taxConfiguration": null,
    "minimumQuantityAccumulatedForItems": 1,
    "decimalDigitsPrecision": 2,
    "minimumValueAccumulated": null,
    "apps": [
        {
            "fields": [
                "quoteId"
            ],
            "id": "b2b-quotes-graphql",
            "major": 1
        },
        {
            "fields": [
                "values"
            ],
            "id": "orderconfig",
            "major": 1
        }
    ],
    "allowMultipleDeliveries": true,
    "allowManualPrice": true,
    "maxNumberOfWhiteLabelSellers": null,
    "maskFirstPurchaseData": null,
    "recaptchaValidation": "vtexcriteria",
    "maskStateOnAddress": true
}
```

You can refer to [Checkout API documentation](https://developers.vtex.com/vtex-developer-docs/reference/updateorderformconfiguration) for more information.

### Advanced configuration

If desired, you can declare the `order-config.form` block by adding and configuring the `formFields` prop and an array of form children blocks (whose descriptions you can find below).

```json
{
  "order-config#static-page": {
    "props": {
      "formFields": [
        {
          "name": "orderType",
          "type": "string",
          "fieldType": "select",
          "label": "Order Type",
          "defaultValue": "res",
          "showInTitle": true,
          "options": [
            {
              "label": "Resale",
              "value": "res"
            },
            {
              "label": "Consumption",
              "value": "cons"
            }
          ]
        },
        {
          "name": "state",
          "type": "string",
          "fieldType": "select",
          "label": "State",
          "showInTitle": true,
          "required": true,
          "options": [
            {
              "label": "ES",
              "value": "ES"
            },
            {
              "label": "SP",
              "value": "SP"
            }
          ]
        },
        {
          "name": "someTextInput",
          "label": "Some Text Input",
          "fieldType": "input",
          "type": "string",
          "required": true,
          "showInTitle": true
        }
      ]
    },
    "children": [
      "order-config.title#static-page",
      "order-config.form#static-page"
    ]
  },
  "order-config.form#static-page": {
    "children": [
      "flex-layout.row#state-and-payment-method",
      "order-config.text#some-text-input",
      "order-config.submit"
    ]
  },
  "flex-layout.row#state-and-payment-method": {
    "children": [
      "order-config.dropdown#state",
      "order-config.radiogroup#payment-method"
    ],
    "props": {
      "blockClass": "stateAndPaymentMethod"
    }
  },
  "order-config.dropdown#state": {
    "props": {
      "pointer": "#/properties/state"
    }
  },
  "order-config.radiogroup#payment-method": {
    "props": {
      "pointer": "#/properties/paymentMethod"
    }
  },
  "order-config.text#some-text-input": {
    "props": {
      "pointer": "#/properties/someTextInput"
    }
  },
  "order-config.title#static-page": {
    "props": {
      "formTitle": "Order Configuration for Static Page"
    }
  }
}
```

| Block name     | Description                                     |
| -------------- | ----------------------------------------------- |
| `order-config.submit` | Renders a `Submit` button. |
| `order-config.dropdown` | Renders the a dropdown field. |
| `order-config.radiogroup` | Renders a radiogroup field. |
| `order-config.text` | Renders a text field. |
| `order-config.textarea` | Renders a text field with a wider range of available characters. |
| `order-config.checkbox` | Renders a checkbox field. |

#### Props

Check out the description of the available props below.

| Prop name | Type | Description  | Default Value | Block name |
| --------- | -------- | ------------| ----------------- | -------- |
| `pointer`  | `string` | Path to which the block must point in the `formFields` prop in order to properly work.  | `undefined`              | `order-config.dropdown`, `order-config.radiogroup`, `order-config.text`, `order-config.textarea`, and `order-config.checkbox` |
| `formFields`  | `object` | Object responsible for defining the form fields.  | `undefined`              | `order-config.form`  |

The `formFields` object contains the following props:

| Prop name | Type | Description                                                                                | Default Value  |
| --------| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `name` | `string` |  Name of the field (only used as an identifier in your code). | `undefined`              |
| `type` | `enum` |  Value type accepted by the field. Possible values are `string` and `number`. | `string`              |
| `fieldType` | `enum` | Input type accepted by the field. Possible values are: `text`, `textarea`, `select`, `radio`, and `checkbox`. | `text`              |
| `label` | `string` | Field name shown to users. | `undefined` |
| `showInTitle` | `boolean` |  Whether to display the value type accepted by the field on its name (`true`) or not (`false`). | `false`  |
| `options` | `object` | Field options to be defined in case `select`, `radio`, or `checkbox` values were declared in the `fieldType` prop. | `undefined`  |

The `options` object contains the following props:

| Prop name   | Type                                 | Description                                                   | Default Value |
| ----------- | ----------------------------------------- | -------------------------------------------------------------------------------------- | ----------------- |
| `label` | `string` | Option name shown to users. | `undefined`           |
| `value` | `string` | Option value. | `undefined`           |

## Customization

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

| CSS Handles |
| ----------- |
| `formSubmitButton` |
| `formSubmitContainer` |
| `formErrorServer` |
| `formErrorUserInput` |
| `loader` |
| `orderConfigFormWrapper` |
| `formObject` |
| `title` |
| `titleValues` |
| `titleWrapper` |
| `wrapper` |

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

Thanks goes to these wonderful people:

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

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

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

```


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

[User] Show me the implementation of order-configuration/graphql/schema.graphql from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```graphql
type Query {

  """
  Get orderConfiguration from our backend
  """
  orderConfiguration: OrderConfig @cacheControl(scope: PRIVATE, maxAge: SHORT)
}

input FieldInput {
  Key: String!
  Value: String!
}

input OrderConfigInput {
  fields: [FieldInput]
}

type Mutation {
  """
  Save an order configuration
  """
  saveOrderConfiguration(orderConfig: OrderConfigInput): Boolean @cacheControl(scope: PRIVATE, maxAge: SHORT)
}

```


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

[User] Show me the implementation of order-configuration/node/package.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "@vtex/clients": "^1.0.4",
    "axios": "^0.21.0",
    "co-body": "^6.0.0",
    "cookie": "^0.4.1",
    "jsonwebtoken": "^8.5.1",
    "ramda": "^0.27.0"
  },
  "devDependencies": {
    "@types/chai": "^4.2.14",
    "@types/co-body": "0.0.3",
    "@types/cookie": "^0.4.0",
    "@types/jsonwebtoken": "^8.3.3",
    "@types/mocha": "^8.2.0",
    "@types/node": "^14.14.11",
    "@types/ramda": "^0.27.11",
    "@vtex/api": "6.37.0",
    "@vtex/tsconfig": "^0.3.0",
    "chai": "^4.2.0",
    "dotenv": "^8.2.0",
    "mocha": "^8.2.1",
    "ts-mockito": "^2.6.1",
    "ts-node": "^9.1.1",
    "tslint": "^5.14.0",
    "tslint-config-vtex": "^2.1.0",
    "typescript": "3.9.7"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty && tslint -c tslint.json --fix './**/*.ts'",
    "test": "mocha --require ts-node/register --require=dotenv/config --timeout 5000 --exit \"test/**/*.test.ts\""
  },
  "version": "3.3.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 order-configuration/node/globals.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {
  IOContext,
  MetricsAccumulator,
  ParamsContext,
  RecorderState,
  SegmentData,
  ServiceContext
} from "@vtex/api";

import { Clients } from "./clients";

if (!global.metrics) {
  console.error("No global.metrics at require time");
  global.metrics = new MetricsAccumulator();
}

export type Context = ServiceContext<Clients, RecorderState, CustomContext>;

declare global {
  type Context = ServiceContext<Clients, RecorderState, CustomContext>;

  interface CustomContext extends ParamsContext {
    cookie: string;
    originalPath: string;
    vtex: CustomIOContext;
  }

  interface CustomIOContext extends IOContext {
    segment?: SegmentData;
    orderFormId?: string;
  }

  interface KeyValue {
    key: string;
    value: string;
  }

  interface Property {
    name: string;
    values: [string];
  }
}

```


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

[User] Show me the implementation of order-configuration/node/index.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import "./globals";

import { LRUCache, RecorderState, Service } from "@vtex/api";

import { Clients } from "./clients";
// import { dataSources } from './dataSources'
// import { schemaDirectives } from './directives'
import { resolvers } from "./resolvers";

const TWO_SECONDS_MS = 2 * 1000;
const THREE_SECONDS_MS = 3 * 1000;
// const SIX_SECONDS_MS = 6 * 1000
const TEN_SECONDS_MS = 10 * 1000;
const THIRTY_SECONDS_MS = 30 * 1000;

// Segments are small and immutable.
const MAX_SEGMENT_CACHE = 10000;
const segmentCache = new LRUCache<string, any>({ max: MAX_SEGMENT_CACHE });
// const catalogCache = new LRUCache<string, any>({max: 3000})
const messagesCache = new LRUCache<string, any>({ max: 3000 });

export default new Service<Clients, RecorderState, CustomContext>({
  clients: {
    implementation: Clients,
    options: {
      checkout: {
        concurrency: 10,
        timeout: THIRTY_SECONDS_MS
      },
      default: {
        retries: 2,
        timeout: THREE_SECONDS_MS
      },
      messagesGraphQL: {
        concurrency: 5,
        memoryCache: messagesCache,
        timeout: TWO_SECONDS_MS
      },
      session: {
        concurrency: 10,
        timeout: TEN_SECONDS_MS
      },
      segment: {
        concurrency: 10,
        memoryCache: segmentCache,
        timeout: THREE_SECONDS_MS
      }
    }
  },
  graphql: {
    // dataSources,
    resolvers
    // schemaDirectives,
  }
});

```


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

[User] Show me the implementation of order-configuration/react/OrderConfigurationModal.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useCallback } from 'react'
import { pathOr } from 'ramda'

import { ButtonWithIcon, IconEdit, Modal } from 'vtex.styleguide'
import {
  useOrderConfigurationDispatch,
  useOrderConfiguration,
} from './OrderConfigurationContext'

const OrderConfigurationModal = (props: { title: string; children: any }) => {
  const dispatch = useOrderConfigurationDispatch()
  const {
    modal: { isOpen },
  } = useOrderConfiguration()
  const onModalOpen = useCallback(() => {
    dispatch({ type: 'SET_MODAL_OPEN', args: { isModalOpen: true } })
  }, [dispatch])
  const onModalClose = useCallback(() => {
    dispatch({ type: 'SET_MODAL_CLOSED', args: { isModalOpen: false } })
  }, [dispatch])

  return (
    <div className="tc">
      <div className="h-100">
        <div className="h-100 flex items-center">
          <ButtonWithIcon
            icon={<IconEdit />}
            iconPosition="right"
            variation="secondary"
            onClick={onModalOpen}
          />
        </div>

        <Modal
          centered
          isOpen={isOpen}
          onClose={onModalClose}
          title={pathOr('Order Configuration', ['title'], props)}
        >
          {props.children}
        </Modal>
      </div>
    </div>
  )
}

export default OrderConfigurationModal

```


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

[User] Show me the implementation of order-configuration/react/Title.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useCallback } from 'react'
import { filter, pick, values } from 'ramda'
import { useCssHandles } from 'vtex.css-handles'
import {
  useOrderConfigurationDispatch,
  useOrderConfiguration,
} from './OrderConfigurationContext'
const CSS_HANDLES = ['title', 'titleValues', 'titleWrapper'] as const

const Title: StorefrontFunctionComponent<{
  formTitle: string
}> = props => {
  const handles = useCssHandles(CSS_HANDLES)
  const { selectedValues, formFields } = useOrderConfiguration()
  const dispatch = useOrderConfigurationDispatch()
  const { formTitle } = props
  const onModalOpen = useCallback(() => {
    dispatch({ type: 'SET_MODAL_OPEN', args: { isModalOpen: true } })
  }, [dispatch])

  return (
    <div
      onClick={onModalOpen}
      aria-hidden="true"
      className={`flex items-center shadow-hover ${handles.titleWrapper}`}
    >
      <span className={`mr4 ${handles.title}`}>{formTitle}</span>
      <span className={`mr4 fw6 ${handles.titleValues}`}>
        {values(
          pick(
            filter(field => field.showInTitle, formFields).map(
              field => field.name
            ),
            selectedValues
          )
        ).join(', ')}
      </span>
    </div>
  )
}

Title.defaultProps = {
  formTitle: 'Order Configuration',
}

export default 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 order-configuration/react/OrderConfigurationContext.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { createContext, useReducer, useContext, FC } from 'react'
import { FormField } from './typings/FormProps'
import { OrderConfiguration } from './typings/global'

const OrderConfigurationContext = createContext<State | undefined>(undefined)
const OrderConfigurationDispatchContext = createContext<Dispatch | undefined>(
  undefined
)

interface State {
  isLoading: boolean
  modal: {
    isOpen: boolean
  }
  selectedValues: OrderConfiguration
  formFields: FormField[]
}

type Dispatch = (action: Action) => void

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

interface SetModalOpenAction {
  type: 'SET_MODAL_OPEN'
  args: {
    isModalOpen: boolean
  }
}

interface SetModalClosedAction {
  type: 'SET_MODAL_CLOSED'
  args: {
    isModalOpen: boolean
  }
}

type Action = SetLoadingAction | SetModalOpenAction | SetModalClosedAction

export const reducer = (state: State, action: Action) => {
  switch (action.type) {
    case 'SET_LOADING': {
      return {
        ...state,
        isLoading: action.args.isLoading,
      }
    }
    case 'SET_MODAL_OPEN': {
      return {
        ...state,
        modal: {
          ...state.modal,
          isOpen: action.args.isModalOpen,
        },
      }
    }
    case 'SET_MODAL_CLOSED': {
      return {
        ...state,
        modal: {
          ...state.modal,
          isOpen: action.args.isModalOpen,
        },
      }
    }
    default:
      return state
  }
}

interface Props {
  selectedValues: OrderConfiguration
  formFields: FormField[]
}

export const OrderConfigurationContextProvider: FC<Props> = ({
  selectedValues,
  formFields,
  children,
}) => {
  const initialState = {
    selectedValues,
    formFields,
    isLoading: true,
    modal: {
      isOpen: false,
    },
  }
  const [state, dispatch] = useReducer(reducer, initialState)
  return (
    <OrderConfigurationContext.Provider value={state}>
      <OrderConfigurationDispatchContext.Provider value={dispatch}>
        {children}
      </OrderConfigurationDispatchContext.Provider>
    </OrderConfigurationContext.Provider>
  )
}

export function useOrderConfigurationDispatch() {
  const context = useContext(OrderConfigurationDispatchContext)

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

  return context
}

export function useOrderConfiguration() {
  const context = useContext(OrderConfigurationContext)

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

  return context
}

```


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

[User] Show me the implementation of order-configuration/react/FormInputRadiogroup.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { RadioGroupInput } from './components/RadioGroup'

export default RadioGroupInput

```


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

[User] Show me the implementation of order-configuration/react/FormSubmit.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useContext } from 'react'
import { defineMessages } from 'react-intl'
import { Button, Alert } from 'vtex.styleguide'
import { useCssHandles } from 'vtex.css-handles'
import { IOMessage } from 'vtex.native-types'

import { SubmitContext } from './logic/formState'

export interface FormSubmitProps {
  label?: string
}

const CSS_HANDLES = [
  'formSubmitContainer',
  'formSubmitButton',
  'formErrorServer',
  'formErrorUserInput',
] as const

const messages = defineMessages({
  submitButton: {
    id: 'store/form.submit.buttonLabel',
    defaultMessage: '',
  },
  userInputError: {
    id: 'store/form.submit.error.userInputError',
    defaultMessage: '',
  },
  serverError: {
    id: 'store/form.submit.error.serverError',
    defaultMessage: '',
  },
})

export default function FormSubmit({
  label = messages.submitButton.id,
}: FormSubmitProps) {
  const { loading, userInputError, serverError } = useContext(SubmitContext)
  const handles = useCssHandles(CSS_HANDLES)

  return (
    <div className={handles.formSubmitContainer}>
      <div className={handles.formSubmitButton}>
        <Button type="submit" isLoading={loading}>
          <IOMessage id={label} />
        </Button>
      </div>
      <div className={handles.formErrorUserInput}>
        {userInputError && (
          <Alert type="error">
            <IOMessage id={messages.userInputError.id} />
          </Alert>
        )}
      </div>
      <div className={handles.formErrorServer}>
        {serverError && (
          <Alert type="error">
            <IOMessage id={messages.serverError.id} />
          </Alert>
        )}
      </div>
    </div>
  )
}

```


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

[User] Show me the implementation of order-configuration/react/OrderConfigurationSelector.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useQuery } from 'react-apollo'
import { useCssHandles } from 'vtex.css-handles'

import orderConfiguration from './queries/orderConfiguration.graphql'
import { OrderConfigurationContextProvider } from './OrderConfigurationContext'
import { FormField } from './typings/FormProps'
import { fromFieldArrayFormat } from './logic/fromFieldArrayFormat'

const CSS_HANDLES = ['loader', 'wrapper'] as const

interface Props {
  formFields: FormField[]
}

const OrderConfigurationSelector: StorefrontFunctionComponent<Props> = props => {
  const { data, loading } = useQuery(orderConfiguration, {
    ssr: false,
  })
  const orderConfigurationFields =
    data && data.orderConfiguration && data.orderConfiguration.fields
  const orderConfigurationLoading = loading

  const handles = useCssHandles(CSS_HANDLES)

  if (orderConfigurationLoading) {
    return (
      <div className={`h-100 flex items-center ${handles.loader}`}>
        Loading...
      </div>
    )
  }

  const selectedValues = orderConfigurationFields
    ? fromFieldArrayFormat(orderConfigurationFields)
    : {}

  return (
    <OrderConfigurationContextProvider
      selectedValues={selectedValues}
      formFields={props.formFields}
    >
      <div className={`mw9 center flex flex-column ${handles.wrapper}`}>
        {props.children}
      </div>
    </OrderConfigurationContextProvider>
  )
}

OrderConfigurationSelector.schema = {
  title: 'admin/editor.custom-price-selector.title',
  description: 'admin/editor.custom-price-selector.description',
  type: 'object',
  properties: {
    formTitle: {
      title: 'admin/editor.custom-price-selector.formTitle.title',
      type: 'string',
      default: 'Order Configuration',
    },
    formFields: {
      title: 'admin/editor.custom-price-selector.formFields.title',
      type: 'array',
      items: {
        title: 'admin/editor.custom-price-selector.formFields.title',
        type: 'object',
        properties: {
          name: {
            title: 'admin/editor.custom-price-selector.formFields.name',
            type: 'string',
          },
          type: {
            title: 'admin/editor.custom-price-selector.formFields.type',
            type: 'string',
            enum: ['string', 'number'],
            enumNames: ['String', 'Number'],
            widget: {
              'ui:widget': 'radio',
            },
            default: 'string',
          },
          fieldType: {
            title: 'admin/editor.custom-price-selector.formFields.fieldType',
            type: 'string',
            enum: ['text', 'textarea', 'select', 'radio', 'checkbox'],
            enumNames: ['Text', 'Textarea', 'Select', 'Radio', 'Checkbox'],
            default: 'text',
          },
          label: {
            title: 'admin/editor.custom-price-selector.formFields.label',
            type: 'string',
          },
          required: {
            title: 'admin/editor.custom-price-selector.formFields.required',
            type: 'boolean',
          },
          showInTitle: {
            title: 'admin/editor.custom-price-selector.formFields.showInTitle',
            type: 'boolean',
            default: false,
          },
          format: {
            title: 'admin/editor.custom-price-selector.formFields.format',
            type: 'string',
            enum: ['', 'email', 'date-time', 'hostname', 'ipv4', 'ipv6', 'uri'],
            enumNames: [
              'Not specified',
              'Email',
              'Date/time in ISO format',
              'Internet host name',
              'IPv4 address',
              'IPv6 address',
              'A universal resource identifier',
            ],
          },
          options: {
            title: 'admin/editor.custom-price-selector.formFields.options',
            description:
              'admin/editor.custom-price-selector.formFields.options.description',
            type: 'array',
            items: {
              title: 'admin/editor.custom-price-selector.formFields.options',
              type: 'object',
              properties: {
                label: {
                  title:
                    'admin/editor.custom-price-selector.formFields.options.label',
                  type: 'string',
                },
                value: {
                  title:
                    'admin/editor.custom-price-selector.formFields.options.value',
                  type: 'string',
                },
              },
            },
          },
        },
      },
    },
  },
}

export default OrderConfigurationSelector

```


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

[User] Show me the implementation of order-configuration/react/FormInputText.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

import { RawInput, HiddenInput, PasswordInput } from './components/Input'
import { FormRawInputProps, InputTypes } from './typings/InputProps'

export default function FormInput(props: FormRawInputProps) {
  const { inputType = InputTypes.input, ...rest } = props

  const INPUT_TYPES = {
    [InputTypes.input]: <RawInput {...rest} pointer={props.pointer} />,
    [InputTypes.hidden]: <HiddenInput {...rest} pointer={props.pointer} />,
    [InputTypes.password]: <PasswordInput {...rest} pointer={props.pointer} />,
  }

  return INPUT_TYPES[inputType]
}

```


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

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

[Assistant]
Here's the implementation:

```json
{
  "name": "custom-price-selector",
  "version": "3.3.1",
  "scripts": {
    "test": "vtex-test-tools test",
    "lint": "tsc --noEmit && eslint --ext ts,tsx ."
  },
  "dependencies": {
    "@vtex/css-handles": "^1.0.0",
    "apollo-cache-inmemory": "^1.6.6",
    "apollo-client": "^2.6.8",
    "apollo-link-http": "^1.5.17",
    "classnames": "^2.2.6",
    "ramda": "^0.26.1",
    "react": "^16.8.3",
    "react-apollo": "^3.1.3",
    "react-dom": "^16.8.3",
    "react-hook-form-jsonschema": "0.2.0-beta.11",
    "react-intl": "^4.5.3",
    "unfetch": "^4.2.0"
  },
  "devDependencies": {
    "@types/classnames": "^2.2.7",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.7.5",
    "@types/prop-types": "^15.7.0",
    "@types/ramda": "^0.26.5",
    "@types/react": "^16.9.2",
    "@vtex/test-tools": "^1.1.0",
    "apollo-client": "^2.5.1",
    "eslint": "^5.16.0",
    "eslint-config-vtex-react": "^4.1.0",
    "prettier": "^1.18.2",
    "tslint-eslint-rules": "^5.4.0",
    "typescript": "3.9.7"
  }
}

```


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

[User] Show me the implementation of order-configuration/react/OrderConfigurationForm.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { contains, pathOr } from 'ramda'
import { FormattedMessage } from 'react-intl'
import { UITypes } from 'react-hook-form-jsonschema'

import { CustomPriceSelectorProps, FormField } from './typings/FormProps'
import { TOAST_DURATION_MS } from './utils/toast'
import { ObjectMapper } from './components/Object'
import { FormHandler } from './components/FormHandler'
import FormSubmit from './FormSubmit'
import { useOrderConfiguration } from './OrderConfigurationContext'
import { ToastConsumer } from 'vtex.styleguide'
import { ToastRenderProps } from './typings/global'

interface CustomPriceSchema {
  type: string
  properties: Record<string, object>
  required: string[]
}

interface FormFieldOption {
  value: string
}

const UI_TYPES = {
  text: UITypes.input,
  select: UITypes.select,
  radio: UITypes.radio,
  checkbox: UITypes.checkbox,
}

const generatePriceSchema = (formFields: FormField[]) =>
  formFields.reduce(
    (acc: CustomPriceSchema, formField) => {
      const hasEnum = contains(pathOr('text', ['fieldType'], formField), [
        'select',
        'radio',
      ])

      const fieldProps = {
        type: formField.type || 'string',
        title: formField.label || formField.name,
        enum: hasEnum
          ? (formField.options || []).map(
              (option: FormFieldOption) => option.value
            )
          : undefined,
        format: formField.format ?? '',
      }

      return {
        ...acc,
        properties: {
          ...acc.properties,
          [formField.name]: fieldProps,
        },
        required: formField.required
          ? [...acc.required, formField.name]
          : acc.required,
      }
    },
    {
      type: 'object',
      properties: {},
      required: [],
    }
  )

const generateUISchema = (formFields: FormField[]) => {
  const properties = formFields.reduce((acc: object, formField) => {
    const fieldType: keyof typeof UI_TYPES = formField.fieldType || 'text'
    return {
      ...acc,
      [formField.name]: {
        type: UI_TYPES[fieldType],
      },
    }
  }, {})
  return { type: UITypes.default, properties }
}

const OrderConfigurationForm: StorefrontFunctionComponent<CustomPriceSelectorProps> = props => {
  const { selectedValues, formFields } = useOrderConfiguration()

  const customPriceSchema: CustomPriceSchema = generatePriceSchema(formFields)
  const UISchema = generateUISchema(formFields)

  return (
    <ToastConsumer>
      {({ showToast }: ToastRenderProps) => {
        const onSuccessfulSubmit = () => {
          window.location.reload()
          showToast({
            message: <FormattedMessage id="store/form.submit.success" />,
            duration: TOAST_DURATION_MS,
          })
        }
        if (!React.Children.count(props.children)) {
          return (
            <FormHandler
              schema={customPriceSchema}
              formProps={props}
              onSuccessfulSubmit={onSuccessfulSubmit}
            >
              <ObjectMapper
                pointer="#"
                uiSchema={UISchema}
                formFields={formFields}
                defaultValues={selectedValues}
              />
              <FormSubmit label="Submit" />
            </FormHandler>
          )
        }
        return (
          <FormHandler
            schema={customPriceSchema}
            formProps={props}
            onSuccessfulSubmit={onSuccessfulSubmit}
          >
            {props.children}
          </FormHandler>
        )
      }}
    </ToastConsumer>
  )
}

OrderConfigurationForm.defaultProps = {
  onSuccessfulSubmit: () => {
    window.location.reload()
  },
}

export default OrderConfigurationForm

```


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

[User] Show me the implementation of order-configuration/react/FormInputDropdown.tsx from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { DropdownInput } from './components/Dropdown'

export default DropdownInput

```


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

[User] Show me the implementation of order-configuration/store/blocks.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "order-config": {
    "props": {
      "formFields": [
        {
          "name": "orderType",
          "type": "string",
          "fieldType": "radio",
          "label": "Order Type",
          "defaultValue": "resale",
          "options": [
            {
              "label": "Resale",
              "value": "resale"
            },
            {
              "label": "Consumption",
              "value": "consumption"
            }
          ]
        },
        {
          "name": "paymentMethod",
          "type": "string",
          "fieldType": "select",
          "label": "Payment Method",
          "defaultValue": "promissory_note",
          "options": [
            {
              "label": "Promissory Note",
              "value": "promissory_note"
            },
            {
              "label": "Credit Card",
              "value": "credit_card"
            }
          ]
        }
      ]
    },
    "children": [
      "order-config.title",
      "order-config.form"
    ]
  },
  "order-config.title": {
    "props": {
      "formTitle": "Order Configuration Default"
    }
  }
}

```


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

[User] Show me the implementation of order-configuration/store/interfaces.json from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "order-config": {
    "component": "OrderConfigurationSelector",
    "composition": "children",
    "allowed": [
      "order-config.modal",
      "order-config.form",
      "order-config.title",
      "flex-layout"
    ]
  },
  "order-config.modal": {
    "component": "OrderConfigurationModal",
    "composition": "children",
    "allowed": [
      "order-config.form",
      "order-config.title"
    ]
  },
  "order-config.form": {
    "component": "OrderConfigurationForm",
    "composition": "children"
  },
  "order-config.text": {
    "component": "FormInputText"
  },
  "order-config.dropdown": {
    "component": "FormInputDropdown"
  },
  "order-config.radiogroup": {
    "component": "FormInputRadiogroup"
  },
  "order-config.submit": {
    "component": "FormSubmit"
  },
  "order-config.title": {
    "component": "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 order-configuration/graphql/types/OrderConfiguration.graphql from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```graphql
type Field {
  Key: String!
  Value: String!
}

type OrderConfig {
  fields: [Field]
}

```


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

[User] Show me the implementation of order-configuration/node/clients/index.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { IOClients } from "@vtex/api";
import { Checkout } from "@vtex/clients";

import { CustomPrice } from "./customPrice";

// Extend the default IOClients implementation with our own custom clients.
export class Clients extends IOClients {
  public get customPrice() {
    return this.getOrSet("customPrice", CustomPrice);
  }

  public get checkout() {
    return this.getOrSet("checkout", Checkout);
  }
}

```


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

[User] Show me the implementation of order-configuration/node/clients/customPrice.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {
  ExternalClient,
  InstanceOptions,
  IOContext,
  RequestConfig
} from "@vtex/api";

import { statusToError } from "../utils";

export class CustomPrice extends ExternalClient {
  public constructor(ctx: IOContext, options?: InstanceOptions) {
    super(`https://${ctx.account}.myvtex.com/_v/custom-prices`, ctx, {
      ...options,
      headers: {
        ...(options && options.headers),
        ...{ Accept: "application/vnd.vtex.ds.v10+json" },
        ...(ctx.adminUserAuthToken
          ? { VtexIdclientAutCookie: ctx.adminUserAuthToken }
          : null),
        ...(ctx.storeUserAuthToken
          ? { VtexIdclientAutCookie: ctx.storeUserAuthToken }
          : null)
      }
    });
  }

  public getSchemas = <T>() =>
    this.get<T>(this.routes.schemas(), {
      metric: "customPrices-getSchemas"
    });

  protected get = <T>(url: string, config?: RequestConfig) => {
    return this.http.get<T>(url, config).catch(statusToError);
  };

  private get routes() {
    return {
      schema: (acronym: string, schema: string) =>
        `${acronym}/schemas/${schema}`,
      schemas: () => "session/schema"
    };
  }
}

```


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

[User] Show me the implementation of order-configuration/node/typings/Checkout.d.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface CheckoutAddress {
  addressType: string
  receiverName: string | null
  addressId: string
  postalCode: string
  city: string
  state: string
  country: string
  street: string
  number: string
  neighborhood: string
  complement: string
  reference: string | null
  geoCoordinates: [number, number]
}

```


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

[User] Show me the implementation of order-configuration/node/typings/global.d.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface GithubAuthHeader {
  Authorization: string,
  'X-Vtex-Use-Https': string
}

interface DocsBotConfigs {
  pem: string,
  reposWithoutReadMe: string[]
}

```


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

[User] Show me the implementation of order-configuration/node/utils/fromFieldArrayFormat.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const fromFieldArrayFormat = (fieldArray: { Key: string; Value: string }[]): Record<string, string> => {
  const recordToReturn: Record<string, string> = {};
  for(let item of fieldArray) {
    recordToReturn[item.Key] = item.Value;
  }
  return recordToReturn;
}
```


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

[User] Show me the implementation of order-configuration/node/utils/toFieldArrayFormat.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const toFieldArrayFormat = (
  dictionary: Record<string, string>
): { Key: string; Value: string }[] => {
  const toReturn: { Key: string; Value: string }[] = [];
  for (let key of Object.keys(dictionary)) {
    toReturn.push({
      Key: key,
      Value: dictionary[key],
    })
  }
  return toReturn;
};

```


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

[User] Show me the implementation of order-configuration/node/utils/vtexId.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
const vtexIdAccount = (account: string) => `VtexIdclientAutCookie_${account}`;
const VTEX_ID = "VtexIdclientAutCookie";

export const vtexIdCookies = (ctx: Context) => {
  const {
    cookies,
    vtex: { account }
  } = ctx;
  const vtexIdAccountCookieValue = cookies.get(vtexIdAccount(account));
  const vtexIdValue = cookies.get(VTEX_ID);

  return {
    account: vtexIdAccountCookieValue
      ? `${vtexIdAccount(account)}=${vtexIdAccountCookieValue}`
      : null,
    id: vtexIdValue ? `${VTEX_ID}=${vtexIdValue}` : null
  };
};

```


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

[User] Show me the implementation of order-configuration/node/utils/getOrderFormIdFromCookie.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
const CHECKOUT_COOKIE = "checkout.vtex.com";

export const getOrderFormIdFromCookie = (cookies: Context["cookies"]) => {
  const cookie = cookies.get(CHECKOUT_COOKIE);
  return cookie && cookie.split("=")[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 order-configuration/node/utils/index.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { AxiosError } from "axios";
import { AuthenticationError, ForbiddenError, UserInputError } from "@vtex/api";

export * from "./getOrderFormIdFromCookie";

export function statusToError(e: any) {
  if (!e.response) {
    throw e;
  }

  const { response } = e as AxiosError;
  const { status } = response!;

  if (status === 401) {
    throw new AuthenticationError(e);
  }
  if (status === 403) {
    throw new ForbiddenError(e);
  }
  if (status === 400) {
    throw new UserInputError(e);
  }

  throw e;
}

```


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

[User] Show me the implementation of order-configuration/node/repositories/Repository.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {DataEntity} from "../resolvers/orderConfiguration/enums/DataEntity";
import {MasterData} from "@vtex/api";
import {Schema} from "../models/Schema";
import {Schemas} from "../resolvers/orderConfiguration/enums/Schemas";

export class Repository<T> {

  public constructor(private readonly masterData: MasterData,
                     private readonly dataEntity: DataEntity,
                     private readonly schema: Schemas,
                     private readonly shouldEnforceSchema: boolean) {
  }

  public async delete(id: string): Promise<void> {
    await this.masterData.deleteDocument({
      dataEntity: this.dataEntity,
      id,
    });
  }

  public async get(id: string): Promise<T> {
    const document = await this.masterData.getDocument({
      dataEntity: this.dataEntity,
      id,
      fields: ["_all"]
    });
    if (document === "") {
      return {} as T;
    }
    const conformingToSchemaDocument = await this.onlyInSchema(document as Record<string, string | number>);
    return {...conformingToSchemaDocument, id: (document as Record<string, string | number>).id} as unknown as T;
  }

  public async save(fields: Record<string, string | number>): Promise<string> {
    const fieldsInSchema = await this.onlyInSchema(fields);
    const documentResponse = await this.masterData.createDocument({
      dataEntity: this.dataEntity,
      schema: this.schema,
      fields: fieldsInSchema,
    });
    return documentResponse.DocumentId;
  }

  public async update(id: string, fields: Record<string, string | number>): Promise<void> {
    const fieldsInSchema = await this.onlyInSchema(fields);
    return await this.masterData.updatePartialDocument({
      dataEntity: this.dataEntity,
      id,
      fields: fieldsInSchema,
      schema: this.schema,
    });
  }

  public async find(fields: Record<string, string | number>,
                    pagination: { page: number; pageSize: number} = { page: 1, pageSize: 20 }): Promise<T[]> {
    const whereClause = Repository.buildWhereClause(fields);
    const documents: Record<string, string | number>[] = await this.masterData.searchDocuments({
      dataEntity: this.dataEntity,
      schema: this.schema,
      fields: ["_all"],
      where: whereClause,
      pagination
    });
    if (documents.length === 0) {
      return [];
    }
    const conformingDocuments: T[] = [];
    for (let document of documents) {
      conformingDocuments.push({...await this.onlyInSchema(document), id: document.id } as unknown as T);
    }
    return conformingDocuments;
  }

  public async findOne(fields: Record<string, string | number>): Promise<T | null> {
    const documents = await this.find(fields);
    if (documents.length === 0) {
      return null;
    }
    return documents[0];
  }

  private async getSchema(): Promise<Schema> {
    return await this.masterData.getSchema({
      dataEntity: this.dataEntity,
      schema: this.schema,
    });
  }

  private async onlyInSchema(document: Record<string, string | number>): Promise<Record<string, string | number>> {
    if (!this.shouldEnforceSchema) {
      return document;
    }
    const schema = await this.getSchema();
    const conformingToSchema: Record<string, string | number> = {};
    for (let key of Object.keys(document)) {
      if (schema.properties[key]) {
        conformingToSchema[key] = document[key];
      }
    }
    return conformingToSchema;
  }

  private static buildWhereClause(fields: Record<string, string | number>): string {
    const separateClauses = []
    for(let field of Object.keys(fields)) {
      separateClauses.push(`${field}=${fields[field]}`)
    }
    return separateClauses.join(" AND ");
  }
}
```


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

[User] Show me the implementation of order-configuration/node/repositories/OrderConfigurationRepository.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {Repository} from "./Repository";
import {OrderConfig} from "../models/OrderConfig";
import {MasterData} from "@vtex/api";
import {Schemas} from "../resolvers/orderConfiguration/enums/Schemas";
import {DataEntity} from "../resolvers/orderConfiguration/enums/DataEntity";

export class OrderConfigurationRepository extends Repository<OrderConfig> {
  public constructor(masterData: MasterData) {
    super(masterData, DataEntity.ORDER_CONFIG, Schemas.ORDER_CONFIGURATION, true);
  }
}
```


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

[User] Show me the implementation of order-configuration/node/repositories/RepositoryFactory.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {Repository} from "./Repository";
import {MasterData} from "@vtex/api";
import {ClientRepository} from "./ClientRepository";
import {OrderConfig} from "../models/OrderConfig";
import {Client} from "../models/Client";
import {OrderConfigurationRepository} from "./OrderConfigurationRepository";

export class RepositoryFactory {
  public static getClientRepository(masterData: MasterData): Repository<Client> {
    return new ClientRepository(masterData);
  }

  public static getOrderConfigurationRepository(masterData: MasterData): Repository<OrderConfig> {
    return new OrderConfigurationRepository(masterData);
  }
}

```


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

[User] Show me the implementation of order-configuration/node/repositories/ClientRepository.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {Repository} from "./Repository";
import {MasterData} from "@vtex/api";
import {DataEntity} from "../resolvers/orderConfiguration/enums/DataEntity";
import {Schemas} from "../resolvers/orderConfiguration/enums/Schemas";
import {Client} from "../models/Client";

export class ClientRepository extends Repository<Client> {
  public constructor(masterData: MasterData) {
    super(masterData, DataEntity.CLIENT, Schemas.CLIENT, false);
  }
}
```


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

[User] Show me the implementation of order-configuration/node/models/Schema.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
export interface Schema {
  'v-cache': boolean;
  properties: Record<string, { type: string}>;
  'v-default-fields': string[];
  'v-indexed': string[];
}

```


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

[User] Show me the implementation of order-configuration/node/models/OrderConfig.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript

export interface OrderConfig {
    id: string;
    [key: string]: string;
}

```


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

[User] Show me the implementation of order-configuration/node/resolvers/index.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { mutations as orderConfigurationMutations, queries as orderConfigurationQueries } from "./orderConfiguration";

export const resolvers = {
  Mutation: {
    ...orderConfigurationMutations
  },
  Query: {
    ...orderConfigurationQueries,
  }
};

```


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

[User] Show me the implementation of order-configuration/node/test/utils/fromFieldArrayFormat.unit.test.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {fromFieldArrayFormat} from "../../utils/fromFieldArrayFormat";
import { expect } from "chai";

describe("fromFieldArrayFormat", () => {
  it('should convert from field array format correctly', () => {
    const fieldFormatArray = [
      {
        Key: "a",
        Value: "123",
      },
      {
        Key: "b",
        Value: "asd",
      }
    ];
    const converted = fromFieldArrayFormat(fieldFormatArray);
    expect(converted).to.be.deep.equal({
      a: "123",
      b: "asd"
    });
  });
});
```


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

[User] Show me the implementation of order-configuration/node/test/utils/TokenUtils.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import axios from "axios";

export interface TokenResponse {
  authStatus: string;
  token: string;
  expires: number;
}

export class TokenUtils {
  public static async getAuthToken(store: string, appKey: string, appToken: string): Promise<string> {
    const tokenUrl = `https://${store}.vtexcommercestable.com.br/api/vtexid/apptoken/login`;
    const data = {
      appkey: appKey,
      apptoken: appToken,
    };
    const response = await axios.post<TokenResponse>(tokenUrl, data);
    return response.data.token;
  }
}

```


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

[User] Show me the implementation of order-configuration/node/test/utils/toFieldArrayFormat.unit.test.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {expect} from "chai";
import {toFieldArrayFormat} from "../../utils/toFieldArrayFormat";

describe("toFieldArrayFormat", () => {
  it('should convert to field array format correctly', () => {
    const object = {
      a: "123",
      b: "asd"
    };
    const converted = toFieldArrayFormat(object);
    expect(converted).to.be.deep.equal([
      {
        Key: "a",
        Value: "123",
      },
      {
        Key: "b",
        Value: "asd",
      }
    ]);
  });
});
```


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

[User] Show me the implementation of order-configuration/node/test/repositories/Repository.integration.test.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {Repository} from "../../repositories/Repository";
import {DataEntity} from "../../resolvers/orderConfiguration/enums/DataEntity";
import {Schemas} from "../../resolvers/orderConfiguration/enums/Schemas";
import {expect} from "chai";
import {MasterDataFactory} from "../factories/MasterDataFactory";
import {TokenUtils} from "../utils/TokenUtils";

describe("Repository", function () {
  let repository: Repository<any>;
  before( async () => {
    const store = process.env.STORE as string;
    const workspace = process.env.WORKSPACE as string;
    const appKey = process.env.APP_KEY as string;
    const appToken = process.env.APP_TOKEN as string;
    const authToken = await TokenUtils.getAuthToken(store, appKey, appToken);
    const masterData = MasterDataFactory.buildMockMasterData(store, authToken, workspace)
    repository = new Repository(masterData, "integration_test" as DataEntity, "repository_test_schema" as Schemas, true);
  });

  describe("get & save", () => {
    it("should fetch a record properly", async () => {
      const id = await repository.save({
        a: "123",
        b: "asd"
      });
      const document = await repository.get(id);
      expect(document).to.deep.equal({
        a: "123",
        b: "asd",
        id,
      });
      await repository.delete(id);
    });
  });

  describe("delete", () => {
    it('should return an empty record after deletion', async () => {
      const id = await repository.save({
        a: "123",
        b: "asd"
      });
      await repository.delete(id);
      const document = await repository.get(id);
      expect(document).to.deep.equal({});
    });
  });

  describe("update", () => {
    it('should update the record properly', async () => {
      const id = await repository.save({
        a: "123",
        b: "asd"
      });
      await repository.update(id, {
        a: "456"
      })
      const document = await repository.get(id);
      expect(document).to.deep.equal({
        a: "456",
        b: "asd",
        id,
      });
      await repository.delete(id);
    });
  });

  describe("find", () => {
    it('should find the document properly', async () => {
      const document = await repository.find({
        a: "iHopeThisStringIsNotCopied",
      });
      expect(document).to.deep.equal([{
        a: "iHopeThisStringIsNotCopied",
        b: "asd",
        id: "222db4a1-3a2d-11eb-82ac-0a58a8d158d9",
      }]);
    });
  });

  describe("findOne", () => {
    it('should find the document properly', async () => {
      const document = await repository.findOne({
        a: "iHopeThisStringIsNotCopied",
      });
      expect(document).to.deep.equal({
        a: "iHopeThisStringIsNotCopied",
        b: "asd",
        id: "222db4a1-3a2d-11eb-82ac-0a58a8d158d9",
      });
    });
  });
});
```


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

[User] Show me the implementation of order-configuration/node/test/factories/MasterDataFactory.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {anything, instance, mock, when} from "ts-mockito";
import {UserLandTracer} from "@vtex/api/lib/tracing/UserLandTracer";
import {IOContext, Logger, MasterData, Span} from "@vtex/api";
import {SpanContext} from "opentracing";
import {ParsedUrlQuery} from "querystring";

export class MasterDataFactory{
  public static buildMockMasterData(store: string, authToken: string, workspace: string): MasterData {
    const tracerMock = mock(UserLandTracer);
    const spanMock = mock(Span);
    when(spanMock.context()).thenReturn(instance(mock(SpanContext)));
    when(tracerMock.startSpan(anything(), anything())).thenReturn(instance(spanMock));
    when(tracerMock.startSpan(anything())).thenReturn(instance(spanMock));
    const masterData = new MasterData(new class implements IOContext {
      account = store;
      authToken = authToken;
      logger = null as unknown as Logger;
      operationId = "";
      platform = "";
      product = "";
      production = false;
      region = "";
      requestId = "";
      route = {
        id: "",
        params: {
          fakeString: "bogus",
        } as ParsedUrlQuery,
        type: "private",
        declarer: undefined,
      } as {
        declarer?: string;
        id: string;
        params: ParsedUrlQuery;
        type: 'public' | 'private' | 'event';
      };
      tracer = instance(tracerMock);
      userAgent = "test";
      workspace = workspace;
    } as unknown as IOContext);
    return masterData;
  }
}
```


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

[User] Show me the implementation of order-configuration/node/test/resolvers/orderConfiguration/orderConfiguration.unit.test.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {orderConfiguration} from "../../../resolvers/orderConfiguration/orderConfiguration";
import {MasterData, Session} from "@vtex/api";
import {anything, instance, mock, when} from "ts-mockito";
import * as Cookies from 'cookies';
import {expect} from "chai";
import {Clients} from "../../../clients";
import * as globals from "../../../globals";

describe("orderConfiguration", () => {
  let masterdata: MasterData;
  let session: Session;
  let cookies: Cookies;
  beforeEach( () => {
    masterdata = mock<MasterData>();
    session = mock<Session>();
    cookies = mock<Cookies>();
  })

  it('should return null when the user email is not present', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {},
      sessionToken: ""
    });
    const result = await orderConfiguration(null, null as unknown as void, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout: null } as unknown as Clients,
      cookies: instance(cookies)
    } as globals.Context);
    expect(result).to.be.null;
  });

  it('should return null when no client was found', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {
        namespaces: {
          profile: {
            email: {
              value: "fakeEmail"
            }
          }
        }
      },
      sessionToken: ""
    });
    when(masterdata.searchDocuments(anything())).thenResolve([]);
    const result = await orderConfiguration(null, null as unknown as void, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout: null } as unknown as Clients,
      cookies: instance(cookies)
    } as globals.Context);
    expect(result).to.be.null;
  });

  it('should return null when no order configuration was found', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {
        namespaces: {
          profile: {
            email: {
              value: "fakeEmail"
            }
          }
        }
      },
      sessionToken: ""
    });
    when(masterdata.searchDocuments(anything())).thenResolve([{
      a: "asd",
      b: "123"
    }]).thenResolve([]);
    const result = await orderConfiguration(null, null as unknown as void, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout: null } as unknown as Clients,
      cookies: instance(cookies)
    } as globals.Context);
    expect(result).to.be.null;
  });

  it('should return the order configuration correctly', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {
        namespaces: {
          profile: {
            email: {
              value: "fakeEmail"
            }
          }
        }
      },
      sessionToken: ""
    });
    when(masterdata.getSchema(anything())).thenResolve({
      'v-cache': false,
      properties: {
        order: {
          type: "string"
        },
        whatever: {
          type: "string"
        }
      },
      'v-default-fields': [],
      'v-indexed': []
    });
    when(masterdata.searchDocuments(anything())).thenResolve([{
      a: "asd",
      b: "123"
    }]).thenResolve([{
      order: "123",
      whatever: "asd",
      id: "fakeId"
    }]);
    const result = await orderConfiguration(null, null as unknown as void, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout: null } as unknown as Clients,
      cookies: instance(cookies)
    } as globals.Context);
    expect(result).to.be.deep.equal({
      fields: [
        { Key: "order", Value: "123"},
        { Key: "whatever", Value: "asd"},
        { Key: "id", Value: "fakeId"}
      ]
    });
  });
});

```


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

[User] Show me the implementation of order-configuration/node/test/resolvers/orderConfiguration/saveOrderConfiguration.unit.test.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {MasterData, Session} from "@vtex/api";
import {anything, capture, instance, mock, verify, when} from "ts-mockito";
import * as Cookies from 'cookies';
import {expect} from "chai";
import {Clients} from "../../../clients";
import * as globals from "../../../globals";
import {saveOrderConfiguration} from "../../../resolvers/orderConfiguration/saveOrderConfiguration";
import {Checkout} from "@vtex/clients";
import {DataEntity} from "../../../resolvers/orderConfiguration/enums/DataEntity";
import {Schemas} from "../../../resolvers/orderConfiguration/enums/Schemas";

describe("saveOrderConfiguration", () => {
  let masterdata: MasterData;
  let session: Session;
  let cookies: Cookies;
  let checkout: Checkout;
  let orderConfig: { fields: { Key: string; Value: string; }[]};
  beforeEach( () => {
    masterdata = mock<MasterData>();
    session = mock<Session>();
    cookies = mock<Cookies>();
    checkout = mock<Checkout>();
    orderConfig = {
      fields: [
        { Key: "a", Value: "asd"},
        { Key: "b", Value: "123"}
      ]
    };
  })

  it('should return null when the user email is not present', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {},
      sessionToken: ""
    });
    const result = await saveOrderConfiguration(null, {
      orderConfig
    }, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout } as unknown as Clients,
      cookies: instance(cookies),
    } as globals.Context);
    expect(result).to.be.false;
  });

  it('should return null when no client was found', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {
        namespaces: {
          profile: {
            email: {
              value: "fakeEmail"
            }
          }
        }
      },
      sessionToken: ""
    });
    when(masterdata.searchDocuments(anything())).thenResolve([]);
    const result = await saveOrderConfiguration(null, {
      orderConfig
    }, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout } as unknown as Clients,
      cookies: instance(cookies)
    } as globals.Context);
    expect(result).to.be.false;
  });

  it('should save a new order configuration when no order configuration was found', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {
        namespaces: {
          profile: {
            email: {
              value: "fakeEmail"
            }
          }
        }
      },
      sessionToken: ""
    });
    when(masterdata.getSchema(anything())).thenResolve({
      'v-cache': false,
      properties: {
        a: {
          type: "string"
        },
        b: {
          type: "string"
        }
      },
      'v-default-fields': [],
      'v-indexed': []
    });
    when(masterdata.searchDocuments(anything())).thenResolve([{
      id: "fakeId",
    }]).thenResolve([]);
    when(masterdata.createDocument(anything())).thenResolve({
      DocumentId: "asdasd",
      Id: "asasdasd",
      Href: "as"
    });
    const result = await saveOrderConfiguration(null, {
      orderConfig
    }, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout } as unknown as Clients,
      cookies: instance(cookies)
    } as globals.Context);
    expect(result).to.be.true;
    verify(masterdata.createDocument(anything())).once();
    const [arg] = capture(masterdata.createDocument).last();
    expect(arg).to.be.deep.equal({
      dataEntity: DataEntity.ORDER_CONFIG,
      schema: Schemas.ORDER_CONFIGURATION,
      fields: { a: "asd", b: "123" },
    });
  });

  it('should return the order configuration correctly', async () => {
    when(session.getSession(anything(), anything())).thenResolve({
      sessionData: {
        namespaces: {
          profile: {
            email: {
              value: "fakeEmail"
            }
          }
        }
      },
      sessionToken: ""
    });
    when(masterdata.getSchema(anything())).thenResolve({
      'v-cache': false,
      properties: {
        a: {
          type: "string"
        },
        b: {
          type: "string"
        }
      },
      'v-default-fields': [],
      'v-indexed': []
    });
    when(masterdata.searchDocuments(anything())).thenResolve([{
      id: "fakeId",
    }]).thenResolve([{
      a: "uuu",
      b: "aaa",
      id: "fakeId"
    }]);
    when(masterdata.createDocument(anything())).thenResolve({
      DocumentId: "asdasd",
      Id: "asasdasd",
      Href: "as"
    });
    const result = await saveOrderConfiguration(null, {
      orderConfig
    }, {
      clients: { masterdata: instance(masterdata), session: instance(session), customPrice: null, checkout } as unknown as Clients,
      cookies: instance(cookies)
    } as globals.Context);
    expect(result).to.be.true;
    verify(masterdata.updatePartialDocument(anything())).once();
    const [arg] = capture(masterdata.updatePartialDocument).last();
    expect(arg).to.be.deep.equal({
      dataEntity: DataEntity.ORDER_CONFIG,
      schema: Schemas.ORDER_CONFIGURATION,
      fields: { a: "asd", b: "123" },
      id: "fakeId"
    });
  });
});

```


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

[User] Show me the implementation of order-configuration/node/resolvers/orderConfiguration/orderConfiguration.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {toFieldArrayFormat} from "../../utils/toFieldArrayFormat";
import {RepositoryFactory} from "../../repositories/RepositoryFactory";

export const VTEX_SESSION = "vtex_session";

export const orderConfiguration = async (_: any, __: void, ctx: Context) => {
  const {
    clients: { masterdata, session },
    cookies
  } = ctx;

  const sessionCookie = cookies.get(VTEX_SESSION);
  const { sessionData } = await session.getSession(sessionCookie!, [
    "profile.email"
  ]);
  const clientRepository = RepositoryFactory.getClientRepository(masterdata);
  const orderConfigRepository = RepositoryFactory.getOrderConfigurationRepository(masterdata);

  const userEmail = sessionData.namespaces?.profile?.email?.value;

  if(!userEmail) {
    return null;
  }

  const client = await clientRepository.findOne({
    email: userEmail,
  });

  if(!client) {
    return null;
  }

  const clientId = client.id;

  const orderConfig = await orderConfigRepository.findOne({
    clientId,
  });

  if (!orderConfig) {
    return null;
  }

  return {
    fields: toFieldArrayFormat(orderConfig)
  };
};

```


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

[User] Show me the implementation of order-configuration/node/resolvers/orderConfiguration/saveOrderConfiguration.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {getOrderFormIdFromCookie} from "../../utils";
import {fromFieldArrayFormat} from "../../utils/fromFieldArrayFormat";
import {RepositoryFactory} from "../../repositories/RepositoryFactory";

interface Args {
  orderConfig: {
    fields: { Key: string; Value: string }[];
  };
}

const CUSTOM_SESSION_KEY = "customSessionKeys";
const VTEX_SESSION = "vtex_session";

export const saveOrderConfiguration = async (
  _: any,
  { orderConfig }: Args,
  ctx: Context
) => {
  const {
    clients: { masterdata, session, checkout },
    cookies
  } = ctx;

  const adaptedOrderConfig = fromFieldArrayFormat(orderConfig.fields);

  const sessionCookie = cookies.get(VTEX_SESSION);
  const { sessionData } = await session.getSession(sessionCookie!, [
    "profile.email"
  ]);
  const clientRepository = RepositoryFactory.getClientRepository(masterdata);
  const orderConfigRepository = RepositoryFactory.getOrderConfigurationRepository(masterdata);

  await session.updateSession(
    CUSTOM_SESSION_KEY,
    orderConfig,
    [],
    sessionCookie
  );

  await checkout.setSingleCustomData(getOrderFormIdFromCookie(cookies)!, {
    appId: "orderConfig",
    appFieldName: "values",
    value: JSON.stringify(adaptedOrderConfig)
  });

  const userEmail = sessionData.namespaces?.profile?.email?.value;

  if(!userEmail) {
    return false;
  }

  const client = await clientRepository.findOne({
    email: userEmail,
  });

  if(!client) {
    return false;
  }

  const orderConfigResult = await orderConfigRepository.findOne({
    clientId: client.id,
  });

  if (!orderConfigResult) {
    await orderConfigRepository.save({ clientId: client.id, ...adaptedOrderConfig});
  }
  else {
    await orderConfigRepository.update(orderConfigResult.id, { ...adaptedOrderConfig });
  }

  return true;
};

```


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

[User] Show me the implementation of order-configuration/node/resolvers/orderConfiguration/index.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { saveOrderConfiguration } from "./saveOrderConfiguration";
import {orderConfiguration} from "./orderConfiguration";

export const mutations = {
  saveOrderConfiguration
};

export const queries = {
  /**
   * Get user session custom keys
   * @return String
   */
  orderConfiguration
};
```


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

[User] Show me the implementation of order-configuration/node/resolvers/orderConfiguration/enums/DataEntity.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
export enum DataEntity {
    CLIENT = "CL",
    ORDER_CONFIG = "order_configuration",
}
```


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

[User] Show me the implementation of order-configuration/node/resolvers/orderConfiguration/enums/Schemas.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
export enum Schemas {
    CLIENT = "v1",
    ORDER_CONFIGURATION = "main"
}
```


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

[User] Show me the implementation of order-configuration/react/mutations/saveOrderConfig.graphql from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation saveOrderConfig($orderConfig: OrderConfigInput!){
  saveOrderConfiguration(orderConfig: $orderConfig)
}

```


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

[User] Show me the implementation of order-configuration/react/mutations/setOrderFormCustomData.graphql from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation setOrderFormCustomData ($appId: String, $field: String, $value: String) {
  setOrderFormCustomData(appId: $appId, field: $field, value: $value) {
    orderFormId
    customData {
      customApps {
        fields
        id
        major
      }
    }
  }
}

```


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

[User] Show me the implementation of order-configuration/react/typings/storefront.d.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

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

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

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

```


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

[User] Show me the implementation of order-configuration/react/typings/FormProps.d.ts from the order-configuration VTEX app.

[Assistant]
Here's the implementation:

```typescript
export type FormProps = {
  // schema: string
}

export type CustomPriceSelectorProps = {
  formTitle: string
  formFields: FormField[]
  onSuccessfulSubmit: () => void
  children: any
}

export type FormField =
  | InputField
  | SelectField
  | CheckboxField
  | RadioGroupField

export type InputField = {
  name: string
  type?: 'string' | 'number'
  fieldType?: 'text' | 'textarea' | 'select' | 'radio' | 'checkbox'
  label?: string
  defaultValue?: string
  required?: boolean
  format?: string
  showInTitle?: boolean
}

export type SelectField = FormField & {
  options: {
    label: string
    value: string
  }[]
}

export type RadioGroupField = SelectField

export type CheckboxField = RadioGroupField & {
  defaultValues?: string[]
}

```