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

[User] Show me the implementation of minicart/react/legacy/__fixtures__/orderFormAttachments.json from the minicart VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "data": {
    "orderForm": {
      "cacheId": "3335fe72057045398dd28bd2fa203b21",
      "orderFormId": "3335fe72057045398dd28bd2fa203b21",
      "value": 22.400000000000002,
      "totalizers": [
        {
          "id": "Items",
          "name": "Items Total",
          "value": 2240,
          "__typename": "vtex_storegraphql_2_51_0_Totalizer"
        },
        {
          "id": "Shipping",
          "name": "Shipping Total",
          "value": 0,
          "__typename": "vtex_storegraphql_2_51_0_Totalizer"
        }
      ],
      "items": [
        {
          "id": "17",
          "name": "Pepperoni Small",
          "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155439-55-55/pepperoni-feast.0e1c4c9e7b8900d08cc51ff285fd9ae3.1.jpg?v=636770441237070000",
          "detailUrl": "/pizza-pepperoni/p",
          "skuName": "Small",
          "quantity": 1,
          "sellingPrice": 14.9,
          "listPrice": 14.9,
          "parentItemIndex": null,
          "parentAssemblyBinding": null,
          "assemblyOptions": {
            "added": [
              {
                "item": {
                  "name": "Classic Crust",
                  "sellingPrice": 0,
                  "quantity": 1,
                  "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
                },
                "normalizedQuantity": 1,
                "choiceType": "SINGLE",
                "extraQuantity": 0,
                "__typename": "vtex_storegraphql_2_51_0_AddedOptionItem"
              },
              {
                "item": {
                  "name": "Pepperoni",
                  "sellingPrice": 0,
                  "quantity": 1,
                  "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
                },
                "normalizedQuantity": 1,
                "choiceType": "TOGGLE",
                "extraQuantity": 0,
                "__typename": "vtex_storegraphql_2_51_0_AddedOptionItem"
              },
              {
                "item": {
                  "name": "Ham",
                  "sellingPrice": 1.5,
                  "quantity": 3,
                  "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
                },
                "normalizedQuantity": 3,
                "choiceType": "MULTIPLE",
                "extraQuantity": 3,
                "__typename": "vtex_storegraphql_2_51_0_AddedOptionItem"
              },
              {
                "item": {
                  "name": "Pineapple",
                  "sellingPrice": 1,
                  "quantity": 3,
                  "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
                },
                "normalizedQuantity": 3,
                "choiceType": "MULTIPLE",
                "extraQuantity": 3,
                "__typename": "vtex_storegraphql_2_51_0_AddedOptionItem"
              }
            ],
            "removed": [
              {
                "removedQuantity": 1,
                "initialQuantity": 1,
                "name": "Onion",
                "__typename": "vtex_storegraphql_2_51_0_RemovedOptionItem"
              }
            ],
            "parentPrice": 14.9,
            "__typename": "vtex_storegraphql_2_51_0_AssemblyOptionItem"
          },
          "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
        },
        {
          "id": "14",
          "name": "Classic Crust",
          "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155413-55-55/classic.png?v=636759866429100000",
          "detailUrl": "/classic-crust/p",
          "skuName": "Classic Crust",
          "quantity": 1,
          "sellingPrice": 0,
          "listPrice": 0,
          "parentItemIndex": 0,
          "parentAssemblyBinding": "Pepperoni - Small_Crust",
          "assemblyOptions": {
            "added": [],
            "removed": [],
            "parentPrice": 0,
            "__typename": "vtex_storegraphql_2_51_0_AssemblyOptionItem"
          },
          "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
        },
        {
          "id": "9",
          "name": "Pepperoni",
          "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155428-55-55/Topping_Pepperoni.jpg.png?v=636766047561270000",
          "detailUrl": "/pepperoni/p",
          "skuName": "Pepperoni",
          "quantity": 1,
          "sellingPrice": 0,
          "listPrice": 0,
          "parentItemIndex": 0,
          "parentAssemblyBinding": "Pepperoni - Small_Basic Toppings",
          "assemblyOptions": {
            "added": [],
            "removed": [],
            "parentPrice": 0,
            "__typename": "vtex_storegraphql_2_51_0_AssemblyOptionItem"
          },
          "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
        },
        {
          "id": "8",
          "name": "Ham",
          "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155432-55-55/Topping_Jamon.jpg.png?v=636766052579200000",
          "detailUrl": "/ham/p",
          "skuName": "Ham",
          "quantity": 3,
          "sellingPrice": 1.5,
          "listPrice": 1.5,
          "parentItemIndex": 0,
          "parentAssemblyBinding": "Pepperoni - Small_Toppings",
          "assemblyOptions": {
            "added": [],
            "removed": [],
            "parentPrice": 1.5,
            "__typename": "vtex_storegraphql_2_51_0_AssemblyOptionItem"
          },
          "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
        },
        {
          "id": "38",
          "name": "Pineapple",
          "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155435-55-55/Topping_Pina.jpg.png?v=636766056177370000",
          "detailUrl": "/pineapple/p",
          "skuName": "Pineapple",
          "quantity": 3,
          "sellingPrice": 1,
          "listPrice": 1,
          "parentItemIndex": 0,
          "parentAssemblyBinding": "Pepperoni - Small_Toppings",
          "assemblyOptions": {
            "added": [],
            "removed": [],
            "parentPrice": 1,
            "__typename": "vtex_storegraphql_2_51_0_AssemblyOptionItem"
          },
          "__typename": "vtex_storegraphql_2_51_0_OrderFormItem"
        }
      ],
      "shippingData": {
        "address": {
          "id": null,
          "neighborhood": "Botafogo",
          "complement": "",
          "number": "300",
          "street": "Praia de Botafogo",
          "postalCode": "22250-040",
          "city": "Rio de Janeiro",
          "reference": null,
          "addressName": null,
          "addressType": "residential",
          "__typename": "vtex_storegraphql_2_51_0_Address"
        },
        "availableAddresses": [
          {
            "id": null,
            "neighborhood": "Botafogo",
            "complement": "",
            "number": "300",
            "street": "Praia de Botafogo",
            "postalCode": "22250-040",
            "city": "Rio de Janeiro",
            "reference": null,
            "addressName": null,
            "addressType": "residential",
            "__typename": "vtex_storegraphql_2_51_0_Address"
          }
        ],
        "__typename": "vtex_storegraphql_2_51_0_OrderFormShippingData"
      },
      "clientProfileData": null,
      "storePreferencesData": {
        "countryCode": "BRA",
        "currencyCode": "BRL",
        "timeZone": "E. South America Standard Time",
        "__typename": "vtex_storegraphql_2_51_0_StorePreferencesData"
      },
      "itemMetadata": {
        "items": [
          {
            "id": "17",
            "name": "Pepperoni Small",
            "skuName": "Small",
            "productId": "13",
            "refId": "1111",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155439-55-55/pepperoni-feast.0e1c4c9e7b8900d08cc51ff285fd9ae3.1.jpg?v=636770441237070000",
            "detailUrl": "/pizza-pepperoni/p",
            "assemblyOptions": [
              {
                "id": "Pepperoni - Small_Crust",
                "name": "Pepperoni - Small",
                "required": true,
                "composition": {
                  "minQuantity": 1,
                  "maxQuantity": 1,
                  "items": [
                    {
                      "maxQuantity": 1,
                      "initialQuantity": 1,
                      "id": "14",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    }
                  ],
                  "__typename": "vtex_storegraphql_2_51_0_CompositionType"
                },
                "__typename": "vtex_storegraphql_2_51_0_AssemblyOption"
              },
              {
                "id": "Pepperoni - Small_Toppings",
                "name": "Pepperoni - Small",
                "required": true,
                "composition": {
                  "minQuantity": 0,
                  "maxQuantity": 10,
                  "items": [
                    {
                      "maxQuantity": 3,
                      "initialQuantity": 0,
                      "id": "8",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    },
                    {
                      "maxQuantity": 3,
                      "initialQuantity": 0,
                      "id": "9",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    },
                    {
                      "maxQuantity": 3,
                      "initialQuantity": 0,
                      "id": "10",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    },
                    {
                      "maxQuantity": 3,
                      "initialQuantity": 0,
                      "id": "11",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    },
                    {
                      "maxQuantity": 3,
                      "initialQuantity": 0,
                      "id": "36",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    },
                    {
                      "maxQuantity": 3,
                      "initialQuantity": 0,
                      "id": "37",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    },
                    {
                      "maxQuantity": 3,
                      "initialQuantity": 0,
                      "id": "38",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    }
                  ],
                  "__typename": "vtex_storegraphql_2_51_0_CompositionType"
                },
                "__typename": "vtex_storegraphql_2_51_0_AssemblyOption"
              },
              {
                "id": "Pepperoni - Small_Basic Toppings",
                "name": "Pepperoni - Small",
                "required": true,
                "composition": {
                  "minQuantity": 1,
                  "maxQuantity": 2,
                  "items": [
                    {
                      "maxQuantity": 1,
                      "initialQuantity": 1,
                      "id": "9",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    },
                    {
                      "maxQuantity": 1,
                      "initialQuantity": 1,
                      "id": "11",
                      "__typename": "vtex_storegraphql_2_51_0_CompositionItem"
                    }
                  ],
                  "__typename": "vtex_storegraphql_2_51_0_CompositionType"
                },
                "__typename": "vtex_storegraphql_2_51_0_AssemblyOption"
              }
            ],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "14",
            "name": "Classic Crust",
            "skuName": "Classic Crust",
            "productId": "12",
            "refId": "14",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155413-55-55/classic.png?v=636759866429100000",
            "detailUrl": "/classic-crust/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "8",
            "name": "Ham",
            "skuName": "Ham",
            "productId": "6",
            "refId": "2",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155432-55-55/Topping_Jamon.jpg.png?v=636766052579200000",
            "detailUrl": "/ham/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "9",
            "name": "Pepperoni",
            "skuName": "Pepperoni",
            "productId": "7",
            "refId": "3",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155428-55-55/Topping_Pepperoni.jpg.png?v=636766047561270000",
            "detailUrl": "/pepperoni/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "10",
            "name": "Champignon",
            "skuName": "Champignon",
            "productId": "8",
            "refId": "4",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155436-55-55/Topping_Champinones.png?v=636766057405600000",
            "detailUrl": "/champignon/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "11",
            "name": "Onion",
            "skuName": "Onion",
            "productId": "9",
            "refId": "5",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155427-55-55/Topping_Cebolla.jpg.png?v=636766046799500000",
            "detailUrl": "/onion/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "36",
            "name": "Black Olives",
            "skuName": "Black Olives",
            "productId": "23",
            "refId": "151113",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155430-55-55/Topping_Aceitunas-Negras.jpg.png?v=636766049376970000",
            "detailUrl": "/black-olives/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "37",
            "name": "Green Pepper",
            "skuName": "Green Pepper",
            "productId": "24",
            "refId": "123123",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155431-55-55/PIMIENTO-VERDE.png?v=636766050771230000",
            "detailUrl": "/green-pepper/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          },
          {
            "id": "38",
            "name": "Pineapple",
            "skuName": "Pineapple",
            "productId": "25",
            "refId": "121211",
            "ean": null,
            "imageUrl": "http://delivery.vteximg.com.br/arquivos/ids/155435-55-55/Topping_Pina.jpg.png?v=636766056177370000",
            "detailUrl": "/pineapple/p",
            "assemblyOptions": [],
            "__typename": "vtex_storegraphql_2_51_0_ItemMetadataUnit"
          }
        ],
        "__typename": "vtex_storegraphql_2_51_0_ItemMetadata"
      },
      "__typename": "vtex_storegraphql_2_51_0_OrderForm"
    }
  }
}

```


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

[User] Show me the implementation of minicart/react/legacy/__fixtures__/orderForm.js from the minicart VTEX app.

[Assistant]
Here's the implementation:

```javascript
export default {
  cacheId: '3335fe72057045398dd28bd2fa203b21',
  orderFormId: '3335fe72057045398dd28bd2fa203b21',
  value: 22.400000000000002,
  totalizers: [
    {
      id: 'Items',
      name: 'Items Total',
      value: 2240,
      __typename: 'vtex_storegraphql_2_51_0_Totalizer',
    },
    {
      id: 'Shipping',
      name: 'Shipping Total',
      value: 0,
      __typename: 'vtex_storegraphql_2_51_0_Totalizer',
    },
  ],
  items: [
    {
      id: '17',
      name: 'Pepperoni Small',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155439-55-55/pepperoni-feast.0e1c4c9e7b8900d08cc51ff285fd9ae3.1.jpg?v=636770441237070000',
      detailUrl: '/pizza-pepperoni/p',
      skuName: 'Small',
      quantity: 2,
      productRefId: 'PSMALL',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 14.9,
      listPrice: 14.9,
      parentItemIndex: null,
      parentAssemblyBinding: null,
      assemblyOptions: {
        added: [
          {
            item: {
              name: 'Classic Crust',
              sellingPrice: 0,
              quantity: 1,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 1,
            choiceType: 'SINGLE',
            extraQuantity: 0,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
          {
            item: {
              name: 'Pepperoni',
              sellingPrice: 0,
              quantity: 1,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 1,
            choiceType: 'TOGGLE',
            extraQuantity: 0,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
          {
            item: {
              name: 'Ham',
              sellingPrice: 1.5,
              quantity: 3,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 3,
            choiceType: 'MULTIPLE',
            extraQuantity: 3,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
          {
            item: {
              name: 'Pineapple',
              sellingPrice: 1,
              quantity: 3,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 3,
            choiceType: 'MULTIPLE',
            extraQuantity: 3,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
        ],
        removed: [
          {
            removedQuantity: 1,
            initialQuantity: 1,
            name: 'Onion',
            __typename: 'vtex_storegraphql_2_51_0_RemovedOptionItem',
          },
        ],
        parentPrice: 14.9,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '14',
      name: 'Classic Crust',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155413-55-55/classic.png?v=636759866429100000',
      detailUrl: '/classic-crust/p',
      skuName: 'Classic Crust',
      quantity: 1,
      productRefId: 'CLASSICCRUST',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 0,
      listPrice: 0,
      parentItemIndex: 0,
      parentAssemblyBinding: 'Pepperoni - Small_Crust',
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 0,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '9',
      name: 'Pepperoni',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155428-55-55/Topping_Pepperoni.jpg.png?v=636766047561270000',
      detailUrl: '/pepperoni/p',
      skuName: 'Pepperoni',
      quantity: 1,
      productRefId: 'PEPPERONI',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 0,
      listPrice: 0,
      parentItemIndex: 0,
      parentAssemblyBinding: 'Pepperoni - Small_Basic Toppings',
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 0,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '8',
      name: 'Ham',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155432-55-55/Topping_Jamon.jpg.png?v=636766052579200000',
      detailUrl: '/ham/p',
      skuName: 'Ham',
      quantity: 3,
      productRefId: 'HAM',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 1.5,
      listPrice: 1.5,
      parentItemIndex: 0,
      parentAssemblyBinding: 'Pepperoni - Small_Toppings',
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 1.5,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '38',
      name: 'Pineapple',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155435-55-55/Topping_Pina.jpg.png?v=636766056177370000',
      detailUrl: '/pineapple/p',
      skuName: 'Pineapple',
      quantity: 3,
      productRefId: 'PINEAPPLE',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 1,
      listPrice: 1,
      parentItemIndex: 0,
      parentAssemblyBinding: 'Pepperoni - Small_Toppings',
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 1,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
  ],
  shippingData: {
    address: {
      id: null,
      neighborhood: 'Botafogo',
      complement: '',
      number: '300',
      street: 'Praia de Botafogo',
      postalCode: '22250-040',
      city: 'Rio de Janeiro',
      reference: null,
      addressName: null,
      addressType: 'residential',
      __typename: 'vtex_storegraphql_2_51_0_Address',
    },
    availableAddresses: [
      {
        id: null,
        neighborhood: 'Botafogo',
        complement: '',
        number: '300',
        street: 'Praia de Botafogo',
        postalCode: '22250-040',
        city: 'Rio de Janeiro',
        reference: null,
        addressName: null,
        addressType: 'residential',
        __typename: 'vtex_storegraphql_2_51_0_Address',
      },
    ],
    __typename: 'vtex_storegraphql_2_51_0_OrderFormShippingData',
  },
  clientProfileData: null,
  storePreferencesData: {
    countryCode: 'BRA',
    currencyCode: 'BRL',
    timeZone: 'E. South America Standard Time',
    __typename: 'vtex_storegraphql_2_51_0_StorePreferencesData',
  },
  itemMetadata: {
    items: [
      {
        id: '17',
        name: 'Pepperoni Small',
        skuName: 'Small',
        productId: '13',
        refId: '1111',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155439-55-55/pepperoni-feast.0e1c4c9e7b8900d08cc51ff285fd9ae3.1.jpg?v=636770441237070000',
        detailUrl: '/pizza-pepperoni/p',
        assemblyOptions: [
          {
            id: 'Pepperoni - Small_Crust',
            name: 'Pepperoni - Small',
            required: true,
            composition: {
              minQuantity: 1,
              maxQuantity: 1,
              items: [
                {
                  maxQuantity: 1,
                  initialQuantity: 1,
                  id: '14',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
              ],
              __typename: 'vtex_storegraphql_2_51_0_CompositionType',
            },
            __typename: 'vtex_storegraphql_2_51_0_AssemblyOption',
          },
          {
            id: 'Pepperoni - Small_Toppings',
            name: 'Pepperoni - Small',
            required: true,
            composition: {
              minQuantity: 0,
              maxQuantity: 10,
              items: [
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '8',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '9',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '10',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '11',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '36',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '37',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '38',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
              ],
              __typename: 'vtex_storegraphql_2_51_0_CompositionType',
            },
            __typename: 'vtex_storegraphql_2_51_0_AssemblyOption',
          },
          {
            id: 'Pepperoni - Small_Basic Toppings',
            name: 'Pepperoni - Small',
            required: true,
            composition: {
              minQuantity: 1,
              maxQuantity: 2,
              items: [
                {
                  maxQuantity: 1,
                  initialQuantity: 1,
                  id: '9',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 1,
                  initialQuantity: 1,
                  id: '11',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
              ],
              __typename: 'vtex_storegraphql_2_51_0_CompositionType',
            },
            __typename: 'vtex_storegraphql_2_51_0_AssemblyOption',
          },
        ],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '14',
        name: 'Classic Crust',
        skuName: 'Classic Crust',
        productId: '12',
        refId: '14',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155413-55-55/classic.png?v=636759866429100000',
        detailUrl: '/classic-crust/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '8',
        name: 'Ham',
        skuName: 'Ham',
        productId: '6',
        refId: '2',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155432-55-55/Topping_Jamon.jpg.png?v=636766052579200000',
        detailUrl: '/ham/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '9',
        name: 'Pepperoni',
        skuName: 'Pepperoni',
        productId: '7',
        refId: '3',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155428-55-55/Topping_Pepperoni.jpg.png?v=636766047561270000',
        detailUrl: '/pepperoni/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '10',
        name: 'Champignon',
        skuName: 'Champignon',
        productId: '8',
        refId: '4',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155436-55-55/Topping_Champinones.png?v=636766057405600000',
        detailUrl: '/champignon/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '11',
        name: 'Onion',
        skuName: 'Onion',
        productId: '9',
        refId: '5',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155427-55-55/Topping_Cebolla.jpg.png?v=636766046799500000',
        detailUrl: '/onion/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '36',
        name: 'Black Olives',
        skuName: 'Black Olives',
        productId: '23',
        refId: '151113',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155430-55-55/Topping_Aceitunas-Negras.jpg.png?v=636766049376970000',
        detailUrl: '/black-olives/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '37',
        name: 'Green Pepper',
        skuName: 'Green Pepper',
        productId: '24',
        refId: '123123',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155431-55-55/PIMIENTO-VERDE.png?v=636766050771230000',
        detailUrl: '/green-pepper/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '38',
        name: 'Pineapple',
        skuName: 'Pineapple',
        productId: '25',
        refId: '121211',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155435-55-55/Topping_Pina.jpg.png?v=636766056177370000',
        detailUrl: '/pineapple/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
    ],
    __typename: 'vtex_storegraphql_2_51_0_ItemMetadata',
  },
  __typename: 'vtex_storegraphql_2_51_0_OrderForm',
}

export const fullItems = {
  cacheId: '3335fe72057045398dd28bd2fa203b21',
  orderFormId: '3335fe72057045398dd28bd2fa203b21',
  value: 22.400000000000002,
  totalizers: [
    {
      id: 'Items',
      name: 'Items Total',
      value: 2240,
      __typename: 'vtex_storegraphql_2_51_0_Totalizer',
    },
    {
      id: 'Shipping',
      name: 'Shipping Total',
      value: 0,
      __typename: 'vtex_storegraphql_2_51_0_Totalizer',
    },
  ],
  items: [
    {
      id: '17',
      name: 'Pepperoni Small',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155439-55-55/pepperoni-feast.0e1c4c9e7b8900d08cc51ff285fd9ae3.1.jpg?v=636770441237070000',
      detailUrl: '/pizza-pepperoni/p',
      skuName: 'Small',
      quantity: 1,
      productRefId: 'PSMALL',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 14.9,
      listPrice: 14.9,
      parentItemIndex: null,
      parentAssemblyBinding: null,
      assemblyOptions: {
        added: [
          {
            item: {
              name: 'Classic Crust',
              sellingPrice: 0,
              quantity: 1,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 1,
            choiceType: 'SINGLE',
            extraQuantity: 0,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
          {
            item: {
              name: 'Pepperoni',
              sellingPrice: 0,
              quantity: 1,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 1,
            choiceType: 'TOGGLE',
            extraQuantity: 0,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
          {
            item: {
              name: 'Ham',
              sellingPrice: 1.5,
              quantity: 3,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 3,
            choiceType: 'MULTIPLE',
            extraQuantity: 3,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
          {
            item: {
              name: 'Pineapple',
              sellingPrice: 1,
              quantity: 3,
              __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
            },
            normalizedQuantity: 3,
            choiceType: 'MULTIPLE',
            extraQuantity: 3,
            __typename: 'vtex_storegraphql_2_51_0_AddedOptionItem',
          },
        ],
        removed: [
          {
            removedQuantity: 1,
            initialQuantity: 1,
            name: 'Onion',
            __typename: 'vtex_storegraphql_2_51_0_RemovedOptionItem',
          },
        ],
        parentPrice: 14.9,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '14',
      name: 'Classic Crust',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155413-55-55/classic.png?v=636759866429100000',
      detailUrl: '/classic-crust/p',
      skuName: 'Classic Crust',
      quantity: 1,
      productRefId: 'CLASSICCRUST',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 0,
      listPrice: 0,
      parentItemIndex: null,
      parentAssemblyBinding: null,
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 0,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '9',
      name: 'Pepperoni',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155428-55-55/Topping_Pepperoni.jpg.png?v=636766047561270000',
      detailUrl: '/pepperoni/p',
      skuName: 'Pepperoni',
      quantity: 1,
      productRefId: 'PEPPERONI',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 0,
      listPrice: 0,
      parentItemIndex: null,
      parentAssemblyBinding: null,
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 0,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '8',
      name: 'Ham',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155432-55-55/Topping_Jamon.jpg.png?v=636766052579200000',
      detailUrl: '/ham/p',
      skuName: 'Ham',
      quantity: 3,
      productRefId: 'HAM',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 1.5,
      listPrice: 1.5,
      parentItemIndex: null,
      parentAssemblyBinding: null,
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 1.5,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
    {
      id: '38',
      name: 'Pineapple',
      imageUrl:
        'http://delivery.vteximg.com.br/arquivos/ids/155435-55-55/Topping_Pina.jpg.png?v=636766056177370000',
      detailUrl: '/pineapple/p',
      skuName: 'Pineapple',
      quantity: 3,
      productRefId: 'PINEAPPLE',
      additionalInfo: {
        brandName: 'PizzaHut',
      },
      productCategoryIds: '/1/',
      productCategories: { 1: 'Pizza' },
      sellingPrice: 1,
      listPrice: 1,
      parentItemIndex: null,
      parentAssemblyBinding: null,
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 1,
        __typename: 'vtex_storegraphql_2_51_0_AssemblyOptionItem',
      },
      __typename: 'vtex_storegraphql_2_51_0_OrderFormItem',
    },
  ],
  shippingData: {
    address: {
      id: null,
      neighborhood: 'Botafogo',
      complement: '',
      number: '300',
      street: 'Praia de Botafogo',
      postalCode: '22250-040',
      city: 'Rio de Janeiro',
      reference: null,
      addressName: null,
      addressType: 'residential',
      __typename: 'vtex_storegraphql_2_51_0_Address',
    },
    availableAddresses: [
      {
        id: null,
        neighborhood: 'Botafogo',
        complement: '',
        number: '300',
        street: 'Praia de Botafogo',
        postalCode: '22250-040',
        city: 'Rio de Janeiro',
        reference: null,
        addressName: null,
        addressType: 'residential',
        __typename: 'vtex_storegraphql_2_51_0_Address',
      },
    ],
    __typename: 'vtex_storegraphql_2_51_0_OrderFormShippingData',
  },
  clientProfileData: null,
  storePreferencesData: {
    countryCode: 'BRA',
    currencyCode: 'BRL',
    timeZone: 'E. South America Standard Time',
    __typename: 'vtex_storegraphql_2_51_0_StorePreferencesData',
  },
  itemMetadata: {
    items: [
      {
        id: '17',
        name: 'Pepperoni Small',
        skuName: 'Small',
        productId: '13',
        refId: '1111',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155439-55-55/pepperoni-feast.0e1c4c9e7b8900d08cc51ff285fd9ae3.1.jpg?v=636770441237070000',
        detailUrl: '/pizza-pepperoni/p',
        assemblyOptions: [
          {
            id: 'Pepperoni - Small_Crust',
            name: 'Pepperoni - Small',
            required: true,
            composition: {
              minQuantity: 1,
              maxQuantity: 1,
              items: [
                {
                  maxQuantity: 1,
                  initialQuantity: 1,
                  id: '14',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
              ],
              __typename: 'vtex_storegraphql_2_51_0_CompositionType',
            },
            __typename: 'vtex_storegraphql_2_51_0_AssemblyOption',
          },
          {
            id: 'Pepperoni - Small_Toppings',
            name: 'Pepperoni - Small',
            required: true,
            composition: {
              minQuantity: 0,
              maxQuantity: 10,
              items: [
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '8',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '9',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '10',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '11',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '36',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '37',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 3,
                  initialQuantity: 0,
                  id: '38',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
              ],
              __typename: 'vtex_storegraphql_2_51_0_CompositionType',
            },
            __typename: 'vtex_storegraphql_2_51_0_AssemblyOption',
          },
          {
            id: 'Pepperoni - Small_Basic Toppings',
            name: 'Pepperoni - Small',
            required: true,
            composition: {
              minQuantity: 1,
              maxQuantity: 2,
              items: [
                {
                  maxQuantity: 1,
                  initialQuantity: 1,
                  id: '9',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
                {
                  maxQuantity: 1,
                  initialQuantity: 1,
                  id: '11',
                  __typename: 'vtex_storegraphql_2_51_0_CompositionItem',
                },
              ],
              __typename: 'vtex_storegraphql_2_51_0_CompositionType',
            },
            __typename: 'vtex_storegraphql_2_51_0_AssemblyOption',
          },
        ],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '14',
        name: 'Classic Crust',
        skuName: 'Classic Crust',
        productId: '12',
        refId: '14',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155413-55-55/classic.png?v=636759866429100000',
        detailUrl: '/classic-crust/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '8',
        name: 'Ham',
        skuName: 'Ham',
        productId: '6',
        refId: '2',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155432-55-55/Topping_Jamon.jpg.png?v=636766052579200000',
        detailUrl: '/ham/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '9',
        name: 'Pepperoni',
        skuName: 'Pepperoni',
        productId: '7',
        refId: '3',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155428-55-55/Topping_Pepperoni.jpg.png?v=636766047561270000',
        detailUrl: '/pepperoni/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '10',
        name: 'Champignon',
        skuName: 'Champignon',
        productId: '8',
        refId: '4',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155436-55-55/Topping_Champinones.png?v=636766057405600000',
        detailUrl: '/champignon/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '11',
        name: 'Onion',
        skuName: 'Onion',
        productId: '9',
        refId: '5',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155427-55-55/Topping_Cebolla.jpg.png?v=636766046799500000',
        detailUrl: '/onion/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '36',
        name: 'Black Olives',
        skuName: 'Black Olives',
        productId: '23',
        refId: '151113',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155430-55-55/Topping_Aceitunas-Negras.jpg.png?v=636766049376970000',
        detailUrl: '/black-olives/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '37',
        name: 'Green Pepper',
        skuName: 'Green Pepper',
        productId: '24',
        refId: '123123',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155431-55-55/PIMIENTO-VERDE.png?v=636766050771230000',
        detailUrl: '/green-pepper/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
      {
        id: '38',
        name: 'Pineapple',
        skuName: 'Pineapple',
        productId: '25',
        refId: '121211',
        ean: null,
        imageUrl:
          'http://delivery.vteximg.com.br/arquivos/ids/155435-55-55/Topping_Pina.jpg.png?v=636766056177370000',
        detailUrl: '/pineapple/p',
        assemblyOptions: [],
        __typename: 'vtex_storegraphql_2_51_0_ItemMetadataUnit',
      },
    ],
    __typename: 'vtex_storegraphql_2_51_0_ItemMetadata',
  },
  __typename: 'vtex_storegraphql_2_51_0_OrderForm',
}

```


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

[User] Show me the implementation of minicart/react/legacy/utils/itemsHelper.js from the minicart VTEX app.

[Assistant]
Here's the implementation:

```javascript
const isParentItem = ({ parentItemIndex, parentAssemblyBinding }) =>
  parentItemIndex == null && parentAssemblyBinding == null

export const shouldShowItem = item => !!item.quantity && isParentItem(item)

```


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

[User] Show me the implementation of minicart/react/legacy/utils/propTypes.js from the minicart VTEX app.

[Assistant]
Here's the implementation:

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

export const MiniCartPropTypes = {
  /* Set the minicart type */
  type: PropTypes.oneOf(['popup', 'sidebar']),
  /* Set the content visibility */
  hideContent: PropTypes.bool,
  /* Label that will appear when the minicart is empty */
  labelMiniCartEmpty: PropTypes.string,
  /* Finish shopping button label */
  labelButtonFinishShopping: PropTypes.string,
  linkButtonFinishShopping: PropTypes.string,
  /* Icon's classnames */
  iconClasses: PropTypes.string,
  /* Icon's size */
  iconSize: PropTypes.number,
  /* Icon's label */
  iconLabel: PropTypes.object,
  /* Label's classnames */
  labelClasses: PropTypes.string,
  /* Set the discount visibility */
  showDiscount: PropTypes.bool,
  /* Set the shipping fee visibility */
  showShippingCost: PropTypes.bool,
}

```


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

[User] Show me the implementation of minicart/react/legacy/utils/urlHelpers.js from the minicart VTEX app.

[Assistant]
Here's the implementation:

```javascript
export const DEFAULT_WIDTH = 'auto'
export const DEFAULT_HEIGHT = 'auto'
export const MAX_WIDTH = 3000
export const MAX_HEIGHT = 4000

/**
 * Having the url below as base for the LEGACY file manager,
 * https://storecomponents.vteximg.com.br/arquivos/ids/155472/Frame-3.jpg?v=636793763985400000
 * the following regex will match https://storecomponents.vteximg.com.br/arquivos/ids/155472
 *
 * Also matches urls with defined sizes like:
 * https://storecomponents.vteximg.com.br/arquivos/ids/155473-160-auto
 * @type {RegExp}
 *
 * On the new vtex.file-manager isn't necessary replace the URL, just add the param on the querystring, like:
 * "?width=WIDTH&height=HEIGHT&aspect=true"
 *
 */
const baseUrlRegex = new RegExp(/.+ids\/(\d+)/)

const httpRegex = new RegExp(/http:\/\//)

export function toHttps(url) {
  if (!url) return ''
  return url.replace(httpRegex, 'https://')
}

export function cleanImageUrl(imageUrl) {
  const result = baseUrlRegex.exec(imageUrl)
  if (result.length > 0) return result[0]
}

function replaceLegacyFileManagerUrl(imageUrl, width, height) {
  const legacyUrlPattern = '/arquivos/ids/'
  const isLegacyUrl = imageUrl.includes(legacyUrlPattern)
  if (!isLegacyUrl) return imageUrl
  return `${cleanImageUrl(imageUrl)}-${width}-${height}`
}

export function changeImageUrlSize(
  imageUrl,
  width = DEFAULT_WIDTH,
  height = DEFAULT_HEIGHT
) {
  if (!imageUrl) return
  typeof width === 'number' && (width = Math.min(width, MAX_WIDTH))
  typeof height === 'number' && (height = Math.min(height, MAX_HEIGHT))

  const normalizedImageUrl = replaceLegacyFileManagerUrl(
    imageUrl,
    width,
    height
  )
  const queryStringSeparator = normalizedImageUrl.includes('?') ? '&' : '?'

  return `${normalizedImageUrl}${queryStringSeparator}width=${width}&height=${height}&aspect=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 minicart/react/legacy/localState/index.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
// eslint-disable-next-line no-restricted-imports
import { head, mergeDeepRight, values } from 'ramda'
import updateOrderFormShipping from 'vtex.store-resources/MutationUpdateOrderFormShipping'
import updateOrderFormCheckin from 'vtex.store-resources/MutationUpdateOrderFormCheckin'

import fullMinicartQuery from './graphql/fullMinicartQuery.gql'

export const ITEMS_STATUS = {
  NONE: 'NONE',
  MODIFIED: 'MODIFIED',
  LOCAL_ITEM: 'LOCAL_ITEM',
}

export default function (client) {
  const replayOrderFormServerMutation = mutation => async (
    _,
    variables,
    { cache }
  ) => {
    const response = await client.mutate({
      variables,
      mutation,
    })

    const updatedOrderForm = head(values(response.data))

    const data = cache.readQuery({ query: fullMinicartQuery })

    const orderForm = JSON.stringify(
      mergeDeepRight(JSON.parse(data.minicart.orderForm), updatedOrderForm)
    )
    cache.writeQuery({
      query: fullMinicartQuery,
      data: {
        ...data,
        minicart: {
          __typename: 'Minicart',
          ...data.minicart,
          orderForm,
        },
      },
    })
    return orderForm
  }

  const resolvers = {
    Mutation: {
      addToCart: (_, { items }, { cache }) => {
        const data = cache.readQuery({ query: fullMinicartQuery })

        const cartItems = JSON.parse(data.minicart.items)
        // We will only add items that are not already in cart or might have attachment.
        const newItems = items.filter(
          item =>
            !cartItems.find(
              cartItem =>
                cartItem.id === item.id &&
                cartItem.seller === item.seller &&
                !cartItem.canHaveAttachment
            )
        )

        const writeItems = cartItems.concat(
          newItems.map(item => ({
            ...item,
            localStatus: navigator.onLine
              ? ITEMS_STATUS.MODIFIED
              : ITEMS_STATUS.LOCAL_ITEM,
          }))
        )

        cache.writeQuery({
          query: fullMinicartQuery,
          data: {
            ...data,
            minicart: {
              __typename: 'Minicart',
              ...data.minicart,
              items: JSON.stringify(writeItems),
            },
          },
        })

        return writeItems
      },
      updateItems: (_, { items: newItems }, { cache }) => {
        const data = cache.readQuery({ query: fullMinicartQuery })

        const cartItems = JSON.parse(data.minicart.items)

        // Items provided to this function MUST have a valid index property
        const cleanNewItems = newItems.filter(({ index }) => index != null)
        const items = [...cartItems]

        for (const newItem of cleanNewItems) {
          const { index } = newItem
          const prevItem = cartItems[index]
          items[index] = mergeDeepRight(prevItem, {
            ...newItem,
            localStatus: ITEMS_STATUS.MODIFIED,
          })
        }

        const newCartItems = items.filter(Boolean)

        cache.writeQuery({
          query: fullMinicartQuery,
          data: {
            ...data,
            minicart: {
              __typename: 'Minicart',
              ...data.minicart,
              items: JSON.stringify(newCartItems),
            },
          },
        })
        return newCartItems
      },
      updateLocalItems: (_, { items }, { cache }) => {
        const data = cache.readQuery({ query: fullMinicartQuery })

        const itemsToRemove = items.filter(({ quantity }) => quantity === 0)
        const itemsToUpdate = items.filter(({ quantity }) => quantity > 0)

        const updatedItems = JSON.parse(data.minicart.items)
          .map((item, index) => {
            const updateItem = itemsToUpdate.find(
              currentItem => currentItem.index === index
            )

            if (updateItem) {
              return {
                ...item,
                ...updateItem,
              }
            }

            return item
          })
          .filter(
            (_item, index) =>
              itemsToRemove.findIndex(
                removedItem => removedItem.index === index
              ) === -1
          )

        cache.writeQuery({
          query: fullMinicartQuery,
          data: {
            ...data,
            minicart: {
              __typename: 'Minicart',
              ...data.minicart,
              items: JSON.stringify(updatedItems),
            },
          },
        })

        return updatedItems
      },
      updateOrderForm: (
        _,
        { orderForm, forceUpdateItems = false },
        { cache }
      ) => {
        const data = cache.readQuery({ query: fullMinicartQuery })

        const prevItems = JSON.parse(data.minicart.items)
        const orderFormItems = (orderForm.items || []).map(item => ({
          ...item,
          localStatus: ITEMS_STATUS.NONE,
        }))

        const currentItems = forceUpdateItems
          ? prevItems.map(item => ({
              ...item,
              localStatus:
                item.localStatus === ITEMS_STATUS.MODIFIED
                  ? ITEMS_STATUS.NONE
                  : item.localStatus,
            }))
          : prevItems

        const updatedItems = [
          ...orderFormItems,
          ...currentItems.filter(
            ({ localStatus }) => localStatus !== ITEMS_STATUS.NONE
          ),
        ]

        cache.writeQuery({
          query: fullMinicartQuery,
          data: {
            ...data,
            minicart: {
              __typename: 'Minicart',
              ...data.minicart,
              orderForm: JSON.stringify(orderForm),
              items: JSON.stringify(updatedItems),
            },
          },
        })

        return orderForm
      },
      updateLocalItemStatus: (_, __, { cache }) => {
        const data = cache.readQuery({ query: fullMinicartQuery })
        const prevItems = JSON.parse(data.minicart.items)

        const updatedItems = prevItems.map(item => ({
          ...item,
          localStatus:
            item.localStatus === ITEMS_STATUS.LOCAL_ITEM
              ? ITEMS_STATUS.MODIFIED
              : item.localStatus,
        }))

        cache.writeQuery({
          query: fullMinicartQuery,
          data: {
            ...data,
            minicart: {
              __typename: 'Minicart',
              ...data.minicart,
              items: JSON.stringify(updatedItems),
            },
          },
        })

        return true
      },
      updateOrderFormShipping: replayOrderFormServerMutation(
        updateOrderFormShipping
      ),
      updateOrderFormCheckin: replayOrderFormServerMutation(
        updateOrderFormCheckin
      ),
      setMinicartOpen: (_, { isOpen }, { cache }) => {
        const data = cache.readQuery({ query: fullMinicartQuery })
        cache.writeQuery({
          query: fullMinicartQuery,
          data: {
            ...data,
            minicart: {
              __typename: 'Minicart',
              ...data.minicart,
              isOpen,
            },
          },
        })
        return true
      },
    },
  }

  const initialState = {
    minicart: {
      __typename: 'Minicart',
      items: '[]',
      orderForm: null,
      isOpen: false,
    },
  }

  return { resolvers, initialState }
}

```


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

[User] Show me the implementation of minicart/react/legacy/components/Popup.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import React from 'react'
import PropTypes from 'prop-types'
import { Overlay } from 'vtex.react-portal'

import minicart from '../minicart.css'

const boxPositionStyle = {
  right: -40,
}

/**
 * Pop-up component.
 */
const Popup = ({ children, onOutsideClick }) => {
  return (
    <Overlay>
      <div
        className="fixed top-0 left-0 w-100 h-100"
        onClick={onOutsideClick}
      />
      <div
        className={`${minicart.box} dn db-ns absolute z-max flex flex-colunm`}
        style={boxPositionStyle}
      >
        <div className={`${minicart.popupContentContainer} shadow-3`}>
          <div
            className={`${minicart.arrowUp} absolute top-0 shadow-3 bg-base h1 w1 pa4 rotate-45`}
          />
          <div
            className={`${minicart.popupChildrenContainer} mt3 bg-base relative flex flex-column`}
          >
            {children}
          </div>
        </div>
      </div>
    </Overlay>
  )
}

Popup.propTypes = {
  /* The pop-up's content */
  children: PropTypes.object,
  /* Offset width to set the arrow position */
  buttonOffsetWidth: PropTypes.number,
  /* Function to be called when click occurs outside the popup */
  onOutsideClick: PropTypes.func,
}

export default Popup

```


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

[User] Show me the implementation of minicart/react/legacy/components/MiniCartFooter.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
import React, { Fragment, memo } from 'react'
import classNames from 'classnames'
import ProductPrice from 'vtex.store-components/ProductPrice'
import { Button, Spinner } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'
import PropTypes from 'prop-types'
import { useRuntime, ExtensionPoint } from 'vtex.render-runtime'

import { MiniCartPropTypes } from '../utils/propTypes'
import minicart from '../minicart.css'

const MiniCartFooter = ({
  shippingCost,
  isSizeLarge,
  isUpdating,
  totalValue,
  buttonLabel,
  buttonLink,
  showDiscount,
  discount,
  labelDiscount,
  showShippingCost,
}) => {
  const { rootPath = '' } = useRuntime()
  const handleClickButton = () => window.location.assign(rootPath + buttonLink)

  const priceAndDiscountClasses = classNames(
    `${minicart.contentDiscount} w-100 flex justify-end items-center mb3`,
    {
      pv3: isSizeLarge,
    }
  )

  const checkoutButtonClasses = classNames({
    'bb bw4 bw2-m b--transparent': isSizeLarge,
  })

  const shouldShowShippingCost = showShippingCost && shippingCost > 0

  const footerClasses = classNames(
    `${minicart.contentFooter} w-100 bg-base pa4 pv5 flex flex-column items-end`,
    {
      'bt b--muted-3': shouldShowShippingCost || isSizeLarge,
    }
  )

  return (
    <Fragment>
      {shouldShowShippingCost && (
        <div
          className={`${minicart.footerShippingPriceContainer} flex items-center justify-between ma5`}
        >
          <div
            className={`${minicart.footerShippingPriceLabelContainer} t-body c-muted-1`}
          >
            <FormattedMessage id="store/minicart.shipping-cost" />
          </div>
          <ProductPrice
            sellingPriceClass="t-heading-5-ns b c-on-base ph2 dib"
            sellingPrice={shippingCost}
            showLabels={false}
            showListPrice={false}
          />
        </div>
      )}
      <div
        className={minicart.footerSpacer}
        style={{
          marginTop: 'auto',
        }}
      />
      <ExtensionPoint id="sandbox" />
      <div className={footerClasses}>
        {!isUpdating && showDiscount && discount > 0 && (
          <div className={priceAndDiscountClasses}>
            <span
              className={`${minicart.labelDiscountText} ttl c-action-primary`}
            >
              {labelDiscount}
            </span>
            <ProductPrice
              sellingPriceClass="c-action-primary t-body ph2 dib"
              sellingPrice={discount}
              listPrice={discount}
              showLabels={false}
              showListPrice={false}
            />
          </div>
        )}
        <div className={`${minicart.contentPrice} mb3`}>
          {isUpdating ? (
            <Spinner size={18} />
          ) : (
            <ProductPrice
              sellingPriceClass="t-heading-5-ns c-on-base b ph2 dib"
              sellingPrice={totalValue}
              listPrice={totalValue}
              showLabels={false}
              showListPrice={false}
            />
          )}
        </div>
        <div className={checkoutButtonClasses}>
          <Button variation="primary" size="small" onClick={handleClickButton}>
            {buttonLabel}
          </Button>
        </div>
      </div>
    </Fragment>
  )
}

MiniCartFooter.propTypes = {
  shippingCost: PropTypes.number,
  isSizeLarge: PropTypes.bool,
  isUpdating: PropTypes.bool,
  totalValue: PropTypes.number.isRequired,
  buttonLink: PropTypes.string,
  buttonLabel: PropTypes.string.isRequired,
  showDiscount: MiniCartPropTypes.showDiscount,
  discount: PropTypes.number,
  labelDiscount: PropTypes.string,
  showShippingCost: MiniCartPropTypes.showShippingCost,
}

export default memo(MiniCartFooter)

```


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

[User] Show me the implementation of minicart/react/legacy/components/MiniCartContent.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
/* eslint-disable react/no-access-state-in-setstate */
import PropTypes from 'prop-types'
// eslint-disable-next-line no-restricted-imports
import { reduceBy, values, clone, find, propEq, compose } from 'ramda'
import React, { Component, Fragment } from 'react'
import { graphql } from 'react-apollo'
import { injectIntl } from 'react-intl'
import classNames from 'classnames'
import { withPixel } from 'vtex.pixel-manager/PixelContext'
import { ExtensionPoint } from 'vtex.render-runtime'
import { ButtonWithIcon, Spinner } from 'vtex.styleguide'
import { IconDelete } from 'vtex.store-icons'

import { MiniCartPropTypes } from '../utils/propTypes'
import { toHttps, changeImageUrlSize } from '../utils/urlHelpers'
import { mapCartItemToPixel } from '../../modules/pixelHelper'
import { ITEMS_STATUS } from '../localState/index'
import updateItemsMutation from '../localState/graphql/updateItemsMutation.gql'
import updateLocalItemsMutation from '../localState/graphql/updateLocalItemsMutation.gql'
import styles from '../minicart.css'
import MiniCartFooter from './MiniCartFooter'

/**
 * Minicart content component
 */

class MiniCartContent extends Component {
  static propTypes = {
    /* Set the mini cart content size */
    isSizeLarge: PropTypes.bool,
    /** Define a function that is executed when the item is clicked */
    onClickAction: PropTypes.func,
    /* Update Items mutation */
    updateItems: PropTypes.func.isRequired,
    updateLocalItems: PropTypes.func.isRequired,
    /* Determines if the orderform is updating */
    updatingOrderForm: PropTypes.bool,
    /* Reused props */
    orderForm: PropTypes.object,
    loading: PropTypes.bool,
    labelMiniCartEmpty: MiniCartPropTypes.labelMiniCartEmpty,
    linkButton: MiniCartPropTypes.linkButtonFinishShopping,
    labelButton: MiniCartPropTypes.labelButtonFinishShopping,
    showDiscount: MiniCartPropTypes.showDiscount,
    showShippingCost: MiniCartPropTypes.showShippingCost,
    itemsToShow: PropTypes.arrayOf(PropTypes.object),
    /* Pixel push */
    push: PropTypes.func.isRequired,
    /** Props to passed to icons from store-icons */
    iconsProps: PropTypes.shape({
      viewBox: PropTypes.string,
      size: PropTypes.number,
    }),
    intl: PropTypes.any,
  }

  state = { isUpdating: [] }

  sumItemsPrice = items =>
    items.reduce(
      (sum, { sellingPrice, quantity }) => sum + sellingPrice * quantity,
      0
    )

  getGroupedItems = () =>
    values(
      reduceBy(
        (acc, item) =>
          acc ? { ...acc, quantity: acc.quantity + item.quantity } : item,
        undefined,
        item => item.id,
        this.props.orderForm.items
      )
    )

  getShippingCost = orderForm => {
    const totalizer = find(propEq('id', 'Shipping'))(orderForm.totalizers || [])
    return (totalizer && totalizer.value / 100) || 0
  }

  calculateDiscount = items =>
    items.reduce(
      (sum, { listPrice, sellingPrice, quantity }) =>
        sum + (listPrice - sellingPrice) * quantity,
      0
    )

  handleItemRemoval = async (item, index) => {
    const { updateItems, updateLocalItems } = this.props
    const updatedItems = [
      {
        id: item.id,
        index: item.cartIndex != null ? item.cartIndex : index,
        quantity: 0,
      },
    ]

    try {
      if (item.cartIndex != null) {
        await updateItems(updatedItems)
      } else {
        await updateLocalItems(updatedItems)
      }

      this.props.push({
        event: 'removeFromCart',
        items: [mapCartItemToPixel(item)],
      })
    } catch (error) {
      // TODO: Toast error message
      console.error(error)
    }
  }

  updateItemLoad = (itemId, newStatus) => {
    const isUpdating = clone(this.state.isUpdating)
    isUpdating[itemId] = newStatus
    this.setState({ isUpdating })
  }

  calculateTotalValue = orderForm =>
    this.getShippingCost(orderForm)
      ? orderForm.value
      : this.sumItemsPrice(orderForm.items)

  getItemCategory = item => {
    if (!item.productCategoryIds || !item.productCategories) {
      return ''
    }

    return item.productCategoryIds
      .split('/')
      .reduce((acc, id) => acc.concat(item.productCategories[id]), [])
      .join('/')
      .slice(1, -1)
  }

  createProductShapeFromItem = item => {
    return {
      productName: item.name,
      brand: item.additionalInfo ? item.additionalInfo.brandName : undefined,
      category: this.getItemCategory(item),
      productRefId: item.productRefId,
      linkText: item.detailUrl.replace(/^\//, '').replace(/\/p$/, ''),
      sku: {
        seller: {
          commertialOffer: {
            Price: item.sellingPriceWithAssemblies * item.quantity,
            ListPrice: item.listPrice,
          },
          sellerId: item.seller,
        },
        name: item.skuName,
        itemId: item.id,
        image: {
          imageUrl: changeImageUrlSize(toHttps(item ? item.imageUrl : ''), 240),
        },
      },
      assemblyOptions: item.assemblyOptions,
      quantity: item.quantity,
      cartIndex: item.cartIndex,
    }
  }

  get isUpdating() {
    const { isUpdating } = this.state
    const {
      orderForm: { items },
      updatingOrderForm,
    } = this.props
    return (
      updatingOrderForm ||
      items.some(item => item.quantity === 0) ||
      isUpdating.some(status => status)
    )
  }

  renderWithoutItems = label => (
    <div
      className={`${styles.item} pa9 flex items-center justify-center relative bg-base`}
    >
      <span className="t-body">{label}</span>
    </div>
  )

  renderMiniCartWithItems = (
    orderForm,
    itemsToShow,
    label,
    labelDiscount,
    showDiscount,
    onClickAction,
    isUpdating,
    isSizeLarge,
    showShippingCost,
    iconsProps
  ) => {
    const MIN_ITEMS_TO_SCROLL = 2

    const classes = classNames(`${styles.content} overflow-x-hidden pa1`, {
      [`${styles.contentSmall} bg-base`]: !isSizeLarge,
      [`${styles.contentLarge}`]: isSizeLarge,
      'overflow-y-scroll':
        itemsToShow.length > MIN_ITEMS_TO_SCROLL && !isSizeLarge,
    })

    return (
      <Fragment>
        <div className={classes}>
          {itemsToShow.map((item, index) => (
            <Fragment key={item.id}>
              <section className={`${styles.itemContainer} relative flex`}>
                <div
                  className={`${styles.itemDeleteIcon} fr absolute top-0 right-0`}
                >
                  {isUpdating[item.id] ? (
                    <div className={`${styles.itemDeleteIconLoader} ma4`}>
                      <Spinner size={18} />
                    </div>
                  ) : (
                    <ButtonWithIcon
                      icon={
                        <IconDelete
                          size={15}
                          activeClassName="c-muted-2"
                          {...iconsProps}
                        />
                      }
                      variation="tertiary"
                      onClick={() => this.handleItemRemoval(item, index)}
                    />
                  )}
                </div>
                <ExtensionPoint
                  id="product-summary"
                  showBorders
                  product={this.createProductShapeFromItem(item)}
                  name={item.name}
                  displayMode="inlinePrice"
                  showListPrice={false}
                  showBadge={false}
                  showInstallments={false}
                  showLabels={false}
                  actionOnClick={onClickAction}
                  muted={item.localStatus !== ITEMS_STATUS.NONE}
                  index={index}
                />
              </section>
            </Fragment>
          ))}
        </div>
        <MiniCartFooter
          shippingCost={this.getShippingCost(orderForm)}
          isUpdating={this.isUpdating}
          totalValue={this.calculateTotalValue(orderForm)}
          discount={this.calculateDiscount(orderForm.items)}
          buttonLink={this.props.linkButton}
          buttonLabel={label}
          isSizeLarge={isSizeLarge}
          labelDiscount={labelDiscount}
          showDiscount={showDiscount}
          showShippingCost={showShippingCost}
        />
      </Fragment>
    )
  }

  renderLoading = () => (
    <div
      className={`${styles.item} pa4 flex items-center justify-center relative bg-base`}
    >
      <Spinner />
    </div>
  )

  render() {
    const {
      itemsToShow,
      labelMiniCartEmpty,
      labelButton,
      intl,
      showDiscount,
      onClickAction,
      isSizeLarge,
      showShippingCost,
      orderForm,
      loading,
      iconsProps,
    } = this.props
    const { isUpdating } = this.state

    if (loading) {
      return this.renderLoading()
    }

    if (!orderForm || !itemsToShow.length) {
      const label =
        labelMiniCartEmpty || intl.formatMessage({ id: 'store/minicart-empty' })
      return this.renderWithoutItems(label)
    }

    const label =
      labelButton ||
      intl.formatMessage({ id: 'store/finish-shopping-button-label' })
    const labelDiscount = intl.formatMessage({
      id: 'store/minicart-content-footer-discount',
    })

    return this.renderMiniCartWithItems(
      orderForm,
      itemsToShow,
      label,
      labelDiscount,
      showDiscount,
      onClickAction,
      isUpdating,
      isSizeLarge,
      showShippingCost,
      iconsProps
    )
  }
}

const withUpdateItemsMutation = graphql(updateItemsMutation, {
  name: 'updateItems',
  props: ({ updateItems }) => ({
    updateItems: items => updateItems({ variables: { items } }),
  }),
})

const withUpdateLocalItemsMutation = graphql(updateLocalItemsMutation, {
  name: 'updateLocalItems',
  props: ({ updateLocalItems }) => ({
    updateLocalItems: items => updateLocalItems({ variables: { items } }),
  }),
})

export default compose(
  injectIntl,
  withUpdateItemsMutation,
  withUpdateLocalItemsMutation,
  withPixel
)(MiniCartContent)

```


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

[User] Show me the implementation of minicart/react/legacy/components/Sidebar.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { IconCaret, IconCart } from 'vtex.store-icons'
import { injectIntl } from 'react-intl'
import OutsideClickHandler from 'react-outside-click-handler'
import Animation from 'vtex.store-components/Animation'
import classNames from 'classnames'
import { Overlay } from 'vtex.react-portal'

import minicart from '../minicart.css'

const OPEN_SIDEBAR_CLASS = minicart.sidebarOpen

/* SideBar component */
class Sidebar extends Component {
  updateComponent() {
    if (this.props.isOpen) {
      document.body.classList.add(OPEN_SIDEBAR_CLASS)
    } else {
      document.body.classList.remove(OPEN_SIDEBAR_CLASS)
    }
  }

  componentDidMount() {
    this.updateComponent()
  }

  componentDidUpdate() {
    this.updateComponent()
  }

  componentWillUnmount() {
    document.body.classList.remove(OPEN_SIDEBAR_CLASS)
  }

  render() {
    const {
      isOpen,
      onOutsideClick,
      intl,
      iconSize,
      quantity,
      iconsProps,
    } = this.props

    if (typeof document === 'undefined') {
      return null
    }

    const scrimClasses = classNames(
      `${minicart.sidebarScrim} fixed dim bg-base--inverted top-0 left-0 z-9999 w-100 vh-100 o-40`,
      {
        dn: !isOpen,
      }
    )

    return (
      <Overlay fullWidth>
        <OutsideClickHandler onOutsideClick={onOutsideClick}>
          <div
            style={{ willChange: 'opacity' }}
            className={scrimClasses}
            onClick={onOutsideClick}
          />

          <Animation
            className={`${minicart.sidebar} w-80 w-auto-ns h-100 fixed top-0 right-0 z-9999 bg-base shadow-2 flex flex-column`}
            isActive={isOpen}
            type="drawerLeft"
          >
            <div
              className={`${minicart.sidebarHeader} pointer flex flex-row items-center pa5 h3 bg-base w-100 z-max bb b--muted-3 bw1`}
            >
              <div
                className={`${minicart.sidebarRightCaretContainer} c-muted-1 pa4 flex items-center`}
                onClick={onOutsideClick}
              >
                <IconCaret orientation="right" size={17} {...iconsProps} />
              </div>
              <div
                className={`${minicart.sidebarItemQuantityContainer} relative c-muted-1`}
              >
                <IconCart size={iconSize} {...iconsProps} />
                {quantity > 0 && (
                  <span
                    className={`${minicart.badge} c-on-emphasis absolute t-mini bg-emphasis br4 w1 h1 pa1 flex justify-center items-center lh-solid`}
                  >
                    {quantity}
                  </span>
                )}
              </div>
              <span
                className={`${minicart.label} dn-m db-l t-action--small pl${
                  quantity > 0 ? '6' : '4'
                } c-muted-1`}
              >
                {intl.formatMessage({ id: 'store/sidebar-title' })}
              </span>
            </div>
            {this.props.children}
          </Animation>
        </OutsideClickHandler>
      </Overlay>
    )
  }
}

Sidebar.propTypes = {
  /* Set the sideBar visibility */
  isOpen: PropTypes.bool,
  /* Sidebar content */
  children: PropTypes.object.isRequired,
  /* Function to be called when click in the close sidebar button or outside the sidebar */
  onOutsideClick: PropTypes.func,
  /* Items quantity */
  quantity: PropTypes.number.isRequired,
  /* Cart icon size */
  iconSize: PropTypes.number,
  /** Props to passed to icons from store-icons */
  iconsProps: PropTypes.shape({
    viewBox: PropTypes.string,
    size: PropTypes.number,
  }),
  intl: PropTypes.any,
}

export default injectIntl(Sidebar)

```


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

[User] Show me the implementation of minicart/react/legacy/__tests__/MiniCart.test.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
import React from 'react'
import { render, fireEvent, wait } from '@vtex/test-tools/react'
import orderFormQuery from 'vtex.store-resources/QueryOrderForm'
import orderForm from '../__fixtures__/orderForm'
import emptyOrderForm from '../__fixtures__/emptyOrderForm'
import MiniCart from '../../index'
import { transformOrderFormItems } from '../../modules/pixelHelper'

const mockedUsePixelPush = jest.fn()

jest.mock('vtex.pixel-manager', () => ({
  usePixel: () => ({ push: mockedUsePixelPush }),
}))

const mocks = [
  {
    request: {
      query: orderFormQuery,
    },
    result: {
      data: {
        orderForm,
      },
    },
  },
]

const emptyMock = [
  {
    request: {
      query: orderFormQuery,
    },
    result: {
      data: {
        orderForm: emptyOrderForm,
      },
    },
  },
]

describe('<MiniCart />', () => {
  beforeEach(() => {
    jest.useFakeTimers()
  })

  afterEach(() => {
    mockedUsePixelPush.mockClear()
  })

  it('should render popup onClick', async () => {
    const { getByText, baseElement } = render(
      <MiniCart type="popup" hideContent={false} />
    )

    await wait(() => {
      jest.runAllTimers()
    })

    let box = baseElement.querySelector('.box')
    let sidebar = baseElement.querySelector('.sidebar')

    // Expect box be null before click
    expect(box).toBeNull()
    // Sidebar should not exist before and after click
    expect(sidebar).toBeNull()

    await wait(() => {
      fireEvent.click(getByText(/button test/i))
    })

    await wait(() => {
      jest.runAllTimers()
    })

    box = baseElement.querySelector('.box')
    sidebar = baseElement.querySelector('.sidebar')

    // Expect Minicart Popup redered
    expect(box).toBeDefined()
    expect(box).not.toBeNull()
    // Expect sidebar still not rendered
    expect(sidebar).toBeNull()
  })

  it('should display sidebar onClick', async () => {
    const { getByText, baseElement } = render(
      <MiniCart type="sidebar" hideContent={false} />
    )

    await wait(() => {
      jest.runAllTimers()
    })

    let box = baseElement.querySelector('.box')
    let sidebar = baseElement.querySelector('.sidebarScrim.dn')

    // Expect box be null before and after click
    expect(box).toBeNull()
    // Sidebar should have diplay none class before click
    expect(sidebar).toBeDefined()
    expect(sidebar).not.toBeNull()

    await wait(() => {
      fireEvent.click(getByText(/button test/i))
    })

    await wait(() => {
      jest.runAllTimers()
    })

    box = baseElement.querySelector('.box')
    sidebar = baseElement.querySelector('.sidebarScrim.dn')

    // Expect sidebar dont have display none after click
    expect(sidebar).toBeNull()
    expect(box).toBeNull()
  })

  it('should match the snapshot in popup mode', async () => {
    const leftClick = { button: 0 }

    const { getByText, asFragment } = render(
      <MiniCart type="popup" hideContent={false} />,
      { graphql: { mocks } }
    )

    await wait(() => {
      jest.runAllTimers()
    })

    await wait(() => {
      fireEvent.click(getByText(/button test/i), leftClick)
    })

    await wait(() => {
      jest.runAllTimers()
    })

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

  it('should match the snapshot in sidebar mode', async () => {
    const { baseElement } = render(
      <MiniCart type="sidebar" hideContent={false} />,
      { graphql: { mocks } }
    )

    await wait(async () => {
      jest.runAllTimers()
    })

    expect(baseElement).toMatchSnapshot()
  })

  it('should be editable in Site Editor', () => {
    const schema = MiniCart.schema || MiniCart.getSchema({})
    expect(schema).toEqual(
      expect.objectContaining({ title: expect.any(String) })
    )
  })

  it('should not show item quantity if there are no items in cart', async () => {
    const { queryByTestId } = render(
      <MiniCart type="sidebar" hideContent={false} showTotalItemsQty={false} />,
      { graphql: { mocks: emptyMock } }
    )

    await wait(() => {
      jest.runAllTimers()
    })

    expect(queryByTestId('item-qty')).toBeNull()
  })

  it('should show the quantity of different items in cart', async () => {
    const { getByTestId } = render(
      <MiniCart type="sidebar" hideContent={false} showTotalItemsQty={false} />,
      { graphql: { mocks } }
    )

    await wait(() => {
      jest.runAllTimers()
    })

    expect(getByTestId('item-qty').textContent).toBe('1')
  })

  it('should show the total quantity of items in cart', async () => {
    const { getByTestId } = render(
      <MiniCart type="sidebar" hideContent={false} showTotalItemsQty />,
      { graphql: { mocks } }
    )

    await wait(() => {
      jest.runAllTimers()
    })

    expect(getByTestId('item-qty').textContent).toBe('2')
  })

  it('should not show price if showPrice is false', async () => {
    const { queryByTestId } = render(
      <MiniCart type="sidebar" hideContent={false} showPrice={false} />,
      { graphql: { mocks } }
    )
    await wait(() => {
      jest.runAllTimers()
    })
    expect(queryByTestId('total-price')).toBeNull()
  })

  it('should not show price if there are no items in the cart', async () => {
    const { queryByTestId } = render(
      <MiniCart type="sidebar" hideContent={false} showPrice />,
      { graphql: { mocks: emptyMock } }
    )
    await wait(() => {
      jest.runAllTimers()
    })

    expect(queryByTestId('total-price')).toBeNull()
  })

  it('should show price if there are items in the cart', async () => {
    const { getByTestId } = render(
      <MiniCart type="sidebar" hideContent={false} showPrice />,
      { graphql: { mocks } }
    )
    await wait(() => {
      jest.runAllTimers()
    })
    expect(getByTestId('total-price')).toBeInTheDocument()
  })

  it('should trigger vtex:viewCart when cart is opened', async () => {
    const { container } = render(
      <MiniCart type="sidebar" hideContent={false} />,
      { graphql: { mocks } }
    )

    const cartButton = container.getElementsByClassName('IconCart')[0]

    await wait(() => {
      jest.runAllTimers()
    })

    await wait(() => {
      fireEvent.click(cartButton)
    })

    await wait(() => {
      jest.runAllTimers()
    })

    const expectedPixelEvent = {
      event: 'viewCart',
      items: transformOrderFormItems(orderForm.items),
    }

    expect(mockedUsePixelPush).toHaveBeenCalledWith(expectedPixelEvent)
  })

  it('should trigger vtex:viewCart when cart is opened with no items', async () => {
    const { getByText } = render(
      <MiniCart type="sidebar" hideContent={false} />,
      { graphql: { mocks: emptyMock } }
    )

    await wait(() => {
      jest.runAllTimers()
    })

    await wait(() => {
      fireEvent.click(getByText(/button test/i))
    })

    await wait(() => {
      jest.runAllTimers()
    })

    const expectedPixelEvent = {
      event: 'viewCart',
      items: [],
    }

    expect(mockedUsePixelPush).toHaveBeenCalledWith(expectedPixelEvent)
  })
})

```


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

[User] Show me the implementation of minicart/react/legacy/__tests__/localState.test.js from the minicart VTEX app.

[Assistant]
Here's the implementation:

```javascript
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import gql from 'graphql-tag'

import createLocalState, { ITEMS_STATUS } from '../localState/index'
import addToCartMutation from '../localState/graphql/addToCartMutation.gql'
import updateItemsMutation from '../localState/graphql/updateItemsMutation.gql'

describe('Local State', () => {
  let cache
  let client

  beforeEach(() => {
    cache = new InMemoryCache()
    client = new ApolloClient({
      link: ApolloLink.empty(),
      cache,
    })

    const { resolvers, initialState } = createLocalState(client)

    client.addResolvers(resolvers)
    cache.writeData({ data: initialState })
  })

  it('should append new items to end of cart', async () => {
    const items = [
      {
        id: '100',
        name: 'Chiclete',
        imageUrl: 'imageUrl',
        detailUrl: '/chiclete/p',
        skuName: 'chiclete',
        quantity: 1,
        sellingPrice: 0,
        listPrice: 0,
        parentItemIndex: null,
        parentAssemblyBinding: null,
        assemblyOptions: {
          added: [],
          removed: [],
          parentPrice: 0,
        },
      },
      {
        id: '101',
        name: 'Chiclete de menta',
        imageUrl: 'imageUrl',
        detailUrl: '/chiclete-de-menta/p',
        skuName: 'chiclete de menta',
        quantity: 1,
        sellingPrice: 0,
        listPrice: 0,
        parentItemIndex: null,
        parentAssemblyBinding: null,
        assemblyOptions: {
          added: [],
          removed: [],
          parentPrice: 0,
        },
      },
    ]

    await client.mutate({ mutation: addToCartMutation, variables: { items } })

    const queryResult = client.readQuery({
      query: gql`
        query {
          minicart @client {
            items
          }
        }
      `,
    })

    const cacheItems = JSON.parse(queryResult.minicart.items)

    // assert that the cache items contains all items of the mutation
    expect(cacheItems).toEqual(
      expect.arrayContaining(items.map(expect.objectContaining))
    )

    cacheItems.forEach(item => {
      expect(item).toHaveProperty('localStatus', ITEMS_STATUS.MODIFIED)
    })
  })

  it('should update quantity of item in cart', async () => {
    const item = {
      id: '100',
      name: 'Chiclete',
      imageUrl: 'imageUrl',
      detailUrl: '/chiclete/p',
      skuName: 'chiclete',
      quantity: 1,
      sellingPrice: 0,
      listPrice: 0,
      parentItemIndex: null,
      parentAssemblyBinding: null,
      assemblyOptions: {
        added: [],
        removed: [],
        parentPrice: 0,
      },
    }

    cache.writeData({
      data: {
        minicart: {
          __typename: 'Minicart',
          items: JSON.stringify([item]),
        },
      },
    })

    const updateItemsPayload = [{ index: 0, quantity: 2, id: item.id }]

    await client.mutate({
      mutation: updateItemsMutation,
      variables: { items: updateItemsPayload },
    })

    const queryResult = client.readQuery({
      query: gql`
        query {
          minicart @client {
            items
          }
        }
      `,
    })

    const cacheItems = JSON.parse(queryResult.minicart.items)

    expect(cacheItems).toEqual(
      expect.arrayContaining(
        updateItemsPayload.map(currentItem =>
          expect.objectContaining({
            id: currentItem.id,
            localStatus: ITEMS_STATUS.MODIFIED,
          })
        )
      )
    )

    expect(cacheItems).toEqual(
      expect.arrayContaining(
        updateItemsPayload.map(currentItem =>
          expect.objectContaining({
            id: currentItem.id,
            quantity: currentItem.quantity,
          })
        )
      )
    )
  })

  it('should update quantity of more than one item in cart', async () => {
    const items = [
      {
        id: '100',
        name: 'Chiclete',
        imageUrl: 'imageUrl',
        detailUrl: '/chiclete/p',
        skuName: 'chiclete',
        quantity: 1,
        sellingPrice: 0,
        listPrice: 0,
        parentItemIndex: null,
        parentAssemblyBinding: null,
        assemblyOptions: {
          added: [],
          removed: [],
          parentPrice: 0,
        },
      },
      {
        id: '101',
        name: 'Chiclete de menta',
        imageUrl: 'imageUrl',
        detailUrl: '/chiclete-de-menta/p',
        skuName: 'chiclete de menta',
        quantity: 1,
        sellingPrice: 0,
        listPrice: 0,
        parentItemIndex: null,
        parentAssemblyBinding: null,
        assemblyOptions: {
          added: [],
          removed: [],
          parentPrice: 0,
        },
      },
    ]

    cache.writeData({
      data: {
        minicart: {
          __typename: 'Minicart',
          items: JSON.stringify(items),
        },
      },
    })

    const updateItemsPayload = [
      { index: 0, quantity: 2, id: items[0].id },
      { index: 1, quantity: 9, id: items[1].id },
    ]

    await client.mutate({
      mutation: updateItemsMutation,
      variables: { items: updateItemsPayload },
    })

    const queryResult = client.readQuery({
      query: gql`
        query {
          minicart @client {
            items
          }
        }
      `,
    })

    const cacheItems = JSON.parse(queryResult.minicart.items)

    expect(cacheItems).toEqual(
      expect.arrayContaining(
        updateItemsPayload.map(item =>
          expect.objectContaining({
            id: item.id,
            localStatus: ITEMS_STATUS.MODIFIED,
          })
        )
      )
    )

    expect(cacheItems).toEqual(
      expect.arrayContaining(
        updateItemsPayload.map(item =>
          expect.objectContaining({ id: item.id, quantity: item.quantity })
        )
      )
    )
  })
})

```


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

[User] Show me the implementation of minicart/react/legacy/__tests__/MiniCartV2.test.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
/* eslint-disable global-require */
import React from 'react'
import { render, wait } from '@vtex/test-tools/react'

import { Minicart } from '../../Minicart'
import { MinicartStateContext } from '../../MinicartContext'
import { transformOrderFormItems } from '../../modules/pixelHelper'
import orderForm from '../__fixtures__/orderForm'

const mockedUsePixelPush = jest.fn()

jest.mock('vtex.pixel-manager', () => ({
  usePixel: () => ({ push: mockedUsePixelPush }),
}))

jest.mock('vtex.order-manager/OrderForm', () => {
  const mockData = require('../__fixtures__/orderForm')

  return {
    useOrderForm: jest
      .fn(() => ({
        orderForm: mockData.default,
      }))
      .mockImplementationOnce(() => ({
        orderForm: [],
      })),
  }
})

const minicartMockContextValue = {
  variation: 'drawer',
  open: true,
  hasBeenOpened: false,
  openOnHoverProp: false,
  openBehavior: 'click',
}

describe('<MiniCart /> v2', () => {
  beforeEach(() => {
    jest.useFakeTimers()
  })

  it('should trigger vtex:viewCart when cart is opened and match items when cart is empty', async () => {
    render(
      <MinicartStateContext.Provider value={minicartMockContextValue}>
        <Minicart variation="drawer" />
      </MinicartStateContext.Provider>
    )

    await wait(async () => {
      jest.runAllTimers()
    })

    const expectedPixelEvent = {
      event: 'viewCart',
      items: [],
    }

    expect(mockedUsePixelPush).toHaveBeenCalledWith(expectedPixelEvent)
  })

  it('should trigger vtex:viewCart when cart is opened and match items when cart is with products', async () => {
    render(
      <MinicartStateContext.Provider value={minicartMockContextValue}>
        <Minicart variation="drawer" />
      </MinicartStateContext.Provider>
    )

    await wait(async () => {
      jest.runAllTimers()
    })

    const expectedPixelEvent = {
      event: 'viewCart',
      items: transformOrderFormItems(orderForm.items),
    }

    expect(mockedUsePixelPush).toHaveBeenCalledWith(expectedPixelEvent)
  })
})

```


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

[User] Show me the implementation of minicart/react/legacy/hooks/useMarketingSessionParams.jsx from the minicart VTEX app.

[Assistant]
Here's the implementation:

```jsx
import { useEffect, useState } from 'react'
// eslint-disable-next-line no-restricted-imports
import { path, pathOr } from 'ramda'

const getUtmParams = publicFields => ({
  source: path(['utm_source', 'value'], publicFields),
  medium: path(['utm_medium', 'value'], publicFields),
  campaign: path(['utm_campaign', 'value'], publicFields),
})

const getUtmiParams = publicFields => ({
  campaign: path(['utmi_cp', 'value'], publicFields),
  page: path(['utmi_p', 'value'], publicFields),
  part: path(['utmi_pc', 'value'], publicFields),
})

const getSessionPromiseFromWindow = () =>
  !window.__RENDER_8_SESSION__ || !window.__RENDER_8_SESSION__.sessionPromise
    ? Promise.resolve(null)
    : window.__RENDER_8_SESSION__.sessionPromise

const useMarketingSessionParams = () => {
  const [utmParams, setUtmParams] = useState(undefined)
  const [utmiParams, setUtmiParams] = useState(undefined)

  useEffect(() => {
    getSessionPromiseFromWindow()
      .then(data => {
        const publicFields = pathOr(
          {},
          ['response', 'namespaces', 'public'],
          data
        )
        if (Object.keys(publicFields).length === 0) {
          return
        }

        setUtmParams(getUtmParams(publicFields))
        setUtmiParams(getUtmiParams(publicFields))
      })
      .catch(() => {
        // Do nothing!
      })
  }, [])

  return { utmParams, utmiParams }
}

export default useMarketingSessionParams

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/updateLocalItemStatusMutation.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation updateLocalItemStatus {
  updateLocalItemStatus @client
}

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/addToCartMutation.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation addToCart($items: [MinicartItem]) {
  addToCart(items: $items) @client
}

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/updateLocalItemsMutation.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation UpdateLocalItems($items: [MinicartItem]) {
  updateLocalItems(items: $items) @client
}

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/fullMinicartQuery.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
query {
  minicart @client {
    items
    orderForm
    isOpen
  }
}

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/minicartOrderFormQuery.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
query orderForm {
  minicart @client {
    orderForm
  }
}

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/updateOrderFormMutation.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation updateOrderForm(
  $orderForm: [OrderForm]
  $forceUpdateItems: Boolean = false
) {
  updateOrderForm(orderForm: $orderForm, forceUpdateItems: $forceUpdateItems)
    @client
}

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/updateItemsMutation.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation updateItems($items: [MinicartItem]) {
  updateItems(items: $items) @client
}

```


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

[User] Show me the implementation of minicart/react/legacy/localState/graphql/setMinicartOpenMutation.gql from the minicart VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation setMinicartOpen($isOpen: Boolean!) {
  setMinicartOpen(isOpen: $isOpen) @client
}

```