[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 store-graphql/node/resolvers/benefits/index.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { flatten, indexOf, path } from 'ramda'

import { queries as checkoutQueries } from '../checkout'

const SKU_SEPARATOR = ','
const CATALOG = 'Catalog'
const DEFAULT_SELLER = '1'
const DEFAULT_QUANTITY = '1'

export const fieldResolvers = {
  Benefit: {
    items: async (benefit: any, _: any, { clients: { catalog } }: Context) => {
      const { teaserType, conditions, effects } = benefit

      if (teaserType !== CATALOG) {
        return
      }

      const {
        parameters: conditionsParameters,
        minimumQuantity = parseInt(DEFAULT_QUANTITY, 10),
      } = conditions

      const { parameters: effectsParameters } = effects

      const items = await Promise.all(
        conditionsParameters.map(
          async (conditionsParameter: any, index: any) => {
            const skuIds: string[] = conditionsParameter.value.split(
              SKU_SEPARATOR
            )

            const discount = effectsParameters[index].value
            const products = await catalog.productBySku(skuIds)

            return products.map((product: any) => {
              const benefitSKUIds: any = []

              product.items.forEach((item: any) => {
                if (indexOf(item.itemId, skuIds) > -1) {
                  benefitSKUIds.push(item.itemId)
                }
              })

              return {
                benefitProduct: product,
                benefitSKUIds,
                discount,
                minQuantity: minimumQuantity,
              }
            })
          }
        )
      )

      return flatten(items)
    },
  },
}

export const queries = {
  /**
   * There are two ways to make the request data
   * First of them is passing the graphql args with the items property which is an array of Shipping Items.
   * Second is passing just the id of the product itself as a graphql argument.
   */
  benefits: async (_: any, args: any, config: any) => {
    const requestBody = {
      items: args.items
        ? args.items
        : [
            {
              id: args.id,
              quantity: DEFAULT_QUANTITY,
              seller: DEFAULT_SELLER,
            },
          ],
    }

    const benefitsData = await checkoutQueries.shipping(_, requestBody, config)

    return path(['ratesAndBenefitsData', 'teaser'], benefitsData) || []
  },
}

```


[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 store-graphql/node/resolvers/logistics/fieldResolvers.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { prop } from 'ramda'

import { LogisticPickupPoint } from './types'
import { SalesChannel } from '../../clients/portal'

export default {
  LogisticsData: {
    shipsTo: async (obj: any, __: any, context: Context) => {
      if (!obj || !obj.shipsTo || obj.shipsTo.length === 0) {
        const defaultSalesChannelCountry = prop(
          'CountryCode',
          (await context.clients.portal.defaultSalesChannel()) as SalesChannel
        )

        return [defaultSalesChannelCountry]
      }

      return obj.shipsTo
    },
  },
  PickupPoint: {
    address: ({ id, address: logAddress }: LogisticPickupPoint) => {
      const { country, location, ...rest } = logAddress

      return {
        ...rest,
        receiverName: null,
        addressId: id,
        addressType: 'pickup',
        country: country.acronym,
        geoCoordinate: [location.longitude, location.latitude],
        id,
      }
    },
    friendlyName: ({ name }: LogisticPickupPoint) => name,
  },
}

```


[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 store-graphql/node/resolvers/logistics/types.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface LogisticAddress {
  country: { acronym: string; name: string }
  location: { latitude: number; longitude: number }
  postalCode: string
  city: string
  state: string
  neighborhood: string
  street: string
  number: string
  complement: string
  reference: string
}

export interface LogisticPickupPoint {
  name: string
  address: LogisticAddress
  id: string
  description: string | null
  instructions: string
  formatted_address: string | null
  isActive: boolean
  distance: number
  seller: string
  businessHours: Array<{
    closingTime: string
    openingTime: string
    dayOfWeek: number
  }>
  tagsLabel: any[]
  pickupHolidays: any[]
}

interface Paging {
  page: number
  perPage: number
  total: number
  pages: number
}

export interface LogisticOutput {
  items: LogisticPickupPoint[]
  paging: Paging
}

export interface NearPickupPointsArgs {
  lat: string
  long: string
  maxDistance: number | undefined
}

export interface PickupPointArgs {
  id: string
}

```


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

[User] Show me the implementation of store-graphql/node/resolvers/logistics/index.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { NearPickupPointsArgs, PickupPointArgs } from './types'
import fieldR from './fieldResolvers'

export const fieldResolvers = fieldR

export const queries = {
  logistics: (_: any, __: any, { clients: { logistics } }: Context) =>
    logistics.shipping(),

  nearPickupPoints: (
    _: any,
    { lat, long, maxDistance }: NearPickupPointsArgs,
    { clients: { logistics } }: Context
  ) => logistics.nearPickupPoints(lat, long, maxDistance),

  pickupPoint: (
    _: any,
    { id }: PickupPointArgs,
    { clients: { logistics } }: Context
  ) => logistics.pickupById(id),
}

```


[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 store-graphql/node/resolvers/session/sessionPickup.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { path } from 'ramda'

export const fieldResolvers = {
  SessionPickup: {
    cacheId: path(['address', 'addressId']),
  },
}

```


[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 store-graphql/node/resolvers/session/index.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { serialize } from 'cookie'
import { identity } from 'ramda'

import { fieldResolvers as sessionPickupResolvers } from './sessionPickup'
import { vtexIdCookies } from '../../utils/vtexId'
import { setCheckoutCookies, syncWithStoreLocale } from '../checkout'
import { VTEX_SESSION, getSession } from './service'

const IMPERSONATED_EMAIL = 'vtex-impersonated-customer-email'
// maxAge of 1-day defined in vtex-impersonated-customer-email cookie
const VTEXID_EXPIRES = 86400

interface SavePickupArgs {
  name: string
  address: CheckoutAddress
}

const convertCheckoutAddressToProfile = (
  checkoutAddress: CheckoutAddress | null
) => {
  if (!checkoutAddress) {
    return checkoutAddress
  }

  const { geoCoordinates, ...rest } = checkoutAddress

  return { ...rest, geoCoordinate: geoCoordinates }
}

// Disclaimer: These queries and mutations assume that vtex_session was passed in cookies.
export const queries = {
  /**
   * Get user session
   * @return Session
   */
  getSession: async (_: any, __: any, ctx: Context) => {
    return getSession(ctx)
  },
}

interface ImpersonateArg {
  email: string
}

export const mutations = {
  impersonate: async (_: any, { email }: ImpersonateArg, ctx: Context) => {
    const {
      clients: { customSession, checkout },
      cookies,
    } = ctx

    await customSession.updateSession(
      IMPERSONATED_EMAIL,
      email,
      [],
      cookies.get(VTEX_SESSION)!,
      vtexIdCookies(ctx)
    )

    const orderForm = await checkout.orderForm()
    const clientProfileData = orderForm?.clientProfileData
      ? orderForm.clientProfileData
      : {}

    if (clientProfileData.email !== email && orderForm.orderFormId) {
      await checkout.updateOrderFormProfile(
        orderForm.orderFormId,
        {
          ...clientProfileData,
          email,
        },
        ctx
      )
    }

    ctx.response.set(
      'Set-Cookie',
      serialize(IMPERSONATED_EMAIL, email, {
        encode: identity,
        maxAge: VTEXID_EXPIRES,
        path: '/',
      })
    )

    return queries.getSession({}, {}, ctx)
  },

  depersonify: async (_: any, __: any, ctx: Context) => {
    const {
      clients: { customSession, checkout },
      cookies,
      vtex: { segment },
    } = ctx

    await customSession.updateSession(
      IMPERSONATED_EMAIL,
      '',
      [],
      cookies.get(VTEX_SESSION)!,
      vtexIdCookies(ctx)
    )

    const { data, headers } = await checkout.newOrderForm()

    await syncWithStoreLocale(data, segment!.cultureInfo, checkout)

    setCheckoutCookies(headers, ctx)

    ctx.cookies.set(IMPERSONATED_EMAIL, '', {
      maxAge: 0,
      path: '/',
    })

    return true
  },

  savePickupInSession: async (_: any, args: SavePickupArgs, ctx: Context) => {
    const { address, name } = args
    const {
      clients: { customSession },
      cookies,
    } = ctx

    await customSession.updateSession(
      'favoritePickup',
      { address: convertCheckoutAddressToProfile(address), name },
      [],
      cookies.get(VTEX_SESSION)!,
      vtexIdCookies(ctx)
    )

    return queries.getSession({}, {}, ctx)
  },
}

export const fieldResolvers = {
  ...sessionPickupResolvers,
}

```


[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 store-graphql/node/resolvers/session/sessionResolver.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { path, toLower } from 'ramda'

interface ProfileFields {
  document?: string
  email?: string
  firstName?: string
  id?: string
  isAuthenticatedAsCustomer?: boolean
  lastName?: string
  phone?: string
  priceTables: string[]
}

export interface SessionFields {
  adminUserEmail?: string
  adminUserId?: string
  id?: string
  cacheId?: string
  impersonable?: boolean
  impersonate?: { profile: ProfileFields }
  orderFormId?: string
  address?: any
  profile?: ProfileFields
  utmParams?: UtmParams
  utmiParams?: UtmiParams
  favoritePickup?: { address: CheckoutAddress; name: string }
  public?: {
    [key: string]: {
      value: string
    }
  }
}

interface UtmParams {
  source?: string
  medium?: string
  campaign?: string
  term?: string
  content?: string
}

interface UtmiParams {
  campaign?: string
  page?: string
  part?: string
}

const convertToBool = (str: any) => !!str && toLower(str) === 'true'

const priceTables = (profile: SessionProfile): string[] => {
  const priceTablesValue = profile?.priceTables?.value

  return priceTablesValue ? priceTablesValue.split(',') : []
}

const profileFields = (
  profile: SessionProfile,
  user: SessionImpersonate | SessionAuthentication
): ProfileFields => ({
  document: path(['document', 'value'], profile),
  email:
    path(['email', 'value'], profile) ??
    path(['storeUserEmail', 'value'], user),
  firstName: path(['firstName', 'value'], profile),
  id: path(['id', 'value'], profile),
  isAuthenticatedAsCustomer: convertToBool(
    path(['isAuthenticated', 'value'], profile)
  ),
  lastName: path(['lastName', 'value'], profile),
  phone: path(['phone', 'value'], profile),
  priceTables: priceTables(profile),
})

const setProfileData = (
  profile: SessionProfile,
  user: SessionImpersonate | SessionAuthentication
) =>
  path(['storeUserId', 'value'], user) && {
    profile: {
      ...profileFields(profile, user),
    },
  }

const setUtmParams = (publicFields: SessionPublic) => ({
  source: path(['utm_source', 'value'], publicFields),
  medium: path(['utm_medium', 'value'], publicFields),
  campaign: path(['utm_campaign', 'value'], publicFields),
  term: path(['utm_term', 'value'], publicFields),
  content: path(['utm_content', 'value'], publicFields),
})

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

export const sessionFields = (
  session: Session
): SessionFields | Record<string, unknown> => {
  const { namespaces } = session

  return namespaces
    ? {
        address: path(['public', 'address', 'value'], namespaces),
        adminUserEmail: path(
          ['authentication', 'adminUserEmail', 'value'],
          namespaces
        ),
        adminUserId: path(
          ['authentication', 'adminUserId', 'value'],
          namespaces
        ),
        id: session.id,
        cacheId: session.id,
        impersonable: convertToBool(
          path(['impersonate', 'canImpersonate', 'value'], namespaces)
        ),
        impersonate: {
          ...setProfileData(namespaces.profile, namespaces.impersonate),
        },
        public: namespaces.public,
        utmParams: setUtmParams(namespaces.public),
        utmiParams: setUtmiParams(namespaces.public),
        orderFormId: path(['public', 'orderFormId', 'value'], namespaces),
        favoritePickup: path(['public', 'favoritePickup', 'value'], namespaces),
        ...setProfileData(namespaces.profile, namespaces.authentication),
      }
    : ({} as any)
}

```


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

[User] Show me the implementation of store-graphql/node/resolvers/session/service.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

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

import { sessionFields } from './sessionResolver'

export const VTEX_SESSION = 'vtex_session'

export async function getSession(context: Context) {
  const {
    clients: { customSession },
    cookies,
  } = context

  const sessionCookie = cookies.get(VTEX_SESSION)

  if (sessionCookie === undefined)
    throw new ResolverError(
      `Invalid request for session, the ${VTEX_SESSION} wasn't provided!`
    )

  const { sessionData } = await customSession.getSession(sessionCookie, ['*'])

  return sessionFields(sessionData)
}

```


[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 store-graphql/node/__tests__/checkout/index.test.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { mutations } from '../../resolvers/checkout'
// eslint-disable-next-line jest/no-mocks-import
import orderForm from '../../__mocks__/orderForm'

const mockContext = {
  vtex: {
    orderFormId: orderForm.orderFormId,
  },
  clients: {
    checkout: {
      orderForm: jest.fn().mockImplementation(() => orderForm),
      updateOrderFormMarketingData: jest.fn(),
      addItem: jest.fn(),
    },
  },
}

beforeEach(() => {
  jest.clearAllMocks()
})

test('should call add item with correct param', async () => {
  const itemToAdd = {
    id: 100,
    quantity: 1,
    seller: '1',
  }

  await mutations.addItem(
    {},
    {
      orderFormId: orderForm.orderFormId,
      items: [itemToAdd],
    },
    mockContext as any
  )

  const checkoutClient = mockContext.clients.checkout

  expect(checkoutClient.addItem.mock.calls[0][0]).toBe(orderForm.orderFormId)
  expect(checkoutClient.addItem.mock.calls[0][1]).toMatchObject([itemToAdd])
  expect(checkoutClient.updateOrderFormMarketingData).toBeCalledTimes(0)
})

test.each([
  null,
  {
    utmSource: 'SOURCE DIFFERENT',
    utmMedium: 'medium',
    utmCampaign: 'campaign',
    utmiCampaign: 'campaign',
    utmiPart: 'part',
    utmipage: 'page33',
  },
])(
  'should correctly update order form marketing data when necessary',
  async (currentMarketingData: any) => {
    const itemToAdd = {
      id: 100,
      quantity: 1,
      seller: '1',
    }

    const checkoutClient = mockContext.clients.checkout

    checkoutClient.orderForm.mockImplementationOnce(() => ({
      ...orderForm,
      marketingData: currentMarketingData,
    }))
    await mutations.addItem(
      {},
      {
        orderFormId: orderForm.orderFormId,
        items: [itemToAdd],
        utmParams: { source: 'source', medium: 'medium', campaign: 'campaign' },
        utmiParams: { part: 'part', page: 'page', campaign: 'campaign' },
      },
      mockContext as any
    )

    expect(checkoutClient.addItem.mock.calls[0][0]).toBe(orderForm.orderFormId)
    expect(checkoutClient.addItem.mock.calls[0][1]).toMatchObject([itemToAdd])
    expect(checkoutClient.updateOrderFormMarketingData).toBeCalledTimes(1)
    expect(checkoutClient.updateOrderFormMarketingData.mock.calls[0][0]).toBe(
      orderForm.orderFormId
    )
    expect(
      checkoutClient.updateOrderFormMarketingData.mock.calls[0][1]
    ).toMatchObject({
      utmSource: 'source',
      utmMedium: 'medium',
      utmCampaign: 'campaign',
      utmiCampaign: 'campaign',
      utmiPart: 'part',
      utmipage: 'page',
    })
  }
)

test.each<any>([
  [
    {
      utmSource: 'source',
      utmMedium: 'medium',
      utmCampaign: 'campaign',
      utmiCampaign: 'campaign',
      utmiPart: 'part',
      utmipage: 'page',
    },
    { source: 'source', medium: 'medium', campaign: 'campaign' },
    { part: 'part', page: 'page', campaign: 'campaign' },
  ],
  [
    {
      utmSource: 'source',
      utmMedium: null,
      utmCampaign: null,
      utmiCampaign: null,
      utmiPart: null,
      utmipage: null,
    },
    { source: 'source' },
    {},
  ],
])(
  'should not update order form marketing if it is identical to the arg sent',
  async (currentMarketingData: any, utmParams: any, utmiParams: any) => {
    const itemToAdd = {
      id: 100,
      quantity: 1,
      seller: '1',
    }

    const checkoutClient = mockContext.clients.checkout

    checkoutClient.orderForm.mockImplementationOnce(() => ({
      ...orderForm,
      marketingData: currentMarketingData,
    }))

    await mutations.addItem(
      {},
      {
        orderFormId: orderForm.orderFormId,
        items: [itemToAdd],
        utmParams,
        utmiParams,
      },
      mockContext as any
    )

    expect(checkoutClient.addItem.mock.calls[0][0]).toBe(orderForm.orderFormId)
    expect(checkoutClient.addItem.mock.calls[0][1]).toMatchObject([itemToAdd])
    expect(checkoutClient.updateOrderFormMarketingData).toBeCalledTimes(0)
  }
)

test.each<any>([
  [undefined, undefined],
  [{}, {}],
])(
  'empty utmParams and utmiParams do not call updateOrderFormMarketingData',
  async (utmParams, utmiParams) => {
    const itemToAdd = {
      id: 100,
      quantity: 1,
      seller: '1',
    }

    const checkoutClient = mockContext.clients.checkout

    checkoutClient.orderForm.mockImplementationOnce(() => ({
      ...orderForm,
      marketingData: { coupon: null, marketingTags: [] },
    }))

    await mutations.addItem(
      {},
      {
        orderFormId: orderForm.orderFormId,
        items: [itemToAdd],
        utmParams,
        utmiParams,
      },
      mockContext as any
    )

    expect(checkoutClient.addItem.mock.calls[0][0]).toBe(orderForm.orderFormId)
    expect(checkoutClient.addItem.mock.calls[0][1]).toMatchObject([itemToAdd])
    expect(checkoutClient.updateOrderFormMarketingData).toBeCalledTimes(0)
  }
)

```


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

[User] Show me the implementation of store-graphql/node/__tests__/price/calculatePrice.ts from the store-graphql VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { calculatePrice } from '../../utils/calculatePrice'
import prices from '../../__mocks__/calculatePrice'

describe('calculatePrice', () => {
  prices.forEach((priceObj) => {
    const { calculatedSellingPrice, unitMultiplier, price } = priceObj

    calculatedSellingPrice.forEach((sellingPrice) => {
      unitMultiplier.forEach((multiplier) => {
        it(`should calculate the correct real price with sellingPrice ${sellingPrice} and unitMultiplier ${multiplier} and`, () => {
          const realPrice = calculatePrice(multiplier, sellingPrice, price)
          const formatRealPrice = Number((realPrice / 100).toFixed(3))
          const realSellingPrice = Math.floor(
            formatRealPrice * multiplier * 100
          )

          expect(realSellingPrice).toBe(sellingPrice)
        })
      })
    })
  })
})

```


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

[Assistant]
Here's the implementation:

```markdown
##  ⚠ Maintenance ⚠
*Starting September 1st 2022, this application will no longer be maintained by VTEX. Code is released for free under the GNU/PL Agreement for you to use and modify at your convenience. The VTEX repository shall remain unchanged with the original version.*

---

# Product Availability Gallery

## Description

The Product Availability component shows the available amount of products. It also implements the needed services to request availability using the inventory API and validating USERS using masterdata.
**IMPORTANT** This block was built to work only in account: ```arvital``` , however it can be easily evolved to support other customers.

It is available to be used in product page, gallery , category and search.

:loudspeaker: **Disclaimer:** Don't fork this project; use, contribute, or open issue with your feature request

## Table of Contents

- [Usage](#usage)
    - [Blocks API](#blocks-api)
        - [Configuration](#configuration)
    - [Styles API](#styles-api)
        - [CSS Namespaces](#css-namespaces)
- [Troubleshooting](#troubleshooting)
- [Tests](#tests)

## Usage

This app uses our store builder with the blocks architecture. To know more about Store Builder [click here.](https://help.vtex.com/en/tutorial/understanding-storebuilder-and-stylesbuilder#structuring-and-configuring-our-store-with-object-object)

To use this app or override the default CSS you need import it in your dependencies on `manifest.json` file.

```json
  "dependencies": {
    "vtexarg.product-availability-gallery-gallery": "1.x"
  }
```

Then, add `product-availability-gallery-gallery` block to your `blocks.json`

Now, you can change the behavior of the `product-availability-gallery-gallery` block.

See an example of how to configure **showing availability**:

```json
"product-availability-gallery-gallery": {
  "props": {
    "showAvailability": true,
    "showAvailabilityMessage": "Available items:"
  }
}
```

### Blocks API

When implementing this app as a block, various inner blocks may be available. The following interface lists the available blocks within product-availability-gallery-gallery and describes if they are required or optional.

```json
{
  "product-availability-gallery-gallery": {
    "component": "ProductAvailability"
  }
}
```

For now this block does not have any required or optional blocks.

#### Configuration

Through the Storefront, you can change the product-availability-gallery's behavior and interface. However, you also can make in your theme app, as Store theme does.

| Prop name           | Type      | Description                                                                                |
| ------------------- | --------- | ------------------------------------------------------------------------------------------- |
| `threshold`     | `Number` | DefineMinimum quantity that makes low stock message appear (if message is set). Default: 0    |
| `lowStockMessage`        | `String` | String to be shown to user when stock is lower than threshold. Should have {quantity} inside the given string, to be replaced for the threshold property. Example: \"Only {quantity} left!\". Leave empty to not show. Default: ""              |
| `highStockMessage`  | `String` | String to be shown when stock is higher or equal than threshold. If left empty, won\'t show. Default: ""                                                              |
| `showAvailability`  | `Boolean` | Enables the possibility to show the available items instead of lowStockMessage or highStockMessage. Default: false                                                              |
| `showAvailabilityMessage`  | `String` | String to be shown when show available option is true. If left empty, won\'t show. Default: ""                                                              |

### Styles API

This app provides some CSS classes as an API for style customization.

To use this CSS API, you must add the `styles` builder and create an app styling CSS file.

1. Add the `styles` builder to your `manifest.json`:

```json
  "builders": {
    "styles": "1.x"
  }
```

2. Create a file called `vtex.product-availability-gallery.css` inside the `styles/css` folder. Add your custom styles:

```css
.container {
  margin-top: 10px;
}
```

#### CSS Namespaces

Below, we describe the namespaces that are defined in the product-availability-gallery.

| Token name                 | Component                                                                                | Description                                                   |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `container`                | [index](https://github.com/vtex-apps/product-availability-gallery/blob/master/react/components/ProductAvailability.tsx) | The main container of `ProductAvailability`                      |
| `lowStockText`          | [index](https://github.com/vtex-apps/product-availability-gallery/blob/master/react/components/LowStock.tsx)    |  Normal text for the low stock message.
| `lowStockHighlight`           | [index](https://github.com/vtex-apps/product-availability-gallery/blob/master/react/components/LowStock.tsx)   |  Number of the low stock message that is supposed to be highlighted.  |
| `highStockText`           | [index](https://github.com/vtex-apps/product-availability-gallery/blob/master/react/components/HighStock.tsx)   | Text of the hight stock message.    |
| `showAvailableText`           | [index](https://github.com/vtex-apps/product-availability-gallery/blob/master/react/components/ShowAvailable.tsx)   | Text of the show available message.    |

## Troubleshooting

You can check if others are passing through similar issues [here](https://github.com/vtex-apps/product-availability-gallery-gallery/issues). Also feel free to [open issues](https://github.com/vtex-apps/product-availability-gallery/issues/new) or contribute with pull requests.

### Travis CI

[![Build Status](https://travis-ci.org/vtex-apps/product-availability-gallery.svg?branch=master)](https://travis-ci.org/vtex-apps/product-availability-gallery)
[![Coverage Status](https://coveralls.io/repos/github/vtex-apps/product-availability-gallery/badge.svg?branch=master)](https://coveralls.io/github/vtex-apps/product-availability-gallery?branch=master)

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

## Contributors ✨

Thanks goes to these wonderful people:
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->

<table>
  <tr>
    <td align="center"><a href="https://github.com/tomymehdi"><img src="https://avatars.githubusercontent.com/u/774112?v=4" width="100px;" alt=""/><br /><sub><b>Tomás Alfredo Mehdi</b></sub></a><br /><a href="https://github.com/vtex-apps/vtex-logger-react/commits?author=tomymehdi" title="Code">💻</a></td>
  </tr>
</table>

<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->

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

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

```


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

[User] Show me the implementation of product-availability-gallery/node/service.json from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 256,
  "ttl": 10,
  "timeout": 5,
  "minReplicas": 2,
  "maxReplicas": 4,
  "workers": 1,
  "routes": {
    "status": {
      "path": "/_v/status/:code/:warehouse",
      "public": true
    },
    "user": {
      "path": "/_v/user/:userId",
      "public": true
    }
  }
}

```


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

[User] Show me the implementation of product-availability-gallery/node/package.json from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "co-body": "^6.0.0",
    "ramda": "^0.25.0"
  },
  "devDependencies": {
    "@types/co-body": "^0.0.3",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.0.0",
    "@types/ramda": "types/npm-ramda#dist",
    "@vtex/api": "6.45.4",
    "@vtex/test-tools": "^1.0.0",
    "@vtex/tsconfig": "^0.5.6",
    "typescript": "3.9.7"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty"
  },
  "version": "0.2.0"
}

```


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

[User] Show me the implementation of product-availability-gallery/node/index.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

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

import { Clients } from './clients'
import { status } from './middlewares/status'
import { user } from './middlewares/user'
import { validate } from './middlewares/validate'

const TIMEOUT_MS = 5000

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

metrics.trackCache('status', memoryCache)

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

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

  // The shape of our State object found in `ctx.state`. This is used as state bag to communicate between middlewares.
  interface State extends RecorderState {
    code: number
    userId: string
    warehouse: string
  }
}

// Export a service that defines route handlers and client options.
export default new Service({
  clients,
  routes: {
    // `status` is the route ID from service.json. It maps to an array of middlewares (or a single handler).
    status: method({
      GET: [validate, status],
    }),
    user: method({
      GET: [validate, user],
    }),
  },
})

```


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

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "node-fetch": "^2.6.1",
    "react": "^17.0.1",
    "react-apollo": "^3.1.5",
    "react-dom": "^17.0.1",
    "react-intl": "^5.12.3"
  },
  "devDependencies": {
    "@apollo/react-testing": "^3.1.4",
    "@types/node-fetch": "^2.5.10",
    "@vtex/api": "6.42.1",
    "@vtex/test-tools": "^3.1.0",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@1.0.0/public/@types/vtex.css-handles",
    "vtex.product-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.product-context@0.9.9/public/@types/vtex.product-context",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.128.4/public/@types/vtex.render-runtime"
  },
  "version": "0.1.0"
}

```


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

[User] Show me the implementation of product-availability-gallery/react/ProductAvailability.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import ProductAvailabilityWrapper from './components/ProductAvailabilityWrapper'

export default ProductAvailabilityWrapper

```


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

[Assistant]
Here's the implementation:

```json
{
  "product-availability-gallery": {
    "component": "ProductAvailability"
  }
}

```


[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 product-availability-gallery/node/clients/status.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

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

export default class Status extends ExternalClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super('https://portal.vtexcommercestable.com.br/api/logistics/pvt/inventory/skus/', context,
    {
      ...options,
      headers: {
        'VtexIdclientAutCookie': `${context.adminUserAuthToken}`,
      },
    })
  }

  public async getStatus(status: number, warehouse: string): Promise<string> {
    return this.http.get( `${status.toString()}?an=${warehouse}`, {
      metric: 'status-get',
    })
  }

  public async getStatusWithHeaders(
    status: number,
    warehouse: string
  ): Promise<IOResponse<string>> {
    return this.http.getRaw(`${status.toString()}?an=${warehouse}`, {
      metric: 'status-get-raw',
    })
  }
}

```


[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 product-availability-gallery/node/clients/additionalDataClient.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

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

export default class AdditionalDataClient extends ExternalClient {

  constructor(context: IOContext, options?: InstanceOptions) {
    super(`http://${context.account}.vtexcommercestable.com.br/api/dataentities/CL/`, context,
    {
      ...options,
      headers: {
        'VtexIdclientAutCookie': context.authToken,
      },
    })

    // console.log(context.authToken)
    // console.log(context.adminUserAuthToken)

  }

  public async get(userId: string) {
    const resp = await this.http.get(`search?_where=userId=${userId}&_fields=_all`)
    // console.log(resp.data)
    return resp
  }
}

```


[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 product-availability-gallery/node/clients/index.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

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

import Status from './status'
import AdditionalDataClient from './additionalDataClient'

// Extend the default IOClients implementation with our own custom clients.
export class Clients extends IOClients {
  public get status() {
    return this.getOrSet('status', Status)
  }
  public get additionalData() {
    return this.getOrSet('additionalDataClient', AdditionalDataClient)
  }
}

```


[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 product-availability-gallery/node/middlewares/status.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function status(ctx: Context, next: () => Promise<any>) {
  const {
    state: { code, warehouse },
    clients: { status: statusClient },
  } = ctx

  // console.info('Received code:', code)
  // console.info('Received ctx:', ctx.state)

  const statusResponse = await statusClient.getStatus(code, warehouse)

  // console.info('Status response:', statusResponse)

  // const {
  //   headers,
  //   data,
  //   status: responseStatus,
  // } = await statusClient.getStatusWithHeaders(code,warehouse)

  // console.info('Status headers', headers)
  // console.info('Status data:', data)

  // ctx.status = responseStatus
  ctx.body = statusResponse
  // ctx.set('Cache-Control', headers['cache-control'])

  await next()
}

```


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

[User] Show me the implementation of product-availability-gallery/node/middlewares/validate.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

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

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

  // console.info('Received params:', params)

  const { code, userId, warehouse } = params

  // if (!code ) {
  //   throw new UserInputError('Code is required') // Wrapper for a Bad Request (400) HTTP Error. Check others in https://github.com/vtex/node-vtex-api/blob/fd6139349de4e68825b1074f1959dd8d0c8f4d5b/src/errors/index.ts
  // }

  const codeNumber = parseInt(code as string, 10)

  ctx.state.code = codeNumber
  // @ts-ignore
  ctx.state.userId = userId
  // @ts-ignore
  ctx.state.warehouse = warehouse

  await next()
}

```


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

[User] Show me the implementation of product-availability-gallery/node/middlewares/user.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function user(ctx: Context, next: () => Promise<any>) {
  const {
    state: { userId },
    clients: { additionalData: additionalDataClient },
  } = ctx

  // console.info('Received userId:', userId)

  const userResponse = await additionalDataClient.get(userId)

  // console.info('user response:', userResponse)

  // const {
  //   headers,
  //   data,
  //   status: responseStatus,
  // } = await statusClient.getStatusWithHeaders(code)

  ctx.body = userResponse
  // ctx.set('Cache-Control', headers['cache-control'])

  await next()
}

```


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

[User] Show me the implementation of product-availability-gallery/react/typings/css.d.ts from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  const css: Record<string, string>
  export default css
}

```


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

[User] Show me the implementation of product-availability-gallery/react/queries/clientAgent.graphql from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```graphql
query clientAgent($mail: String){
  documents(acronym:"CL", fields:"approved", where:$mail) @context(provider: "vtex.store-graphql"){
    id
    fields {
      key
      value
    }
  }
}
```


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

[User] Show me the implementation of product-availability-gallery/react/queries/getBrand.graphql from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Brand($id: Int) {
    brand(id: $id) @context(provider: "vtex.store-graphql") {
        slug
        imageUrl
    }
}
```


[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 product-availability-gallery/react/components/ProductAvailabilityWrapper.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, {useEffect, useState} from 'react'
import {useProduct} from 'vtex.product-context'
import type {ProductTypes} from 'vtex.product-context'
import {useCssHandles} from 'vtex.css-handles'
import type {CssHandlesTypes} from 'vtex.css-handles'
import {defineMessages} from 'react-intl'
import {useFullSession} from 'vtex.session-client'
import ProductAvailability from './ProductAvailability'
import {CssHandlesProvider} from './CssHandlesContext'

const messages = defineMessages({
    title: {
        defaultMessage: 'Product Availability',
        id: 'admin/editor.product-availability.title',
    },
    description: {
        defaultMessage: 'Component that shows the remaining available quantity',
        id: 'admin/editor.product-availability.description',
    },
    thresholdTitle: {
        defaultMessage: 'Threshold quantity',
        id: 'admin/editor.product-availability.threshold.title',
    },
    thresholdDescription: {
        defaultMessage:
            'Minimum quantity that makes low stock message appear (if message is set)',
        id: 'admin/editor.product-availability.threshold.description',
    },
    lowStockMessageTitle: {
        defaultMessage: 'Low stock message',
        id: 'admin/editor.product-availability.lowStockMessage.title',
    },
    lowStockMessageDescription: {
        defaultMessage:
            'String to be shown to user when stock is lower than threshold. Should have {quantity} inside the given string, to be replaced for the threshold property. Example: "Only {quantity} left!". Leave empty to not show.',
        id: 'admin/editor.product-availability.lowStockMessage.description',
    },
    highStockMessageTitle: {
        defaultMessage: 'High stock message',
        id: 'admin/editor.product-availability.highStockMessage.title',
    },
    highStockMessageDescription: {
        defaultMessage:
            "String to be shown when stock is higher or equal than threshold. If left empty, won't show",
        id: 'admin/editor.product-availability.highStockMessage.description',
    },
    showAvailabilityMessageTitle: {
        defaultMessage: 'Show available Message',
        id: 'admin/editor.product-availability.showAvailabilityMessage.title',
    },
    showAvailabilityMessageDescription: {
        defaultMessage: 'String to be shown when show available option is true',
        id: 'admin/editor.product-availability.showAvailabilityMessage.description',
    },
})
const CONTAINER_CSS_HANDLES = ['container'] as const
const LOW_STOCK_CSS_HANDLES = ['lowStockText', 'lowStockHighlight'] as const
const HIGH_STOCK_CSS_HANDLES = ['highStockText'] as const
const SHOW_AVAILABLE_CSS_HANDLES = ['showAvailableText'] as const
export const CSS_HANDLES = [
    ...CONTAINER_CSS_HANDLES,
    ...LOW_STOCK_CSS_HANDLES,
    ...HIGH_STOCK_CSS_HANDLES,
    ...SHOW_AVAILABLE_CSS_HANDLES,
] as const
export function getFirstAvailableSeller(sellers?: ProductTypes.Seller[]) {
    if (!sellers || sellers.length === 0) {
        return
    }
    const availableSeller = sellers.find(
        seller => seller.commertialOffer.AvailableQuantity !== 0
    )
    return availableSeller
}
interface Props {
    threshold: number
    lowStockMessage?: string
    highStockMessage?: string
    showAvailability?: boolean
    showAvailabilityMessage?: string
    classes?: CssHandlesTypes.CustomClasses<typeof CONTAINER_CSS_HANDLES &
        (
            | typeof LOW_STOCK_CSS_HANDLES
            | typeof HIGH_STOCK_CSS_HANDLES
            | typeof SHOW_AVAILABLE_CSS_HANDLES
            )>
}
interface Balance {
    totalQuantity: number;
    reservedQuantity: number;
}
function ProductAvailabilityWrapper({
                                        threshold = 0,
                                        lowStockMessage,
                                        highStockMessage,
                                        showAvailability,
                                        showAvailabilityMessage,
                                        classes,
                                    }: Props) {
    const {handles, withModifiers} = useCssHandles(CSS_HANDLES, {classes})
    const productContextValue = useProduct()
    const session = useFullSession()
    const [userId, setUserId] = useState<string>('');
    const [warehouse, setWarehouse] = useState<string>('');
    const [isSeller, setIsSeller] = useState<boolean>(false);
    const [clientId, setClientId] = useState<string>('');
    const seller = getFirstAvailableSeller(
        productContextValue?.selectedItem?.sellers
    )
    const prodId = productContextValue?.selectedItem?.itemId;
    const [balance, setBalance] = useState<Balance>({totalQuantity: 0, reservedQuantity: 0})
    const getData = () => {
        fetch(`https://${window.location.hostname}/_v/status/${prodId}/${warehouse}`,
            {
                credentials: 'include'
            })
            .then(response => response.json())
            .then(json => {
                setBalance(json.balance[0])
            })
    }
    const getUser = () => {
        fetch(`https://${window.location.hostname}/_v/user/${userId}`,
            {
                credentials: 'include'
            })
            .then(response => response.json())
            // eslint-disable-next-line no-console
            .then(user => {
                if (user[0].agente === "VE" || user[0].agente === "VC" || user[0].agente === "CO") {
                    fetch(`https://${window.location.hostname}/_v/user/${clientId}`,
                        {
                            credentials: 'include'
                        })
                        .then(response => {
                            return response.json()
                        })
                        .then(client => {
                            setWarehouse(client[0].sucursal)
                            setIsSeller(true);
                        })
                }
            })
    }
    useEffect(() => {
        if (typeof window !== "undefined") {
            setClientId(session?.data?.session?.namespaces?.profile?.id?.value)
            setUserId(session?.data?.session?.namespaces?.authentication?.storeUserId?.value)
        }
    }, [session])
    useEffect(() => {
        if(userId) {
            getUser()
        }
    }, [userId])
    useEffect(() => {
        if(userId) {
            getData()
        }
    }, [warehouse, productContextValue])
    if (!productContextValue) {
        return null
    }
    return (
        <div>
            <CssHandlesProvider handles={handles} withModifiers={withModifiers}>
                <ProductAvailability
                    threshold={threshold}
                    lowStockMessage={lowStockMessage}
                    highStockMessage={highStockMessage}
                    showAvailability={isSeller ? showAvailability : false}
                    showAvailabilityMessage={showAvailabilityMessage}
                    balance={balance}
                />
            </CssHandlesProvider>
        </div>
    )
}
ProductAvailabilityWrapper.schema = {
    title: messages.title.id,
    description: messages.description.id,
    type: 'object',
    properties: {
        threshold: {
            title: messages.thresholdTitle.id,
            description: messages.thresholdDescription.id,
            type: 'number',
            default: 0,
            isLayout: true,
        },
        lowStockMessage: {
            title: messages.lowStockMessageTitle.id,
            description: messages.lowStockMessageDescription.id,
            type: 'string',
        },
        highStockMessage: {
            title: messages.highStockMessageTitle.id,
            description: messages.highStockMessageDescription.id,
            type: 'string',
        },
        showAvailabilityMessage: {
            title: messages.showAvailabilityMessageTitle.id,
            description: messages.showAvailabilityMessageDescription.id,
            type: 'string',
        },
    },
}
export default ProductAvailabilityWrapper
```


[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 product-availability-gallery/react/components/LowStock.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment } from 'react'

import { useContextCssHandles } from './CssHandlesContext'

interface Props {
  text: string
  availableQuantity: number
}

function LowStock({ text, availableQuantity }: Props) {
  const { handles } = useContextCssHandles()
  const [before, after] = text.split('{quantity}')

  return (
    <Fragment>
      {before && (
        <span className={`${handles.lowStockText} c-muted-2 t-body`}>
          {before}
        </span>
      )}
      {availableQuantity && (
        <span className={`${handles.lowStockHighlight} c-muted-2 t-body b mh1`}>
          {availableQuantity}
        </span>
      )}
      {after && (
        <span className={`${handles.lowStockText} c-muted-2 t-body`}>
          {after}
        </span>
      )}
    </Fragment>
  )
}

export default LowStock

```


[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 product-availability-gallery/react/components/CssHandlesContext.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { createCssHandlesContext } from 'vtex.css-handles'

import { CSS_HANDLES } from './ProductAvailabilityWrapper'

const { CssHandlesProvider, useContextCssHandles } = createCssHandlesContext(
  CSS_HANDLES
)

export { CssHandlesProvider, useContextCssHandles }

```


[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 product-availability-gallery/react/components/Container.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import type { PropsWithChildren } from 'react'

import { useContextCssHandles } from './CssHandlesContext'

function Container({ children }: PropsWithChildren<unknown>) {
  const { handles } = useContextCssHandles()

  return <div className={`${handles.container} flex pv2`}>{children}</div>
}

export default Container

```


[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 product-availability-gallery/react/components/ShowAvailable.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

import { useContextCssHandles } from './CssHandlesContext'

interface Props {
  showAvailabilityMessage?: string
  availableQuantity: number
}

function HighStock({ showAvailabilityMessage, availableQuantity }: Props) {
  const { handles } = useContextCssHandles()

  return (
    <span className={`${handles.showAvailableText} c-muted-2 t-body b mh1`}>
      {showAvailabilityMessage} {availableQuantity}
    </span>
  )
}

export default HighStock

```


[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 product-availability-gallery/react/components/HighStock.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

import { useContextCssHandles } from './CssHandlesContext'

interface Props {
  text: string
}

function HighStock({ text }: Props) {
  const { handles } = useContextCssHandles()

  return (
    <span className={`${handles.highStockText} c-muted-2 t-body`}>{text}</span>
  )
}

export default HighStock

```


[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 product-availability-gallery/react/components/ProductAvailability.tsx from the product-availability-gallery VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { memo } from 'react'

import LowStock from './LowStock'
import HighStock from './HighStock'
import ShowAvailable from './ShowAvailable'
import Container from './Container'

interface Props {
  threshold: number
  lowStockMessage?: string
  highStockMessage?: string
  showAvailability?: boolean
  showAvailabilityMessage?: string
  balance?: any
}

function ProductAvailability({
  threshold,
  lowStockMessage,
  highStockMessage,
  showAvailability,
  showAvailabilityMessage,
  balance,
}: Props) {
  const availableQuantity = balance.totalQuantity - balance.reservedQuantity ?? 0
  if (!availableQuantity || availableQuantity < 1) {
    return null
  }

  const isLowStock = availableQuantity < threshold

  if (!showAvailability) {
    if (isLowStock && lowStockMessage) {
      return (
        <Container>
          <LowStock
            text={lowStockMessage}
            availableQuantity={availableQuantity}
          />
        </Container>
      )
    }

    if (!isLowStock && highStockMessage) {
      return <HighStock text={highStockMessage} />
    }

    return null
  }

  return (
    <Container>
      <ShowAvailable
        showAvailabilityMessage={showAvailabilityMessage}
        availableQuantity={availableQuantity}
      />
    </Container>
  )
}

export default memo(ProductAvailability)

```


[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 livestreaming-utils/react/useLivestreaming.tsx from the livestreaming-utils VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useContext } from 'react'

import { LivestreamingContext } from './LivestreamingContextProvider'

export const useLivestreaming = () => {
  return useContext(LivestreamingContext)
}

export default useLivestreaming

```


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

[Assistant]
Here's the implementation:

```json
{
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "lint": "tsc --noEmit && eslint --quiet --fix --ext ts,tsx ."
  },
  "resolutions": {
    "@types/react": "17.0.48",
    "@types/react-dom": "17.0.17"
  },
  "dependencies": {
    "@nizza/player": "3.0.0-alpha.0",
    "@types/react": "17.0.48",
    "@types/react-dom": "17.0.17",
    "react": "^17.x",
    "react-dom": "^17.x"
  },
  "devDependencies": {
    "@types/node": "18.11.10",
    "@vtex/tsconfig": "^0.6.0",
    "typescript": "3.9.7"
  }
}

```


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

[User] Show me the implementation of livestreaming-utils/react/LivestreamingContextProvider.tsx from the livestreaming-utils VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { AddToCartConfig } from '@nizza/player'
import type { FC } from 'react'
import React, { createContext, useMemo } from 'react'

export interface LivestreamingProps {
  addToCartConfig?: AddToCartConfig
}

export const LivestreamingContext = createContext<LivestreamingProps>({
  addToCartConfig: {},
})

LivestreamingContext.displayName = 'LivestreamingContext'

export interface LivestreamingProviderProps {
  value: LivestreamingProps
}

const LivestreamingProvider: FC<LivestreamingProviderProps> = ({
  value = {},
  children,
}) => {
  const context = useMemo(() => value, [value])

  return (
    <LivestreamingContext.Provider value={context}>
      {children}
    </LivestreamingContext.Provider>
  )
}

LivestreamingProvider.displayName = 'LivestreamingConfigProvider'

export default LivestreamingProvider

```


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

[Assistant]
Here's the implementation:

```json
{
  "livestreaming-context": {
    "component": "LivestreamingContextProvider",
    "composition": "children",
    "allowed": "*"
  }
}

```


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

[Assistant]
Here's the implementation:

```markdown
# Zopim

VTEX Zopim first-party app

## How to install

Open the VTEX App Store and install this app on your store.

Now, open the app settings on your admin and fill in your Zopim's Account Key.

```


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

[User] Show me the implementation of b2b-approved-message/messages/pt.json from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Sua organização não foi aprovada para fazer pedidos nesta loja no momento. Se já está assim há algum tempo e você acha que isso é um erro, entre em contato conosco."
}

```


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

[User] Show me the implementation of b2b-approved-message/messages/en.json from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Your organization is not approved to place orders on this store right now. If it’s been like this for a while and you think this is a mistake, please contact us."
}

```


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

[User] Show me the implementation of b2b-approved-message/messages/es.json from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/b2b-approved-message.message": "Su organización no está aprobada para realizar pedidos en esta tienda en este momento. Si ha sido así por un tiempo y cree que es un error, comuníquese con nosotros."
}

```


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

[User] Show me the implementation of b2b-approved-message/docs/README.md from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

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

# B2B Approved Message

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

App responsible for  display a message if user is not approved in supplier

## Configuration

In this section, you first must **add the primary instructions** that will allow users to use the app's blocks in their store, such as:

1. Adding the app as a theme dependency in the `manifest.json` file;
2. Declaring the app's main block in a given theme template or inside another block from the theme.

## Customization

No CSS Handles are available yet for the app customization.

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

## Contributors ✨

Thanks goes to these wonderful people:

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

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

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

----

Check out some documentation models that are already live:
- [Breadcrumb](https://github.com/vtex-apps/breadcrumb)
- [Image](https://vtex.io/docs/components/general/vtex.store-components/image)
- [Condition Layout](https://vtex.io/docs/components/all/vtex.condition-layout@1.1.6/)
- [Add To Cart Button](https://vtex.io/docs/components/content-blocks/vtex.add-to-cart-button@0.9.0/)
- [Store Form](https://vtex.io/docs/components/all/vtex.store-form@0.3.4/)

```


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

[User] Show me the implementation of b2b-approved-message/react/ApprovedMessage.test.tsx from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

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

import ApprovedMessage from './Greeting'

test('greets Fred', () => {
  const { queryByText } = render(<ApprovedMessage name="Fred" />)

  expect(queryByText('Hey, Fred')).toBeInTheDocument()
})

```


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

[User] Show me the implementation of b2b-approved-message/react/ApprovedMessage.tsx from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { Alert } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'

import { isApproved, isLoggedIn, useSession } from './session'

const ApprovedMessage = () => {
  const [show, setShow] = React.useState(true)
  const session = useSession()

  if (!show) return null

  if (!isLoggedIn(session)) return null

  if (isApproved(session)) return null

  return (
    <div className="relative">
      <div className="mw8 tc absolute center top-0 left-0 right-0 z-1">
        <Alert type="warning" onClose={() => setShow(false)}>
          <FormattedMessage id="store/b2b-approved-message.message" />
          <span />
        </Alert>
      </div>
    </div>
  )
}

export default ApprovedMessage

```


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

[User] Show me the implementation of b2b-approved-message/react/session.ts from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  Session,
  SessionPromise,
  SessionResponse,
} from 'vtex.render-runtime'
import React from 'react'

const NOT_APPROVED_TRADE_POLICY = '5'

declare global {
  interface Window {
    __RENDER_8_SESSION__?: {
      sessionPromise?: Promise<SessionPromise>
    }
  }
}

export function getSession() {
  return window?.__RENDER_8_SESSION__?.sessionPromise ?? null
}

export const useSession = () => {
  const [session, setSession] = React.useState<SessionResponse>()

  React.useEffect(() => {
    ;(async () => {
      const sessionPromise = getSession()

      if (!sessionPromise) return

      const { response } = await sessionPromise

      setSession(response)
    })()
  }, [])

  return session
}

export const isLoggedIn = (session: SessionResponse | undefined): boolean =>
  !!(session as Session)?.namespaces?.profile?.email

export const isApproved = (session: SessionResponse | undefined): boolean => {
  const tradePolicy = (session as Session)?.namespaces?.store?.channel?.value

  if (!tradePolicy) return false

  return tradePolicy !== NOT_APPROVED_TRADE_POLICY
}

```


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

[User] Show me the implementation of b2b-approved-message/react/package.json from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "CHANGE_ME",
  "version": "0.1.0",
  "scripts": {
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "apollo-client": "^2.6.8",
    "react": "^16.12.0",
    "react-apollo": "^3.1.3",
    "react-dom": "^16.12.0",
    "react-intl": "^3.12.0"
  },
  "devDependencies": {
    "@apollo/react-testing": "^3.1.3",
    "@types/jest": "^25.1.4",
    "@types/node": "^13.9.8",
    "@types/react": "^16.9.31",
    "@vtex/test-tools": "^3.3.2",
    "@vtex/tsconfig": "^0.4.4",
    "apollo-cache-inmemory": "^1.6.5",
    "graphql": "^14.6.0",
    "typescript": "3.9.7",
    "vtex.b2b-approved-message": "https://gsasouza--b2bstore.myvtex.com/_v/private/typings/linked/v1/vtex.b2b-approved-message@0.0.0+build1626376459/public/@types/vtex.b2b-approved-message",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.130.0/public/@types/vtex.render-runtime",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.145.0/public/@types/vtex.styleguide"
  }
}

```


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

[User] Show me the implementation of b2b-approved-message/store/interfaces.json from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "b2b-approved-message": {
    "component": "ApprovedMessage"
  }
}

```


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

[User] Show me the implementation of b2b-approved-message/react/typings/vtex.render-runtime.d.ts from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

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

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

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

  interface ExtensionPointProps {
    id: string

    [key: string]: any
  }

  interface ChildBlock<BlockProps> {
    props: BlockProps
  }

  export const ExtensionPoint: ComponentType<ExtensionPointProps>
  export const useChildBlock: <BlockProps>({
    id,
  }: {
    id: string
  }) => ChildBlock<BlockProps> | null
  export const Helmet: ReactElement
  export const Link: ReactType
  export const NoSSR: ReactElement
  export const RenderContextConsumer: unknown
  export const TreePathContextConsumer: unknown
  export const useTreePath: unknown
  export const useRuntime: unknown
  export const canUseDOM: boolean
  export const withRuntimeContext: <
    TOriginalProps extends Record<string, unknown>
  >(
    Component: ComponentType<TOriginalProps & RenderContextProps>
  ) => ComponentType<TOriginalProps>

  export const withSession: <TOriginalProps extends {}>(
    Component: ComponentType<TOriginalProps & RenderContextProps>
  ) => ComponentType<TOriginalProps>

  interface KeyValue {
    value: string
  }

  interface Session {
    id: string
    namespaces: {
      store: {
        channel: KeyValue
      }
      profile: {
        isAuthenticated: KeyValue
        email: string
      }
    }
  }

  interface SessionUnauthorized {
    type: 'Unauthorized'
    message: string
  }

  interface SessionForbidden {
    type: 'Forbidden'
    message: string
  }

  type SessionResponse = Session | SessionUnauthorized | SessionForbidden

  export interface RenderSession {
    sessionPromise: Promise<SessionPromise>
  }

  export interface SessionPromise {
    response: Session | SessionUnauthorized | SessionForbidden
  }
}

```


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

[User] Show me the implementation of b2b-approved-message/react/typings/gql.d.ts from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

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

  const Schema: DocumentNode

  export default Schema
}

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

  const schema: DocumentNode

  export default Schema
}

```


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

[User] Show me the implementation of b2b-approved-message/react/typings/css.d.ts from the b2b-approved-message VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  type Styles = {
    [selector: string]: string
  }

  const styles: Styles

  export default styles
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "admin/tracking.title": "",
  "admin/tracking.last-schedule.label": "",
  "admin/tracking.next-schedule.label": "",
  "admin/tracking.settings.tab.label": "",
  "admin/tracking.schedule.label": "",
  "admin/tracking.active.label": "",
  "admin/tracking.inactive.label": "",
  "admin/carrier.title": "",
  "admin/carrier.save.label": "",
  "admin/carrier.canadapost.label": "",
  "admin/carrier.canadapost.id.label": "",
  "admin/carrier.canadapost.password.label": "",
  "admin/carrier.fedex.label": "",
  "admin/carrier.fedex.key.label": "",
  "admin/carrier.fedex.account-number.label": "",
  "admin/carrier.fedex.meter-number.label": "",
  "admin/carrier.fedex.password.label": "",
  "admin/carrier.ups.label": "",
  "admin/carrier.ups.key.label": "",
  "admin/carrier.usps.label": "",
  "admin/carrier.usps.userID.label": ""
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "admin/tracking.title": "Shipment Tracker",
  "admin/tracking.last-schedule.label": "Last Schedule Run:",
  "admin/tracking.next-schedule.label": "Next Schedule Run:",
  "admin/tracking.settings.tab.label": "Settings",
  "admin/tracking.schedule.label": "Update Schedule",
  "admin/tracking.active.label": "Active",
  "admin/tracking.inactive.label": "Inactive",
  "admin/carrier.title": "Carrier",
  "admin/carrier.save.label": "Save",
  "admin/carrier.canadapost.label": "Canada Post",
  "admin/carrier.canadapost.id.label": "User Id",
  "admin/carrier.canadapost.password.label": "Account Password",
  "admin/carrier.fedex.label": "Fedex",
  "admin/carrier.fedex.key.label": "Key",
  "admin/carrier.fedex.account-number.label": "Account Number",
  "admin/carrier.fedex.meter-number.label": "Meter Number",
  "admin/carrier.fedex.password.label": "Password",
  "admin/carrier.ups.label": "UPS",
  "admin/carrier.ups.key.label": "Key",
  "admin/carrier.usps.label": "USPS",
  "admin/carrier.usps.userID.label": "User ID"
}

```


[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 shipment-tracker/messages/context.json from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin/tracking.title": "admin/tracking.title",
  "admin/tracking.last-schedule.label": "admin/tracking.last-schedule.label",
  "admin/tracking.next-schedule.label": "admin/tracking.next-schedule.label",
  "admin/tracking.settings.tab.label": "admin/tracking.settings.tab.label",
  "admin/tracking.schedule.label": "admin/tracking.schedule.label",
  "admin/tracking.active.label": "admin/tracking.active.label",
  "admin/tracking.inactive.label": "admin/tracking.inactive.label",
  "admin/carrier.title": "admin/carrier.title",
  "admin/carrier.save.label": "admin/carrier.save.label",
  "admin/carrier.canadapost.label": "admin/carrier.canadapost.label",
  "admin/carrier.canadapost.id.label": "admin/carrier.canadapost.id.label",
  "admin/carrier.canadapost.password.label": "admin/carrier.canadapost.password.label",
  "admin/carrier.fedex.label": "admin/carrier.fedex.label",
  "admin/carrier.fedex.key.label": "admin/carrier.fedex.key.label",
  "admin/carrier.fedex.account-number.label": "admin/carrier.fedex.account-number.label",
  "admin/carrier.fedex.meter-number.label": "admin/carrier.fedex.meter-number.label",
  "admin/carrier.fedex.password.label": "admin/carrier.fedex.password.label",
  "admin/carrier.ups.label": "admin/carrier.ups.label",
  "admin/carrier.ups.key.label": "admin/carrier.ups.key.label",
  "admin/carrier.usps.label": "admin/carrier.usps.label",
  "admin/carrier.usps.userID.label": "admin/carrier.usps.userID.label"
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "admin/tracking.title": "",
  "admin/tracking.last-schedule.label": "",
  "admin/tracking.next-schedule.label": "",
  "admin/tracking.settings.tab.label": "",
  "admin/tracking.schedule.label": "",
  "admin/tracking.active.label": "",
  "admin/tracking.inactive.label": "",
  "admin/carrier.title": "",
  "admin/carrier.save.label": "",
  "admin/carrier.canadapost.label": "",
  "admin/carrier.canadapost.id.label": "",
  "admin/carrier.canadapost.password.label": "",
  "admin/carrier.fedex.label": "",
  "admin/carrier.fedex.key.label": "",
  "admin/carrier.fedex.account-number.label": "",
  "admin/carrier.fedex.meter-number.label": "",
  "admin/carrier.fedex.password.label": "",
  "admin/carrier.ups.label": "",
  "admin/carrier.ups.key.label": "",
  "admin/carrier.usps.label": "",
  "admin/carrier.usps.userID.label": ""
}

```


[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 shipment-tracker/admin/navigation.json from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "section": "orders",
  "titleId": "admin-example.navigation.label-group",
  "path": "/admin/shipping-tracker"
}

```


[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 shipment-tracker/admin/routes.json from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin.app.shipping-tracker": {
    "component": "Admin",
    "path": "/admin/app/shipping-tracker"
  }
}

```


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

[Assistant]
Here's the implementation:

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

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

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

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

# Shipment Tracker

Shipment Tracker is a VTEX IO native solution that allows stores to provide built in shipment tracking for their customers. The carriers supported currently are USPS, UPS, Fedex, and Canada Post. Updates can be seen in the orders page, along with email updates being sent out to the customer.

## Configuration
### Step 1 Installing the Shipment Tracker app

Using your terminal, log in to the desired VTEX account and run the following command:

`vtex install vtex.shipment-tracker@0.x`

### Step 2 - Adding in Carriers

1. In the admin page, scroll down to the carriers section. Currently, the app is configured to provide tracking information for USPS, UPS, FedEx, and Canada Post
2. For the carrier(s) you would like to use, fill in the required fields such as user ID, password, etc. This can be found on the carrier websites, after creating an account and requesting developer access.

## Modus Operandi

The app may be configured to use a **scheduler** where an administrator is responsible for activating regular database updates.

To activate the scheduler, simply toggle the switch in the admin panel.

## Customization

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

```


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

[Assistant]
Here's the implementation:

```graphql
type Query {
  config: Config @cacheControl(scope: PRIVATE)
  allShipments: [Shipment] @cacheControl(scope: PRIVATE, maxAge: Short)
  shipmentsByCarrier(carrier: String): [Shipment]
    @cacheControl(scope: PRIVATE, maxAge: Short)
  interactions(shipmentId: String): [Interaction]
    @cacheControl(scope: PRIVATE, maxAge: Medium)
  shipment(id: String): Shipment @cacheControl(scope: PRIVATE, maxAge: Medium)
  viewSchedule: ViewSchedule @cacheControl(scope: PRIVATE)
}

type Mutation {
  addShipment(
    trackingNumber: String
    carrier: String
    delivered: Boolean
    orderId: String
    invoiceId: String
    externalLink: String
  ): String
  updateShipment(
    id: String
    trackingNumber: String
    carrier: String
    delivered: Boolean
    orderId: String
    invoiceId: String
    externalLink: String
    lastInteractionDate: String
  ): String
  addInteraction(
    shipmentId: String
    interaction: String
    delivered: Boolean
  ): String
  createSchedule: Schedule
  deleteSchedule: Boolean
}

type Config {
  schema: Boolean
  title: String
}

type Shipment {
  id: String
  trackingNumber: String
  carrier: String
  delivered: Boolean
  orderId: String
  invoiceId: String
  externalLink: String
  createdIn: String
  lastInteractionDate: String
}

type Interaction {
  id: String
  shipmentId: String
  interaction: String
  delivered: Boolean
  createdIn: String
  updatedIn: String
}

type Schedule {
  nextExecution: String
}

type ViewSchedule {
  lastInteractionIn: String
  nextExecution: String
}

```


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

[User] Show me the implementation of shipment-tracker/node/service.json from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "stack": "nodejs",
  "memory": 1536,
  "ttl": 30,
  "timeout": 12,
  "minReplicas": 15,
  "maxReplicas": 100,
  "workers": 1,
  "routes": {
    "updateTracking": {
      "path": "/_v/api/tracking/update",
      "public": true
    }
  },
  "events": {
    "orderStatusChange": {
      "sender": "vtex.orders-broadcast",
      "topics": ["invoiced"]
    }
  }
}

```


[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 shipment-tracker/node/featureFlags.ts from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const flags = {
  VTEX_ASSETS_URL: false,
}

```


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

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

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.search-graphql",
  "scripts": {
    "lint": "tsc --noEmit && eslint --ext ts .",
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "@gocommerce/utils": "^0.6.11",
    "atob": "^2.1.2",
    "axios": "^0.19.0",
    "camelcase": "^5.0.0",
    "cookie": "^0.3.1",
    "graphql": "^14.5.8",
    "graphql-tools": "^4.0.6",
    "qs": "^6.6.0",
    "querystring": "^0.2.0",
    "ramda": "^0.26.1",
    "slugify": "^1.2.6",
    "typescript": "3.9.7",
    "xml2js": "^0.4.23"
  },
  "devDependencies": {
    "@types/atob": "^2.1.2",
    "@types/camelcase": "^4.1.0",
    "@types/cookie": "^0.3.2",
    "@types/es6-shim": "^0.31.32",
    "@types/graphql": "^14.5.0",
    "@types/jest": "^24.0.18",
    "@types/koa": "^2.0.46",
    "@types/node": "^12.0.0",
    "@types/qs": "^6.5.1",
    "@types/ramda": "^0.26.21",
    "@types/xml2js": "^0.4.8",
    "@vtex/api": "6.39.1",
    "@vtex/test-tools": "^1.2.0",
    "@vtex/tsconfig": "^0.2.0",
    "eslint": "^6.8.0",
    "eslint-config-vtex": "^12.1.1",
    "prettier": "^1.16.4",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@0.4.4/public/@types/vtex.css-handles",
    "vtex.product-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.product-context@0.9.7/public/@types/vtex.product-context",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@7.42.0/public/@types/vtex.render-runtime",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.134.1/public/@types/vtex.styleguide"
  },
  "version": "3.1.2"
}

```


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

[User] Show me the implementation of shipment-tracker/node/constants.ts from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const CARRIERS = {
  UPS: 'UPS',
  USPS: 'USPS',
  FEDEX: 'FEDEX',
  CANADAPOST: 'CANADAPOST',
} as const

export type Carrier = typeof CARRIERS[keyof typeof CARRIERS]

```


[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 shipment-tracker/node/index.ts from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

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

import { Clients } from './clients'
import { resolvers } from './resolvers'
import { orderStatusChange } from './events/orderStatusChange'
import { updateTracking } from './routes/updateTracking'

const TIMEOUT_MS = 800

const clients: ClientsConfig<Clients> = {
  implementation: Clients,
  options: {
    default: {
      retries: 2,
      timeout: TIMEOUT_MS,
    },
  },
}
declare global {
  // We declare a global Context type just to avoid re-writing ServiceContext<Clients, State> in every handler and resolver
  type Context = ServiceContext<Clients>

  interface StatusChangeContext extends EventContext<Clients> {
    body: {
      domain: string
      orderId: string
      currentState: string
      lastState: string
      currentChangeDate: string
      lastChangeDate: string
    }
  }
  type State = RecorderState
}

export default new Service<Clients, RecorderState, ParamsContext>({
  clients,
  graphql: {
    resolvers,
  },
  events: {
    orderStatusChange,
  },
  routes: {
    updateTracking,
  },
})

```


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

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.admin-example",
  "version": "0.0.1",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "@types/node": "^11.12.1",
    "@types/react": "^16.8.10",
    "@types/react-intl": "^2.3.17",
    "apollo-client": "^2.4.7",
    "graphql": "^14.0.2",
    "prop-types": "^15.7.2",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-intl": "^2.7.2",
    "typescript": "3.9.7",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.126.11/public/@types/vtex.render-runtime",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.135.1/public/@types/vtex.styleguide"
  },
  "dependencies": {
    "react-apollo": "^3.1.5"
  }
}

```


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

[User] Show me the implementation of shipment-tracker/react/styles.global.css from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

```css
html,
body,
#render-container,
#render-provider,
.render-container,
.render-provider {
  height: 100%;
}

```


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

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

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useEffect, useState } from 'react'
import { useMutation, useQuery } from 'react-apollo'
import { injectIntl, defineMessages } from 'react-intl'
import {
  Layout,
  PageBlock,
  PageHeader,
  Toggle,
  Tabs,
  Tab,
} from 'vtex.styleguide'

import ViewSchedule from './queries/viewSchedule.gql'
import DeleteSchedule from './queries/deleteSchedule.gql'
import CreateSchedule from './queries/createSchedule.gql'
import Carriers from './components/Carriers'

import './styles.global.css'

const AdminExample: FC<any> = ({ intl }) => {
  const messages = defineMessages({
    title: {
      id: 'admin/tracking.title',
      defaultMessage: 'Shipment Tracker',
    },
    settingsTab: {
      id: 'admin/tracking.settings.tab.label',
      defaultMessage: 'Settings',
    },
    scheduleLabel: {
      id: 'admin/tracking.schedule.label',
      defaultMessage: 'Update Schedule',
    },
    lastSchedule: {
      id: 'admin/tracking.last-schedule.label',
      defaultMessage: 'Last Schedule Run:',
    },
    nextSchedule: {
      id: 'admin/tracking.next-schedule.label',
      defaultMessage: 'Next Schedule Run:',
    },
    active: {
      id: 'admin/tracking.active.label',
      defaultMessage: 'Active',
    },
    inactive: {
      id: 'admin/tracking.inactive.label',
      defaultMessage: 'Inactive',
    },
  })
  const [activeTab, setActiveTab] = useState<number>(1)
  const [schedule, setSchedule] = useState<null | Schedule>(null)
  const [
    deleteSchedule,
    { loading: deleteLoading, data: deleteResponse },
  ] = useMutation(DeleteSchedule)
  const [
    createSchedule,
    { loading: createLoading, data: createResponse },
  ] = useMutation<ScheduleCreateResponse>(CreateSchedule)
  const {
    data: scheduleData,
    loading: viewLoading,
    called: viewCalled,
  } = useQuery<ScheduleViewResponse>(ViewSchedule)

  useEffect(() => {
    if (scheduleData?.viewSchedule) {
      setSchedule(scheduleData.viewSchedule)
    } else {
      setSchedule(null)
    }
  }, [scheduleData])

  useEffect(() => {
    if (deleteResponse) {
      setSchedule(null)
    }
  }, [deleteResponse])

  useEffect(() => {
    if (createResponse?.createSchedule) {
      setSchedule(createResponse.createSchedule)
    }
  }, [createResponse])

  const handleChange = () => {
    if (schedule) {
      return deleteSchedule()
    }

    return createSchedule()
  }

  if (!viewCalled || viewLoading) {
    return null
  }

  return (
    <Layout
      pageHeader={<PageHeader title={intl.formatMessage(messages.title)} />}
    >
      <Tabs fullWidth>
        <Tab
          label={intl.formatMessage(messages.settingsTab)}
          active={activeTab === 1}
          onClick={() => setActiveTab(1)}
        >
          <div className="mt5" />
          <PageBlock
            title={intl.formatMessage(messages.scheduleLabel)}
            variation="full"
          >
            <div className="flex justify-between">
              <div>
                <div className="flex">
                  <div className="mr4">
                    {intl.formatMessage(messages.lastSchedule)}
                  </div>
                  {`${
                    schedule?.lastInteractionIn
                      ? schedule.lastInteractionIn
                      : '-'
                  }`}
                </div>
                <div className="flex mt3">
                  <div className="mr4">
                    {intl.formatMessage(messages.nextSchedule)}
                  </div>
                  {`${schedule ? schedule.nextExecution : '-'}`}
                </div>
              </div>
              <div className="flex items-center">
                <div className={'w4'}>
                  <Toggle
                    label={
                      schedule
                        ? intl.formatMessage(messages.active)
                        : intl.formatMessage(messages.inactive)
                    }
                    semantic
                    size="large"
                    checked={schedule?.nextExecution}
                    onChange={() => handleChange()}
                  />
                </div>
              </div>
            </div>
          </PageBlock>
          <Carriers />
        </Tab>
      </Tabs>
    </Layout>
  )
}

export default injectIntl(AdminExample)

```


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

[Assistant]
Here's the implementation:

```json
{
  "shipping-tracker": {
    "component": "Admin"
  }
}

```


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

[User] Show me the implementation of shipment-tracker/node/clients/canadaPost.ts from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

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

export default class CanadaPostClient extends ExternalClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    // production - soa-gw.canadapost.ca
    super('http://soa-gw.canadapost.ca', context, {
      ...options,
      headers: {
        'X-Vtex-Use-Https': 'true',
        'Proxy-Authorization': context.authToken,
      },
    })
  }

  public async getTracking(
    trackingNumber: string,
    key: string
    // vtexAppKey: string,
    // vtexAppToken: string
  ): Promise<string> {
    return this.http.get(`/vis/track/pin/${trackingNumber}/detail`, {
      headers: {
        // 'X-VTEX-API-AppKey': vtexAppKey,
        // 'X-VTEX-API-AppToken': vtexAppToken,
        'Authorization': `Basic ${key}`,
        'Accept-language': 'en-CA',
        'Accept': 'application/vnd.cpc.track-v2+xml'
      },
    })
  }
}

```


[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 shipment-tracker/node/clients/scheduler.ts from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

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

const routes = {
  scheduler: (workspace: string, account: string) =>
    `/api/scheduler/${workspace}/${account}?version=4`,
  getSchedule: (workspace: string, account: string) =>
    `/api/scheduler/${workspace}/${account}/vtex-shipping-tracker?version=4`,
}

export default class SchedulerClient extends JanusClient {
  constructor(ctx: IOContext, options?: InstanceOptions) {
    super(ctx, {
      ...options,
      headers: {
        ...options?.headers,
        VtexIdclientAutCookie: ctx.authToken,
      },
    })
  }

  public createSchedule = (
    schedulerData: CreateSchedulerArgs
  ): Promise<CreateSchedulerResponse> => {
    return this.http.post(
      routes.scheduler(this.context.workspace, this.context.account),
      schedulerData,
      { metric: 'scheduler-create-schedule' }
    )
  }

  public viewSchedule = async (): Promise<ViewSchedulerResponse> => {
    return this.http.get(
      routes.getSchedule(this.context.workspace, this.context.account),
      { metric: 'scheduler-view-schedule' }
    )
  }

  public deleteSchedule = async () => {
    return this.http.delete(
      routes.getSchedule(this.context.workspace, this.context.account),
      { metric: 'scheduler-delete-schedule' }
    )
  }
}

```


[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 shipment-tracker/node/clients/ups.ts from the shipment-tracker VTEX app.

[Assistant]
Here's the implementation:

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

export default class UPSClient extends ExternalClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super('https://wwwcie.ups.com', context, {
      ...options,
      headers: {
        'X-Vtex-Use-Https': 'true',
        'Proxy-Authorization': context.authToken,
      },
    })
  }

  public async getTracking(
    trackingNumber: string,
    key: string
  ): Promise<string> {
    return this.http.get(`/track/v1/details/${trackingNumber}`, {
      headers: {
        AccessLicenseNumber: key,
      },
    })
  }
}

```