[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 place-components/react/AddressForm.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import classnames from 'classnames'
import React, { useState, useMemo, useRef } from 'react'
import { Input, Dropdown } from 'vtex.styleguide'
import { DisplayDefinition } from 'vtex.country-data-settings'
import { useAddressContext } from 'vtex.address-context/AddressContext'
import { AddressFields, Field } from 'vtex.address-context/types'
import { useIntl, defineMessages } from 'react-intl'

import { useAddressForm, FieldName, FieldsMeta } from './useAddressForm'
import { styleRules } from './countries/rules'
import PlaceDetails from './PlaceDetails'
import NumberOption from './components/NumberOption'
import { useCountry } from './useCountry'

const messages = defineMessages({
  receiverName: {
    id: 'place-components.label.receiverName',
    defaultMessage: 'Receiver',
  },
  country: {
    defaultMessage: '',
    id: 'place-components.label.country',
  },
  state: {
    defaultMessage: '',
    id: 'place-components.label.state',
  },
  city: {
    defaultMessage: '',
    id: 'place-components.label.city',
  },
  neighborhood: {
    defaultMessage: '',
    id: 'place-components.label.neighborhood',
  },
  streetRoadAvenue: {
    defaultMessage: '',
    id: 'place-components.label.streetRoadAvenue',
  },
  numberOption: {
    defaultMessage: '',
    id: 'place-components.label.numberOption',
  },
  complement: {
    defaultMessage: '',
    id: 'place-components.label.complement',
  },
  stateAbbreviation: {
    defaultMessage: '',
    id: 'place-components.label.stateAbbreviation',
  },
  postalCode: {
    defaultMessage: '',
    id: 'place-components.label.postalCode',
  },
})

/**
 * This utility serves to create a "diff" for the fields we will
 * show to the user.
 *
 * For example if the address form is not in a  editing state, we will
 * render a place details with the "extended" display and we will only
 * show the fields that are *not* in the compact mode. This works by ignoring
 * all fields from the compact mode that are in the extended mode.
 */
const getExcludedFields = (
  summary: DisplayDefinition[][],
  includedFields: string[] = []
) => {
  const excludedFields = new Set<string>()

  summary.forEach((line) => {
    line.forEach((fragment) => {
      if (includedFields.includes(fragment.name)) {
        return
      }

      excludedFields.add(fragment.name)
    })
  })

  return excludedFields
}

interface AddressFormProps {
  hiddenFields?: AddressFields[]
  mandatoryEditableFields?: AddressFields[]
  onResetAddress?: () => void
  form?: ReturnType<typeof useAddressForm>
  expanded?: boolean
  onExpandForm?: () => void
}

const AddressForm: React.FC<AddressFormProps> = ({
  hiddenFields = [],
  mandatoryEditableFields = [],
  onResetAddress,
  form: propsForm,
  expanded: propsExpanded,
  onExpandForm,
}) => {
  const intl = useIntl()
  const addressContext = useAddressContext()
  const localForm = useAddressForm({
    initialAddress: addressContext.address,
    onAddressChange: addressContext.setAddress,
  })

  const [localExpanded, setLocalExpanded] = useState(false)

  const expanded = propsExpanded ?? localExpanded

  const form = propsForm ?? localForm
  const address = propsForm?.address ?? addressContext.address

  const country = useCountry()
  const countryRules = addressContext.rules[country]

  const { fields: countryRulesFields, display } = countryRules ?? {}
  const summary = display?.extended

  const handleEditButtonClick = () => {
    if (expanded) {
      onResetAddress?.()
    } else if (onExpandForm != null) {
      onExpandForm()
    } else {
      setLocalExpanded(true)
    }
  }

  const displayMode = expanded ? 'minimal' : 'compact'

  // The use of `useRef` is to prevent the fields from suddenly disappearing
  // from the form while typing the value
  //
  // For example: if the form is missing the number from the address and the user
  // starts typing the number, since the only validation we do on numbers is to check
  // if the value _exists_, as soon as the first character is typed the field will no
  // longer be invalid causing it to suddenly "disappear" from the screen if we don't use
  // the `useRef` hook.
  const initialInvalidFields = useRef([
    ...form.invalidFields,
    ...mandatoryEditableFields,
  ])

  const ignoredFields = useMemo(
    () =>
      getExcludedFields(
        display?.[displayMode] ?? [],
        initialInvalidFields.current
      ),
    [display, displayMode]
  )

  const handleFieldBlur: React.FocusEventHandler<
    HTMLInputElement | HTMLSelectElement
  > = (evt) => {
    const fieldName = evt.target.name

    if (!(fieldName in address)) {
      return
    }

    form.onFieldBlur(fieldName as FieldName)
  }

  return (
    <div>
      <div className="mb6 flex items-baseline lh-copy">
        <PlaceDetails
          display={displayMode}
          hiddenFields={initialInvalidFields.current as AddressFields[]}
          onEdit={handleEditButtonClick}
        />
      </div>
      <div>
        {summary
          ?.map((line) =>
            line.filter((fragment) => {
              const field = countryRulesFields?.[fragment.name as FieldName]

              if (
                !field ||
                ignoredFields.has(fragment.name) ||
                hiddenFields.includes(fragment.name as AddressFields)
              ) {
                return false
              }

              return true
            })
          )
          .filter((line) => line.length > 0)
          .map((line, index, renderedSummary) => (
            <div className="flex flex-wrap" key={index}>
              {line.map((fragment, fragmentIndex) => {
                const field = countryRulesFields?.[
                  fragment.name as FieldName
                ] as Field

                const style = styleRules[field.label]

                let fragmentElement = null

                const { maxLength, autoComplete, label } = field

                const handleChange = (value: string) => {
                  form.onFieldChange(fragment.name as FieldName, value)
                }

                const handleInputChange: React.ChangeEventHandler<
                  HTMLInputElement | HTMLSelectElement
                > = (evt) => {
                  handleChange(evt.target.value)
                }

                const value = address[fragment.name as FieldName] ?? ''

                const fragmentMeta =
                  form.meta[fragment.name as keyof FieldsMeta]

                const commonProps = {
                  label: intl.formatMessage(
                    messages[label as keyof typeof messages]
                  ),
                  value,
                  name: fragment.name,
                  onBlur: handleFieldBlur,
                  ...(maxLength && { maxLength }),
                  ...(autoComplete && { autoComplete }),
                  ...(fragmentMeta?.blurred && fragmentMeta.errorMessage
                    ? {
                        errorMessage: intl.formatMessage(
                          fragmentMeta.errorMessage
                        ),
                      }
                    : null),
                }

                fragmentElement =
                  fragment.name === 'number' ? (
                    <NumberOption
                      {...commonProps}
                      onChange={handleChange}
                      showCheckbox
                    />
                  ) : field.options ? (
                    <Dropdown
                      {...commonProps}
                      onChange={handleInputChange}
                      options={field.options}
                    />
                  ) : (
                    <Input {...commonProps} onChange={handleInputChange} />
                  )

                return (
                  <div
                    className={classnames('flex-auto', {
                      mb5: index < renderedSummary.length - 1,
                      mr5: fragmentIndex < line.length - 1,
                    })}
                    style={style}
                    key={fragment.name}
                  >
                    {fragmentElement}
                  </div>
                )
              })}
            </div>
          ))}
      </div>
    </div>
  )
}

export default AddressForm

```


[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 place-components/react/useAddressForm.ts from the place-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useState, useCallback, useMemo } from 'react'
import { defineMessages, MessageDescriptor } from 'react-intl'
import { AddressFields } from 'vtex.address-context/types'
import Utils from 'vtex.address-context/Utils'
import AddressContext from 'vtex.address-context/AddressContext'
import { Address } from 'vtex.checkout-graphql'

import { useCountry } from './useCountry'

const { createEmptyAddress, validateAddress } = Utils
const { useAddressContext } = AddressContext

interface FieldMeta {
  blurred: boolean
  errorMessage?: MessageDescriptor
}

export type FieldName = Exclude<
  AddressFields,
  'addressId' | 'addressType' | 'isDisposable'
>

export type FieldsMeta = {
  [field in FieldName]?: FieldMeta
}

interface FormOptions {
  initialAddress?: Address | null
  onAddressChange?: (address: Address) => void
}

const messages = defineMessages({
  fieldRequired: {
    defaultMessage: '',
    id: 'place-components.error.fieldRequired',
  },
})

export function useAddressForm({
  initialAddress,
  onAddressChange,
}: FormOptions = {}) {
  const { rules: addressRules } = useAddressContext()
  const [address, setAddress] = useState(initialAddress ?? createEmptyAddress())
  const country = useCountry()

  const { isValid, invalidFields } = useMemo(
    () => validateAddress(address, addressRules),
    [address, addressRules]
  )

  const [fieldsMeta, setFieldsMeta] = useState<FieldsMeta>(
    Object.fromEntries(
      invalidFields.map((field) => [
        field,
        { errorMessage: messages.fieldRequired },
      ])
    )
  )

  const updateFieldMeta = useCallback(
    (fieldName: FieldName, meta: Partial<FieldMeta>) => {
      setFieldsMeta((prevMeta) => ({
        ...prevMeta,
        [fieldName]: {
          ...prevMeta[fieldName],
          ...meta,
        },
      }))
    },
    []
  )

  const onFieldBlur = useCallback(
    (fieldName: FieldName) => {
      updateFieldMeta(fieldName, { blurred: true })
    },
    [updateFieldMeta]
  )

  const executeFieldValidation = useCallback(
    (name: string, value?: string | boolean | null | Array<number | null>) => {
      const countryRules = addressRules[country]

      if (!countryRules) {
        return
      }

      const fieldName = name in countryRules.fields ? (name as FieldName) : null

      if (!fieldName) {
        return
      }

      const fieldRule = countryRules.fields[fieldName]

      let errorMessage

      if (
        fieldRule?.required &&
        typeof value === 'string' &&
        value.length === 0
      ) {
        errorMessage = messages.fieldRequired
      }

      updateFieldMeta(fieldName as FieldName, { errorMessage })
    },
    [country, addressRules, updateFieldMeta]
  )

  const onFieldChange = useCallback(
    (fieldName: FieldName, value: string) => {
      const updatedAddress = { ...address, [fieldName]: value }

      executeFieldValidation(fieldName, value)

      setAddress(updatedAddress)
      onAddressChange?.(updatedAddress)
    },
    [address, onAddressChange, executeFieldValidation]
  )

  const updateAddress = useCallback(
    (update: React.SetStateAction<Address>) => {
      setAddress((prevAddress) => {
        let updatedAddress

        if (typeof update === 'function') {
          updatedAddress = update(prevAddress)
        } else {
          updatedAddress = update
        }

        Object.entries(updatedAddress).forEach(([fieldName, fieldValue]) => {
          executeFieldValidation(fieldName, fieldValue)
        })

        return updatedAddress
      })
    },
    [executeFieldValidation]
  )

  return {
    address,
    setAddress: updateAddress,
    isValid,
    invalidFields,
    meta: fieldsMeta,
    onFieldBlur,
    onFieldChange,
  }
}

export default useAddressForm

```


[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 place-components/react/useCountry.ts from the place-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useRuntime } from 'vtex.render-runtime'
import { useAddressContext } from 'vtex.address-context/AddressContext'

export const useCountry = () => {
  const { culture } = useRuntime()
  const { address } = useAddressContext()

  // TODO: should also try to get country from:
  // - addresses in account
  // - IP
  return address?.country ?? culture.country
}

```


[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 place-components/react/LocationSelect.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useAddressContext } from 'vtex.address-context/AddressContext'
import { Dropdown } from 'vtex.styleguide'
import { FormattedMessage, defineMessages } from 'react-intl'
import { Address } from 'vtex.checkout-graphql'
import { AddressFields } from 'vtex.address-context/types'

import { useCountry } from './useCountry'

const messages = defineMessages({
  province: {
    defaultMessage: '',
    id: 'place-components.label.province',
  },
  city: {
    defaultMessage: '',
    id: 'place-components.label.city',
  },
  department: {
    defaultMessage: '',
    id: 'place-components.label.department',
  },
  region: {
    defaultMessage: '',
    id: 'place-components.label.region',
  },
  community: {
    defaultMessage: '',
    id: 'place-components.label.community',
  },
  municipality: {
    defaultMessage: '',
    id: 'place-components.label.municipality',
  },
  district: {
    defaultMessage: '',
    id: 'place-components.label.district',
  },
  state: {
    defaultMessage: '',
    id: 'place-components.label.state',
  },
  locality: {
    defaultMessage: '',
    id: 'place-components.label.locality',
  },
})

const LocationSelect: React.FC = () => {
  const { address, setAddress, rules } = useAddressContext()
  const country = useCountry()
  const countryRules = rules[country]

  if (!countryRules?.locationSelect) {
    throw new Error(
      `The country "${country}" is not applicable to the LocationSelect component`
    )
  }

  const { countryData, fields } = countryRules.locationSelect

  const addressFields = fields.map(
    (field) => address[field.name as AddressFields]
  )

  const firstMissingIdx = addressFields.findIndex((field) => !field)
  const completedFields =
    firstMissingIdx === -1
      ? addressFields
      : addressFields.slice(0, firstMissingIdx)

  const getLocationSelects = () => {
    const locationSelects = []
    let currentOptions = countryData

    for (let i = 0; i < fields.length; ++i) {
      const field = fields[i]
      const fieldValue = address[field.name as AddressFields]

      if (typeof fieldValue !== 'string') {
        continue
      }

      locationSelects.push(
        <div className="mb5" key={i}>
          <Dropdown
            label={
              <FormattedMessage
                {...messages[field.label as keyof typeof messages]}
              />
            }
            disabled={i > completedFields.length}
            options={(Array.isArray(currentOptions) // Workaround, fix JSON country data
              ? currentOptions
              : Object.keys(currentOptions)
            ).map((name) => {
              return { label: name, value: name }
            })}
            onChange={({
              target: { value },
            }: React.ChangeEvent<HTMLSelectElement>) => {
              let newFields: { [key: string]: string | null } = {
                [field.name as string]: value,
              }

              for (let j = i + 1; j < fields.length; ++j) {
                newFields = { ...newFields, [fields[j].name as string]: null }
              }

              setAddress((prevAddress: Address) => ({
                ...prevAddress,
                ...newFields,
              }))
            }}
            placeholder="Select..."
            value={fieldValue}
          />
        </div>
      )

      currentOptions = fieldValue
        ? // eslint-disable-next-line @typescript-eslint/ban-types
          currentOptions[fieldValue as keyof object]
        : {}
    }

    return locationSelects
  }

  return <div>{getLocationSelects()}</div>
}

export default LocationSelect

```


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

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "test": "vtex-test-tools test --testPathIgnorePatterns third_party"
  },
  "dependencies": {
    "@reach/combobox": "^0.10.5",
    "classnames": "^2.2.6",
    "graphql": "^14.6.0",
    "msk": "^1.0.5",
    "react": "^16.8.3",
    "react-apollo": "^3.1.3",
    "react-dom": "^16.8.3",
    "react-intl": "3.9.1"
  },
  "devDependencies": {
    "@apollo/react-testing": "^3.1.3",
    "@reach/listbox": "^0.10.2",
    "@testing-library/dom": "^7.29.5",
    "@testing-library/user-event": "^12.7.1",
    "@types/classnames": "^2.2.7",
    "@types/jest": "^26.0.8",
    "@types/node": "^12.7.5",
    "@types/prop-types": "^15.7.0",
    "@types/react": "^16.9.2",
    "@vtex/styleguide": "^9.112.13",
    "@vtex/test-tools": "^3.0.2",
    "apollo-cache-inmemory": "^1.6.6",
    "apollo-client": "^2.6.10",
    "vtex.address-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.address-context@0.6.2/public/@types/vtex.address-context",
    "vtex.checkout-components": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.checkout-components@0.5.1/public/@types/vtex.checkout-components",
    "vtex.checkout-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.checkout-graphql@0.56.2/public/@types/vtex.checkout-graphql",
    "vtex.country-data-settings": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.country-data-settings@0.4.0/public/@types/vtex.country-data-settings",
    "vtex.country-flags": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.country-flags@0.1.1/public/@types/vtex.country-flags",
    "vtex.geolocation-graphql-interface": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.geolocation-graphql-interface@0.3.0/public/@types/vtex.geolocation-graphql-interface",
    "vtex.places-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.places-graphql@0.4.0/public/@types/vtex.places-graphql",
    "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.3/public/@types/vtex.styleguide"
  },
  "jest": {
    "setupFilesAfterEnv": [
      "<rootDir>/setupTests.js"
    ]
  },
  "version": "0.15.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 place-components/react/LocationCountry.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useEffect, useState } from 'react'
import { useAddressContext } from 'vtex.address-context/AddressContext'
import { Listbox } from 'vtex.checkout-components'
import { CountryFlag } from 'vtex.country-flags'
import { defineMessages, useIntl } from 'react-intl'

import { useCountry } from './useCountry'

const {
  ListboxInput,
  ListboxButton,
  ListboxPopover,
  ListboxList,
  ListboxOption,
} = Listbox

const messages = defineMessages({
  ARG: {
    defaultMessage: '',
    id: 'place-components.label.ARG',
  },
  BRA: {
    defaultMessage: '',
    id: 'place-components.label.BRA',
  },
  BOL: {
    defaultMessage: '',
    id: 'place-components.label.BOL',
  },
  KOR: {
    defaultMessage: '',
    id: 'place-components.label.KOR',
  },
})

const renderCountryFlagWithName = ({
  country,
  name,
}: {
  country: string
  name: string
}) => (
  <>
    <CountryFlag iso3={country} />
    <span className="dib ml3">{name}</span>
  </>
)

interface LocationCountryProps {
  labelId?: string
  className?: string
}

const LocationCountry: React.FC<LocationCountryProps> = ({
  labelId = 'location-country',
  className = '',
}) => {
  const intl = useIntl()
  const { setAddress, countries } = useAddressContext()

  const [country, setCountry] = useState(useCountry())

  if (country && countries && !countries.includes(country)) {
    throw new Error(
      `The country "${country}" doesn't belong to the country list, can't render LocationCountry`
    )
  }

  useEffect(() => {
    setAddress((prevAddress) => ({
      ...prevAddress,
      country,
      // reset all other fields related
      // to the country
      city: null,
      complement: null,
      geoCoordinates: null,
      neighborhood: null,
      number: null,
      postalCode: null,
      state: null,
      street: null,
    }))
  }, [country, setAddress])

  // Do not render anything if we only have 1 country or none.
  if (countries.length <= 1) {
    return null
  }

  return (
    <div className={className}>
      <span
        id={labelId}
        className="vtex-input__label db mb3 w-100 c-on-base t-body"
      >
        {intl.formatMessage({ id: 'place-components.label.country' })}
      </span>
      <ListboxInput
        translate={undefined}
        aria-labelledby={labelId}
        value={country}
        onChange={setCountry}
      >
        <ListboxButton>
          {({ label }) =>
            renderCountryFlagWithName({
              country,
              name: label,
            })
          }
        </ListboxButton>
        <ListboxPopover translate={undefined}>
          <ListboxList>
            {countries.map((countryCode) => {
              const name =
                countryCode in messages
                  ? intl.formatMessage(
                      messages[countryCode as keyof typeof messages]
                    )
                  : countryCode

              return (
                <ListboxOption
                  value={countryCode}
                  label={name}
                  key={countryCode}
                >
                  {renderCountryFlagWithName({
                    country: countryCode,
                    name,
                  })}
                </ListboxOption>
              )
            })}
          </ListboxList>
        </ListboxPopover>
      </ListboxInput>
    </div>
  )
}

export default LocationCountry

```


[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 place-components/react/LocationSearch.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState, useRef, useEffect, ReactNode } from 'react'
import { FormattedMessage } from 'react-intl'
import {
  Input,
  IconSearch,
  IconClear,
  IconWarning,
  Spinner,
} from 'vtex.styleguide'
import { positionMatchWidth } from '@reach/popover'
import { useAddressContext } from 'vtex.address-context/AddressContext'
import { useLazyQuery, useQuery } from 'react-apollo'
import {
  Address,
  AddressSuggestion,
  Image,
  Query,
  QueryAddressArgs,
  QueryAddressSuggestionsArgs,
} from 'vtex.geolocation-graphql-interface'

import PROVIDER_LOGO from './graphql/providerLogo.graphql'
import SESSION_TOKEN from './graphql/sessionToken.graphql'
import ADDRESS_SUGGESTIONS from './graphql/addressSuggestions.graphql'
import ADDRESS from './graphql/address.graphql'
import {
  Combobox,
  ComboboxInput,
  ComboboxOption,
  ComboboxPopover,
  ComboboxList,
} from './components/Combobox'
import PlaceIcon from './components/PlaceIcon'
import { useCountry } from './useCountry'

const DEBOUNCE_DELAY_IN_MS = 500

const useProviderLogo = (): Image | undefined => {
  const { data, error } = useQuery<Query, never>(PROVIDER_LOGO)

  if (error) {
    console.error(error.message)
  }

  return data?.providerLogo
}

const useDebouncedValue = (value: string, delayInMs: number): string => {
  const [debouncedValue, setDebouncedValue] = useState(value)

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value)
    }, delayInMs)

    return () => {
      clearTimeout(handler)
    }
  }, [value, delayInMs])

  return debouncedValue
}

const useSuggestions = (
  searchTerm: string,
  sessionToken?: string | null,
  country?: string | null
): [AddressSuggestion[], boolean] => {
  const [executeAddressSuggestions, { data, error, loading }] = useLazyQuery<
    Query,
    QueryAddressSuggestionsArgs
  >(ADDRESS_SUGGESTIONS)

  useEffect(() => {
    if (searchTerm.trim().length) {
      executeAddressSuggestions({
        variables: { searchTerm, sessionToken, country },
      })
    }
    // the effect shouldn't be triggered when the sessionToken changes
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchTerm, country, executeAddressSuggestions])

  useEffect(() => {
    if (error) {
      console.error(error.message)
    }
  }, [error])

  return [data?.addressSuggestions ?? [], loading]
}

const renderSuggestionText = ({
  mainText,
  mainTextMatchInterval: { offset, length },
  secondaryText,
}: AddressSuggestion) => {
  return (
    <div className="truncate c-muted-2">
      <span className="c-on-base">
        {mainText.substr(0, offset)}
        <span className="b">{mainText.substr(offset, length)}</span>
        {mainText.substr(offset + length)}
      </span>{' '}
      <span>{secondaryText}</span>
    </div>
  )
}

interface LocationSearchProps {
  label?: ReactNode | string
  onSelectAddress?: (address: Address) => void
}

const LocationSearch: React.FC<LocationSearchProps> = ({
  label = <FormattedMessage id="place-components.label.autocompleteAddress" />,
  onSelectAddress,
}) => {
  const [searchTerm, setSearchTerm] = useState('')
  const [displayedSearchTerm, setDisplayedSearchTerm] = useState('')
  const inputWrapperRef = useRef<HTMLDivElement>(null)
  const { setAddress } = useAddressContext()
  const providerLogo = useProviderLogo()
  const debouncedSearchTerm = useDebouncedValue(
    searchTerm,
    DEBOUNCE_DELAY_IN_MS
  )

  const {
    data: sessionTokenData,
    error: sessionTokenError,
    refetch: refetchSessionToken,
  } = useQuery<Query, never>(SESSION_TOKEN, {
    notifyOnNetworkStatusChange: true,
  })

  const country = useCountry()
  const sessionToken = sessionTokenData?.sessionToken ?? null
  const [suggestions, loadingSuggestions] = useSuggestions(
    debouncedSearchTerm,
    sessionToken,
    country
  )

  const [executeAddress, { data, error, loading }] = useLazyQuery<
    Query,
    QueryAddressArgs
  >(ADDRESS)

  useEffect(() => {
    if (sessionTokenError) {
      console.error(sessionTokenError.message)
    }
  }, [sessionTokenError])

  useEffect(() => {
    if (data) {
      setAddress((prevAddress) => ({
        ...prevAddress,
        ...data.address,
      }))
      onSelectAddress?.(data.address)
    }

    if (error) {
      console.error(error.message)
    }
  }, [data, error, onSelectAddress, setAddress])

  const handleKeyDown = (event: React.KeyboardEvent) => {
    if (event.key !== 'Escape') {
      return
    }

    setSearchTerm('')
    setDisplayedSearchTerm('')
  }

  const handleSuggestionSelection = (selectedSuggestion: string) => {
    const externalId = suggestions.find(
      (suggestion) => suggestion.description === selectedSuggestion
    )?.externalId

    if (externalId == null) {
      console.error(`${selectedSuggestion} was not found`)

      return
    }

    setDisplayedSearchTerm(selectedSuggestion)
    executeAddress({ variables: { externalId, sessionToken } })
    refetchSessionToken()
  }

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSearchTerm(event.target.value)
    setDisplayedSearchTerm(event.target.value)
  }

  const handleClick = () => {
    setSearchTerm('')
    setDisplayedSearchTerm('')
  }

  return (
    <div className="w-100">
      <Combobox onSelect={handleSuggestionSelection}>
        <div ref={inputWrapperRef}>
          <ComboboxInput
            as={Input}
            size="large"
            testId="location-search-input"
            label={label}
            prefix={
              <div className="c-action-primary flex justify-center items-center">
                <IconSearch />
              </div>
            }
            suffix={
              loading ? (
                <Spinner size={20} />
              ) : searchTerm.trim().length ? (
                <span
                  data-testid="location-search-clear"
                  role="button"
                  // the input can be cleared by pressing the esc key,
                  // so the clear button should not be tabbable
                  tabIndex={-1}
                  className="flex pa3 na3 pointer outline-0 c-muted-3 hover-gray"
                  onClick={handleClick}
                  onKeyPress={() => {}}
                >
                  <IconClear />
                </span>
              ) : null
            }
            disabled={loading}
            value={displayedSearchTerm}
            onChange={handleChange}
            onKeyDown={handleKeyDown}
          />
        </div>
        {debouncedSearchTerm.trim().length ? (
          <ComboboxPopover
            position={(_targetRect, popoverRect) =>
              positionMatchWidth(
                inputWrapperRef.current?.getBoundingClientRect(),
                popoverRect
              )
            }
          >
            {suggestions.length > 0 ? (
              <ComboboxList>
                {suggestions.map((suggestion, index) => (
                  <ComboboxOption value={suggestion.description} key={index}>
                    <PlaceIcon className="flex flex-shrink-0 mr4 c-muted-1" />
                    {renderSuggestionText(suggestion)}
                  </ComboboxOption>
                ))}
              </ComboboxList>
            ) : null}
            {loadingSuggestions ? (
              <div className="flex flex-row justify-center items-center pa3">
                <Spinner size={20} />
              </div>
            ) : null}
            {suggestions.length > 0 && providerLogo ? (
              <div className="flex flex-row-reverse">
                <div className="mt3 mb1 mh5">
                  <img
                    className="h1"
                    src={providerLogo.src}
                    alt={providerLogo.alt}
                  />
                </div>
              </div>
            ) : null}
            {!loadingSuggestions && suggestions.length === 0 ? (
              <div className="flex items-center pv3 ph5">
                <div className="flex flex-shrink-0 mr4 c-muted-3">
                  <IconWarning />
                </div>
                <div className="truncate c-muted-2 fw6">
                  <FormattedMessage id="place-components.label.autocompleteAddressFail" />
                </div>
              </div>
            ) : null}
          </ComboboxPopover>
        ) : null}
      </Combobox>
    </div>
  )
}

export default LocationSearch

```


[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 place-components/react/setupTests.js from the place-components VTEX app.

[Assistant]
Here's the implementation:

```javascript
global.navigator.geolocation = {
  getCurrentPosition: jest.fn(),
}

global.navigator.permissions = {
  query: jest.fn(),
}

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation((query) => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(), // Deprecated
    removeListener: jest.fn(), // Deprecated
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
})

```


[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 place-components/react/DeviceCoordinates.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState, useEffect, useCallback, useMemo } from 'react'
import { useAddressContext } from 'vtex.address-context/AddressContext'
import { ButtonPlain, Spinner, Tooltip, IconLocation } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'
import { useLazyQuery } from 'react-apollo'
import { Address } from 'vtex.places-graphql'

import REVERSE_GEOCODE_QUERY from './graphql/reverseGeocode.graphql'

export interface GeolocationPosition {
  coords: {
    latitude: number
    longitude: number
  }
}

interface GeolocationPositionError {
  code: number
  message: string
}

type PermissionState = 'prompt' | 'pending' | 'granted' | 'denied'

interface Props {
  onSuccess?: (address: Address) => void
}

const DeviceCoordinates: React.FC<Props> = ({ onSuccess }) => {
  const { setAddress } = useAddressContext()
  const [geolocationPermission, setGeolocationPermission] = useState<
    PermissionState
  >('prompt')

  const [executeReverseGeocode, geoResult] = useLazyQuery(REVERSE_GEOCODE_QUERY)

  const { loading } = geoResult

  useEffect(() => {
    if (geoResult.data) {
      setAddress(geoResult.data.reverseGeocode)
      onSuccess?.(geoResult.data.reverseGeocode)
    }

    if (geoResult.error) {
      console.warn(geoResult.error.message)
    }
  }, [geoResult, setAddress, onSuccess])

  const onGetCurrentPositionSuccess = useCallback(
    ({ coords }: GeolocationPosition) => {
      setGeolocationPermission('granted')

      executeReverseGeocode({
        variables: {
          lat: coords.latitude.toString(),
          lng: coords.longitude.toString(),
        },
      })
    },
    [executeReverseGeocode]
  )

  const onGetCurrentPositionError = useCallback(
    (err: GeolocationPositionError) => {
      setGeolocationPermission('denied')
      console.warn(`ERROR(${err.code}): ${err.message}`)
    },
    []
  )

  const requestGeolocation = useCallback(() => {
    setGeolocationPermission('pending')
    navigator.geolocation.getCurrentPosition(
      onGetCurrentPositionSuccess,
      onGetCurrentPositionError,
      {
        enableHighAccuracy: true,
      }
    )
  }, [onGetCurrentPositionError, onGetCurrentPositionSuccess])

  const handleButtonClick = () => {
    requestGeolocation()
  }

  useEffect(() => {
    // some browsers do not have/require permissions
    if (!navigator.permissions) {
      return
    }

    navigator.permissions
      .query({ name: 'geolocation' })
      .then((result: PermissionStatus) => {
        if (result.state === 'denied') {
          setGeolocationPermission('denied')
        }
      })
  }, [requestGeolocation])

  const locationIcon = useMemo(() => {
    switch (geolocationPermission) {
      case 'prompt':
        return <IconLocation block />

      case 'granted':
        return <IconLocation solid block />

      case 'pending':
        return <Spinner size={16} block />

      case 'denied':
        return <IconLocation block />

      default:
        return null
    }
  }, [geolocationPermission])

  let buttonElement = (
    <ButtonPlain
      disabled={geolocationPermission === 'denied'}
      onClick={handleButtonClick}
    >
      <div className="flex items-center">
        <div className="flex-none mr3">
          {loading ? <Spinner size={16} /> : locationIcon}
        </div>
        <div className="flex-auto">
          <FormattedMessage id="place-components.label.useCurrentLocation" />
        </div>
      </div>
    </ButtonPlain>
  )

  if (geolocationPermission === 'denied') {
    buttonElement = (
      <Tooltip label="Permission not granted">{buttonElement}</Tooltip>
    )
  }

  return buttonElement
}

export default DeviceCoordinates

```


[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 place-components/react/__fixtures__/addressRules.fixture.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { AddressRules } from 'vtex.address-context/types'

export const braRules: AddressRules = {
  BRA: {
    display: {
      minimal: [
        [
          {
            name: 'postalCode',
          },
        ],
      ],
      compact: [
        [
          {
            name: 'street',
          },
          {
            delimiter: ' ',
            name: 'number',
          },
        ],
        [
          {
            name: 'neighborhood',
          },
        ],
        [
          {
            name: 'city',
          },
          {
            delimiter: ' - ',
            name: 'state',
          },
        ],
        [
          {
            name: 'postalCode',
          },
        ],
      ],
      extended: [
        [
          {
            name: 'receiverName',
          },
        ],
        [
          {
            name: 'street',
          },
          {
            delimiter: ' ',
            name: 'number',
          },
        ],
        [
          {
            name: 'complement',
          },
        ],
        [
          {
            name: 'neighborhood',
          },
        ],
        [
          {
            name: 'city',
          },
          {
            delimiter: ' - ',
            name: 'state',
          },
        ],
        [
          {
            name: 'postalCode',
          },
        ],
      ],
    },
    fields: {
      country: {
        label: 'country',
        hidden: true,
        maxLength: 100,
      },
      state: {
        label: 'stateAbbreviation',
        maxLength: 100,
        required: true,
        optionsCaption: 'UF',
        options: [
          {
            label: 'AC',
            value: 'AC',
          },
          {
            label: 'AL',
            value: 'AL',
          },
          {
            label: 'AP',
            value: 'AP',
          },
          {
            label: 'AM',
            value: 'AM',
          },
          {
            label: 'BA',
            value: 'BA',
          },
          {
            label: 'CE',
            value: 'CE',
          },
          {
            label: 'DF',
            value: 'DF',
          },
          {
            label: 'ES',
            value: 'ES',
          },
          {
            label: 'GO',
            value: 'GO',
          },
          {
            label: 'MA',
            value: 'MA',
          },
          {
            label: 'MT',
            value: 'MT',
          },
          {
            label: 'MS',
            value: 'MS',
          },
          {
            label: 'MG',
            value: 'MG',
          },
          {
            label: 'PA',
            value: 'PA',
          },
          {
            label: 'PB',
            value: 'PB',
          },
          {
            label: 'PR',
            value: 'PR',
          },
          {
            label: 'PE',
            value: 'PE',
          },
          {
            label: 'PI',
            value: 'PI',
          },
          {
            label: 'RJ',
            value: 'RJ',
          },
          {
            label: 'RN',
            value: 'RN',
          },
          {
            label: 'RS',
            value: 'RS',
          },
          {
            label: 'RO',
            value: 'RO',
          },
          {
            label: 'RR',
            value: 'RR',
          },
          {
            label: 'SC',
            value: 'SC',
          },
          {
            label: 'SP',
            value: 'SP',
          },
          {
            label: 'SE',
            value: 'SE',
          },
          {
            label: 'TO',
            value: 'TO',
          },
        ],
      },
      city: {
        label: 'city',
        maxLength: 100,
        required: true,
      },
      neighborhood: {
        label: 'neighborhood',
        maxLength: 100,
        required: true,
      },
      street: {
        label: 'streetRoadAvenue',
        required: true,
      },
      number: {
        label: 'numberOption',
        maxLength: 750,
        required: true,
        autoComplete: 'off',
      },
      complement: {
        label: 'complement',
        maxLength: 750,
      },
      reference: {
        label: 'reference',
        hidden: true,
        maxLength: 750,
      },
      receiverName: {
        label: 'receiverName',
        elementName: 'receiver',
        maxLength: 750,
        required: true,
      },
      postalCode: {
        mask: '99999-999',
        label: 'postalCode',
        additionalData: {
          forgottenURL:
            'http://www.buscacep.correios.com.br/servicos/dnec/index.do',
        },
      },
    },
  },
}

```


[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 place-components/react/__fixtures__/address.fixture.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { Address } from 'vtex.places-graphql'

export const emptyAddress: Address = {
  street: '',
  number: '',
  complement: '',
  postalCode: '',
  city: '',
  state: '',
  addressId: '',
  addressType: null,
  country: '',
  geoCoordinates: [],
  neighborhood: '',
  receiverName: null,
  reference: null,
}

export const completeAddress: Address = {
  street: 'Av. Belgrano',
  number: '2248',
  complement: 'B',
  postalCode: '2000',
  city: 'Rosario',
  state: 'Santa Fé',
  addressId: '',
  addressType: null,
  country: 'ARG',
  geoCoordinates: [],
  neighborhood: 'Las Delicias',
  receiverName: null,
  reference: null,
}

export const incompleteAddress: Address = {
  street: 'Av. Belgrano',
  number: '2248',
  complement: '',
  postalCode: '2000',
  city: '',
  state: '',
  addressId: '',
  addressType: null,
  country: 'ARG',
  geoCoordinates: [],
  neighborhood: '',
  receiverName: null,
  reference: null,
}

export const sampleAddress: Address = {
  street: 'Rua Afonso Camargo',
  number: '805',
  complement: '',
  postalCode: '85070-200',
  city: 'Guarapuava',
  state: 'PR',
  addressId: '',
  addressType: null,
  country: 'BRA',
  geoCoordinates: [],
  neighborhood: 'Santana',
  receiverName: null,
  reference: null,
}

export const vtexOfficeAddress: Address = {
  addressId: '1',
  addressType: 'residential',
  city: 'Rio de Janeiro',
  complement: null,
  country: 'BRA',
  geoCoordinates: [-43.18037200000001, -22.9418474],
  neighborhood: 'Botafogo',
  number: '200',
  postalCode: '22250-145',
  receiverName: null,
  reference: null,
  state: 'RJ',
  street: 'Rua Praia de Botafogo',
}

```


[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 place-components/react/typings/vtex.address-context.d.ts from the place-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.address-context/AddressContext' {
  export * from 'vtex.address-context/react/AddressContext'
  export { default } from 'vtex.address-context/react/AddressContext'
}

declare module 'vtex.address-context/types' {
  export * from 'vtex.address-context/react/types'
}

declare module 'vtex.address-context/Utils' {
  export * from 'vtex.address-context/react/Utils'
}

```


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

[Assistant]
Here's the implementation:

```typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
declare module '*.css' {
  const css: any
  export default css
}

```


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

[User] Show me the implementation of place-components/react/typings/graphql.d.ts from the place-components VTEX app.

[Assistant]
Here's the implementation:

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

  const value: DocumentNode
  export default value
}

```


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

[User] Show me the implementation of place-components/react/typings/vtex.styleguide.d.ts from the place-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react'

declare module 'vtex.styleguide' {
  export const Button: React.FC<any>

  export const Input: React.FC<any>

  export const IconClear: React.FC<any>

  export const IconWarning: React.FC<any>

  export const InputButton: React.FC<any>

  export const Spinner: React.FC<any>

  export const IconLocation: React.FC<any>

  export const Checkbox: React.FC<any>

  interface DropdownProps {
    value?: string
    label?: React.ReactNode
    placeholder?: string
    options: Array<{ label: string; value: string }>
    onChange?: React.ChangeEventHandler<HTMLSelectElement>
    disabled?: boolean
    name?: string
  }

  export const Dropdown: React.FC<DropdownProps>

  export const IconSearch: React.FC<any>

  export const IconCaretDown: React.FC<any>

  export const IconEdit: React.FC<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 place-components/react/components/PlaceIcon.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

export const PlaceIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (
  <svg
    {...props}
    xmlns="http://www.w3.org/2000/svg"
    width="14"
    height="16"
    viewBox="0 0 14 16"
    fill="none"
  >
    <path
      d="M7.04917 0C3.12177 0 0 3.1 0 7C0 8.56189 0.476353 10.0562 1.42906 11.2607C1.50908 11.3782 1.60101 11.4919 1.70535 11.6007L5.19589 15.2393C5.63744 15.6996 6.21111 15.9534 6.79833 16.0006C6.97371 16.0366 7.15342 16.0328 7.31309 15.9891C7.86105 15.9204 8.39053 15.6705 8.80411 15.2393L12.2946 11.6007C12.4052 11.4855 12.5017 11.3647 12.585 11.2399C13.5268 10.039 13.9976 8.55289 13.9976 7C14.0983 3.1 10.9766 0 7.04917 0ZM9.56673 6.5C9.56673 7.88071 8.43958 9 7.04917 9C5.65876 9 4.53161 7.88071 4.53161 6.5C4.53161 5.11929 5.65876 4 7.04917 4C8.43958 4 9.56673 5.11929 9.56673 6.5Z"
      fill="currentColor"
    />
  </svg>
)

export default PlaceIcon

```


[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 place-components/react/components/Combobox.css from the place-components VTEX app.

[Assistant]
Here's the implementation:

```css
:root {
  --reach-combobox: 1;
}

.option:not([aria-selected="true"]).option:not(:hover) {
  background-color: transparent;
}

.popover {
  box-shadow: 0px 1px 16px rgba(46, 46, 46, 0.12);
}
```


[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 place-components/react/components/NumberOption.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState, useRef, useMemo } from 'react'
import { Input, Checkbox } from 'vtex.styleguide'
import { FormattedMessage, useIntl, defineMessages } from 'react-intl'

const messages = defineMessages({
  wn: {
    defaultMessage: '',
    id: 'place-components.label.wn',
  },
  numberOption: {
    defaultMessage: '',
    id: 'place-components.label.numberOption',
  },
  fieldRequired: {
    defaultMessage: '',
    id: 'place-components.error.fieldRequired',
  },
  withoutNumber: {
    defaultMessage: '',
    id: 'place-components.label.withoutNumber',
  },
})

interface Props {
  showCheckbox: boolean
  name: string
  label: React.ReactNode
  value: string
  onChange?: (value: string) => void
  disabled?: boolean
  maxLength?: number
  autoComplete?: string
}

const NumberOption: React.FC<Props> = ({
  showCheckbox,
  onChange,
  ...props
}) => {
  const intl = useIntl()
  const inputRef = useRef<HTMLInputElement>(null)
  const withoutNumberMessage = useMemo(() => intl.formatMessage(messages.wn), [
    intl,
  ])

  const [disabled, setDisabled] = useState(
    showCheckbox && props.value === withoutNumberMessage
  )

  const onCheckboxChange = () => {
    onChange?.(disabled ? '' : intl.formatMessage(messages.wn))
    setDisabled(!disabled)

    setTimeout(() => {
      inputRef.current?.focus()
    }, 0)
  }

  const checkboxProps = {
    id: 'number-checkbox',
    name: 'number-checkbox',
    label: <FormattedMessage {...messages.withoutNumber} />,
    onChange: onCheckboxChange,
    checked: disabled,
  }

  return (
    <div className="flex">
      <div className="flex-auto">
        <Input
          ref={inputRef}
          {...props}
          onChange={({
            target: { value },
          }: React.ChangeEvent<HTMLInputElement>) => onChange?.(value)}
          disabled={disabled || props.disabled}
        />
      </div>
      {showCheckbox && (
        <div className="flex-none h-regular ml5 mt7 flex items-center">
          <Checkbox {...checkboxProps} />
        </div>
      )}
    </div>
  )
}

export default NumberOption

```


[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 place-components/react/components/Combobox.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import {
  Combobox as ReachCombobox,
  ComboboxInput as ReachComboboxInput,
  ComboboxPopover as ReachComboboxPopover,
  ComboboxPopoverProps as ReachComboboxPopoverProps,
  ComboboxList as ReachComboboxList,
  ComboboxListProps as ReachComboboxListProps,
  ComboboxOption as ReachComboboxOption,
  ComboboxOptionProps as ReachComboboxOptionProps,
  ComboboxOptionText as ReachComboboxOptionText,
} from '@reach/combobox'
import { PopoverProps } from '@reach/popover'
import React, { forwardRef } from 'react'
import classNames from 'classnames'

import styles from './Combobox.css'

export const Combobox = ReachCombobox

export const ComboboxInput = ReachComboboxInput

export const ComboboxPopover = forwardRef<
  HTMLDivElement,
  ReachComboboxPopoverProps &
    Partial<PopoverProps> &
    React.RefAttributes<HTMLDivElement>
>(function ComboboxPopover({ className, ...props }, ref) {
  return (
    <ReachComboboxPopover
      {...props}
      ref={ref}
      className={classNames(
        className,
        styles.popover,
        'bg-base pv3 mt2 br2 ba bw1 b--muted-4 absolute outline-0'
      )}
    />
  )
})

export const ComboboxList: React.FC<ReachComboboxListProps & {
  className?: string
}> = ({ className, ...props }) => (
  <ReachComboboxList
    {...props}
    className={classNames(className, 'bg-base list ma0 pa0 outline-0')}
  />
)

export const ComboboxOption: React.FC<ReachComboboxOptionProps & {
  className?: string
}> = ({ className, children, ...props }) => (
  <ReachComboboxOption
    {...props}
    className={classNames(
      className,
      styles.option,
      'flex items-center pv3 ph5 pointer bg-action-secondary hover-bg-action-secondary active-bg-action-secondary'
    )}
  >
    {children ?? <ReachComboboxOptionText />}
  </ReachComboboxOption>
)

export default {
  Combobox,
  ComboboxInput,
  ComboboxPopover,
  ComboboxList,
  ComboboxOption,
}

```


[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 place-components/react/__tests__/LocationInput.test.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render, screen, waitFor } from '@vtex/test-tools/react'
import { MockedResponse } from '@apollo/react-testing'
import { Address } from 'vtex.checkout-graphql'
import { AddressRules, CountryRules, Field } from 'vtex.address-context/types'
import { AddressContextProvider } from 'vtex.address-context/AddressContext'
import userEvent from '@testing-library/user-event'

import LocationInput from '../LocationInput'
import { validPostalCode } from '../__fixtures__/graphql/getAddressFromPostalCode.fixture'

interface SetupProps {
  address?: Address | null
  countries?: string[]
  rules?: AddressRules
  graphqlMocks?: MockedResponse[]
}

interface RenderComponentProps extends SetupProps {
  locationInputProps?: React.ComponentProps<typeof LocationInput>
}

const defaultGraphqlMocks: MockedResponse[] = []

describe('LocationInput', () => {
  const renderComponent = ({
    locationInputProps = {},
    address = { country: 'BRA' },
    countries = [],
    rules = {
      BRA: {
        fields: {
          postalCode: {
            mask: '99999-999',
            pattern: '^(\\d){5}-?(\\d){3}$',
            additionalData: {
              forgottenURL:
                'https://buscacepinter.correios.com.br/app/endereco/',
            },
          } as Field,
        },
      } as CountryRules,
    },
    graphqlMocks = [],
  }: RenderComponentProps) => {
    return render(
      <AddressContextProvider
        address={address}
        countries={countries}
        rules={rules}
      >
        <LocationInput {...locationInputProps} />
      </AddressContextProvider>,
      {
        graphql: {
          mocks: [...defaultGraphqlMocks, ...graphqlMocks],
          addTypename: false,
        },
      }
    )
  }

  afterEach(() => {
    jest.resetAllMocks()
  })

  it('should format and submit a valid postal code', async () => {
    const mockedOnSuccess = jest.fn()

    renderComponent({
      locationInputProps: { onSuccess: mockedOnSuccess },
      graphqlMocks: [validPostalCode],
    })

    const input = screen.getByRole('textbox', {
      name: /postal code/i,
    })

    userEvent.type(input, '22250040')
    userEvent.click(screen.getByRole('button'))

    await waitFor(() => {
      expect(mockedOnSuccess).toHaveBeenCalledTimes(1)
    })
  })

  it('should format and submit a valid postal code after fixing an invalid postal code', async () => {
    const mockedOnSuccess = jest.fn()

    renderComponent({
      locationInputProps: { onSuccess: mockedOnSuccess },
      graphqlMocks: [validPostalCode],
    })

    const input = screen.getByRole('textbox', {
      name: /postal code/i,
    })

    // it's missing the last digit
    userEvent.type(input, '2225004')
    userEvent.click(screen.getByRole('button'))

    expect(
      screen.getByText(/inform a valid postal code\./i)
    ).toBeInTheDocument()

    userEvent.type(input, '{selectall}22250040')
    userEvent.click(screen.getByRole('button'))

    await waitFor(() => {
      expect(mockedOnSuccess).toHaveBeenCalledTimes(1)
    })
  })

  it('should apply the postal code mask when the input lose focus', () => {
    renderComponent({})
    const input = screen.getByRole('textbox', {
      name: /postal code/i,
    })

    userEvent.type(input, '222500')
    expect(input).toHaveValue('222500')

    userEvent.type(input, '4')
    expect(input).toHaveValue('2225004')

    userEvent.click(screen.getByRole('button'))
    expect(input).toHaveValue('22250-04')

    userEvent.type(input, '{selectall}2225004')
    expect(input).toHaveValue('2225004')

    userEvent.type(input, '{enter}')
    expect(input).toHaveValue('22250-04')
  })
})

```


[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 place-components/react/__tests__/LocationSearch.test.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render, screen, fireEvent, waitFor } from '@vtex/test-tools/react'
import { MockedResponse } from '@apollo/react-testing'
import { Address } from 'vtex.checkout-graphql'
import { AddressRules } from 'vtex.address-context/types'
import { AddressContextProvider } from 'vtex.address-context/AddressContext'

import LocationSearch from '../LocationSearch'
import { googleLogo } from '../__fixtures__/graphql/providerLogo.fixture'
import {
  noSuggestions,
  simpleSuggestions,
  simpleSuggestionWithoutToken,
} from '../__fixtures__/graphql/addressSuggestions.fixture'
import { simpleSuggestedAddress } from '../__fixtures__/graphql/address.fixture'
import { defaultSessionToken } from '../__fixtures__/graphql/sessionToken.fixture'

const UNTABABBLE = -1
const LABEL_MATCHER = /Address \(street, number, square\.\.\.\)/i

interface RenderComponentProps {
  address?: Address | null
  countries?: string[]
  rules?: AddressRules
  graphqlMocks?: MockedResponse[]
}

const defaultGraphqlMocks = [
  googleLogo,
  defaultSessionToken,
  // This duplication is intentional: the first one will be used during the
  // first query and the second one is used during the refetch. Currently,
  // Apollo provides not many good alternatives to do that. You can read
  // more about it on this issue:
  //  https://github.com/apollographql/apollo-client/issues/7286
  defaultSessionToken,
]

describe('Location Search', () => {
  const renderComponent = ({
    address = { country: 'BRA' },
    countries = [],
    rules = {},
    graphqlMocks = [],
  }: RenderComponentProps) => {
    return render(
      <AddressContextProvider
        address={address}
        countries={countries}
        rules={rules}
      >
        <LocationSearch />
      </AddressContextProvider>,
      {
        graphql: {
          mocks: [...defaultGraphqlMocks, ...graphqlMocks],
          addTypename: false,
        },
      }
    )
  }

  it('should be able to select a suggested address when a search term is found', async () => {
    renderComponent({
      graphqlMocks: [
        simpleSuggestions,
        simpleSuggestedAddress,
        simpleSuggestionWithoutToken,
      ],
    })

    const input = screen.getByLabelText(LABEL_MATCHER)

    fireEvent.change(input, { target: { value: 'Praia de Botafogo' } })

    expect(
      await screen.findByText('Praia de Botafogo, 200')
    ).toBeInTheDocument()
    expect(
      await screen.findByText('Praia de Botafogo, 300')
    ).toBeInTheDocument()

    fireEvent.click(screen.getByText('Praia de Botafogo, 200'))
    expect(input).toHaveValue(
      'Praia de Botafogo, 200, Botafogo, Rio de Janeiro, RJ'
    )

    // same as waiting loading to finish
    await waitFor(() => {
      expect(screen.queryByRole('button')).toBeInTheDocument()
    })
  })

  it('should be able to clear the input with clear button when something is typed', () => {
    renderComponent({ graphqlMocks: [simpleSuggestions] })

    expect(screen.queryByRole('button')).not.toBeInTheDocument()

    const input = screen.getByLabelText(LABEL_MATCHER)

    fireEvent.change(input, { target: { value: 'Praia de Botafogo' } })
    const button = screen.getByRole('button')

    expect(button.tabIndex).toBe(UNTABABBLE)

    fireEvent.click(button)

    expect(input).toHaveValue('')
    expect(screen.queryByRole('button')).not.toBeInTheDocument()
  })

  it('should be able to clear the input with ESC key when something is typed', () => {
    renderComponent({ graphqlMocks: [simpleSuggestions] })

    expect(screen.queryByRole('button')).not.toBeInTheDocument()

    const input = screen.getByLabelText(LABEL_MATCHER)

    fireEvent.change(input, { target: { value: 'Praia de Botafogo' } })
    fireEvent.keyDown(input, { key: 'Escape', code: 'Escape' })

    expect(input).toHaveValue('')
    expect(screen.queryByRole('button')).not.toBeInTheDocument()
  })

  it('should display failure message when the search term is not found', async () => {
    renderComponent({ graphqlMocks: [noSuggestions] })

    const input = screen.getByLabelText(LABEL_MATCHER)

    fireEvent.change(input, { target: { value: 'asdfasdfasdf' } })

    await waitFor(() => {
      expect(screen.queryByText('No results found')).toBeInTheDocument()
    })
  })

  it('should render provider logo', async () => {
    renderComponent({ graphqlMocks: [simpleSuggestions] })

    const input = screen.getByLabelText(LABEL_MATCHER)

    fireEvent.change(input, { target: { value: 'Praia de Botafogo' } })

    expect(await screen.findByAltText('Google logo')).toBeInTheDocument()
    fireEvent.blur(input)
  })
})

```


[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 place-components/react/__tests__/AddressForm.test.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { fireEvent, screen, render } from '@vtex/test-tools/react'
import { AddressContextProvider } from 'vtex.address-context/AddressContext'
import { createEmptyAddress } from 'vtex.address-context/Utils'

import AddressForm from '../AddressForm'
import { useAddressForm, FieldName } from '../useAddressForm'
import { braRules } from '../__fixtures__/addressRules.fixture'

describe('AddressForm', () => {
  it('should read address from context', () => {
    render(
      <AddressContextProvider
        address={{ ...createEmptyAddress(), country: 'BRA' }}
        rules={braRules}
        countries={['BRA']}
      >
        <AddressForm />
      </AddressContextProvider>
    )

    const numberInput = screen.getByLabelText(/^number$/i)

    expect(numberInput).toBeInTheDocument()

    fireEvent.change(numberInput, { target: { value: '300' } })

    expect(numberInput).toHaveValue('300')
  })

  it('should be able to act as controlled component', () => {
    const changes: any[] = []

    const Component: React.VFC = () => {
      const form = useAddressForm({
        initialAddress: { ...createEmptyAddress(), country: 'BRA' },
        onAddressChange: (address) => changes.push(address),
      })

      return (
        <>
          <AddressForm form={form} />
          <button
            onClick={() => {
              form.invalidFields.map((field) =>
                form.onFieldBlur(field as FieldName)
              )
            }}
          >
            blur fields
          </button>
        </>
      )
    }

    render(
      <AddressContextProvider
        address={{
          // this won't be used
          ...createEmptyAddress(),
          number: '123',
          country: 'BRA',
        }}
        rules={braRules}
        countries={['BRA']}
      >
        <Component />
      </AddressContextProvider>
    )

    const numberInput = screen.getByLabelText(/^number$/i)

    expect(numberInput).toBeInTheDocument()
    expect(numberInput).not.toHaveValue('123')

    fireEvent.change(numberInput, { target: { value: '321' } })

    expect(numberInput).toHaveValue('321')
    expect(changes).toStrictEqual([
      expect.objectContaining({
        number: '321',
      }),
    ])

    fireEvent.click(screen.getByText('blur fields'))

    expect(
      screen.getAllByText(/this field is required/i).length
    ).toBeGreaterThan(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 place-components/react/__tests__/DeviceCoordinates.test.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { fireEvent, render, screen, waitFor } from '@vtex/test-tools/react'
import { MockedProvider, MockedResponse } from '@apollo/react-testing'
import { Address } from 'vtex.checkout-graphql'
import { AddressRules } from 'vtex.address-context/types'
import { AddressContextProvider } from 'vtex.address-context/AddressContext'

import DeviceCoordinates, { GeolocationPosition } from '../DeviceCoordinates'
import { reverseGeocode } from '../__fixtures__/graphql/reverseGeocode.fixture'
import { vtexOfficeAddress } from '../__fixtures__/address.fixture'

interface RenderComponentProps {
  deviceCoordinatesProps?: React.ComponentProps<typeof DeviceCoordinates>
  address?: Address | null
  countries?: string[]
  rules?: AddressRules
  graphqlMocks?: MockedResponse[]
}

const defaultGraphqlMocks = [] as MockedResponse[]

describe('Device Coordinates', () => {
  const renderComponent = ({
    deviceCoordinatesProps,
    address = { country: 'BRA' },
    countries = [],
    rules = {},
    graphqlMocks = [],
  }: RenderComponentProps) => {
    return render(
      <MockedProvider
        addTypename={false}
        mocks={[...defaultGraphqlMocks, ...graphqlMocks]}
      >
        <AddressContextProvider
          address={address}
          countries={countries}
          rules={rules}
        >
          <DeviceCoordinates {...deviceCoordinatesProps} />
        </AddressContextProvider>
      </MockedProvider>
    )
  }

  afterEach(() => {
    jest.resetAllMocks()
  })

  describe('when geolocation is granted', () => {
    it('should get an address from coordinates', async () => {
      const callOrder: string[] = []

      const { query } = navigator.permissions
      const mockedPermissionsQuery = query as jest.MockedFunction<typeof query>

      mockedPermissionsQuery.mockImplementation((_permission) => {
        callOrder.push('permissions')

        return Promise.resolve({ state: 'granted' } as PermissionStatus)
      })

      Object.defineProperty(navigator, 'permissions', {
        get() {
          return { query: mockedPermissionsQuery }
        },
      })

      const { getCurrentPosition } = navigator.geolocation
      const mockedGetCurrentPosition = getCurrentPosition as jest.MockedFunction<
        typeof getCurrentPosition
      >

      mockedGetCurrentPosition.mockImplementation((success) => {
        callOrder.push('geolocation')

        return Promise.resolve(
          success({
            coords: {
              latitude: vtexOfficeAddress.geoCoordinates[0],
              longitude: vtexOfficeAddress.geoCoordinates[1],
            },
          } as GeolocationPosition)
        )
      })

      Object.defineProperty(navigator, 'geolocation', {
        get() {
          return { getCurrentPosition: mockedGetCurrentPosition }
        },
      })

      const mockedOnSuccess = jest.fn()

      renderComponent({
        deviceCoordinatesProps: { onSuccess: mockedOnSuccess },
        graphqlMocks: [reverseGeocode],
      })

      const button = screen.getByRole('button')

      fireEvent.click(button)

      expect(mockedPermissionsQuery).toHaveBeenCalledTimes(1)
      expect(mockedGetCurrentPosition).toHaveBeenCalledTimes(1)
      expect(callOrder).toEqual(['permissions', 'geolocation'])
      await waitFor(() => {
        expect(mockedOnSuccess).toHaveBeenCalledTimes(1)
      })
    })

    it("should get an address from coordinates on a browser that doesn't support navigator.permissions", async () => {
      Object.defineProperty(navigator, 'permissions', {
        get() {
          return undefined
        },
      })

      const { getCurrentPosition } = navigator.geolocation
      const mockedGetCurrentPosition = getCurrentPosition as jest.MockedFunction<
        typeof getCurrentPosition
      >

      mockedGetCurrentPosition.mockImplementation((success) =>
        Promise.resolve(
          success({
            coords: {
              latitude: vtexOfficeAddress.geoCoordinates[0],
              longitude: vtexOfficeAddress.geoCoordinates[1],
            },
          } as GeolocationPosition)
        )
      )

      Object.defineProperty(navigator, 'geolocation', {
        get() {
          return { getCurrentPosition: mockedGetCurrentPosition }
        },
      })

      const mockedOnSuccess = jest.fn()

      renderComponent({
        deviceCoordinatesProps: { onSuccess: mockedOnSuccess },
        graphqlMocks: [reverseGeocode],
      })

      const button = screen.getByRole('button')

      fireEvent.click(button)

      expect(mockedGetCurrentPosition).toHaveBeenCalledTimes(1)
      await waitFor(() => {
        expect(mockedOnSuccess).toHaveBeenCalledTimes(1)
      })
    })
  })

  // TODO
  describe('when geolocation is blocked', () => {})

  // TODO
  describe('when geolocation is prompt', () => {})
})

```


[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 place-components/react/graphql/address.graphql from the place-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Address($externalId: String!, $sessionToken: String) {
  address(externalId: $externalId, sessionToken: $sessionToken)
    @context(provider: "vtex.geolocation-graphql-interface") {
    addressId
    addressType
    city
    complement
    country
    geoCoordinates
    neighborhood
    number
    postalCode
    reference
    state
    street
  }
}

```


[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 place-components/react/graphql/addressSuggestions.graphql from the place-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query AddressSuggestions(
  $searchTerm: String!
  $sessionToken: String
  $country: String
) {
  addressSuggestions(
    searchTerm: $searchTerm
    sessionToken: $sessionToken
    country: $country
  ) @context(provider: "vtex.geolocation-graphql-interface") {
    description
    mainText
    mainTextMatchInterval {
      offset
      length
    }
    secondaryText
    externalId
  }
}

```


[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 place-components/react/graphql/getAddressFromPostalCode.graphql from the place-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query GetAddressFromPostalCode($postalCode: String, $countryCode: String) {
  getAddressFromPostalCode(postalCode: $postalCode, countryCode: $countryCode) {
    addressId
    addressType
    city
    complement
    country
    geoCoordinates
    neighborhood
    number
    postalCode
    reference
    state
    street
  }
}

```


[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 place-components/react/graphql/reverseGeocode.graphql from the place-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query ReverseGeocode($lat: String, $lng: String) {
  reverseGeocode(lat: $lat, lng: $lng) {
    addressId
    addressType
    city
    complement
    country
    geoCoordinates
    neighborhood
    number
    postalCode
    reference
    state
    street
  }
}

```


[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 place-components/react/graphql/sessionToken.graphql from the place-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query SessionToken {
  sessionToken @context(provider: "vtex.geolocation-graphql-interface")
}

```


[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 place-components/react/graphql/providerLogo.graphql from the place-components VTEX app.

[Assistant]
Here's the implementation:

```graphql
query ProviderLogo {
  providerLogo @context(provider: "vtex.geolocation-graphql-interface") {
    src
    alt
  }
}

```


[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 place-components/react/countries/rules.ts from the place-components VTEX app.

[Assistant]
Here's the implementation:

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

export const styleRules: {
  [key: string]: CSSProperties
} = {
  complement: {
    minWidth: 199,
    maxWidth: 512,
  },
  number: {
    minWidth: 71,
    maxWidth: 128,
  },
  numberOption: {
    minWidth: 256,
    maxWidth: 256,
  },
  streetRoadAvenue: {
    minWidth: 256,
    maxWidth: 512,
  },
  neighborhood: {
    minWidth: 256,
    maxWidth: 256,
  },
  addressLine1: {
    minWidth: 256,
    maxWidth: 512,
  },
  addressLine2: {
    minWidth: 256,
    maxWidth: 512,
  },
  city: {
    minWidth: 199,
    maxWidth: 256,
  },
  canton: {
    minWidth: 256,
    maxWidth: 256,
  },
  province: {
    minWidth: 128,
    maxWidth: 256,
  },
  address: {
    minWidth: 256,
    maxWidth: 512,
  },
  town: {
    minWidth: 256,
    maxWidth: 256,
  },
  county: {
    minWidth: 256,
    maxWidth: 256,
  },
  interiorNo: {
    minWidth: 256,
    maxWidth: 256,
  },
  exteriorNoOption: {
    minWidth: 256,
    maxWidth: 256,
  },
  colony: {
    minWidth: 256,
    maxWidth: 256,
  },
  municipalityDelegation: {
    minWidth: 256,
    maxWidth: 256,
  },
  stateAbbreviation: {
    minWidth: 128,
    maxWidth: 128,
  },
  state: {
    minWidth: 256,
    maxWidth: 256,
  },
  locality: {
    minWidth: 256,
    maxWidth: 256,
  },
  deliveryInstructions: {
    minWidth: 256,
    maxWidth: 512,
  },
  department: {
    minWidth: 256,
    maxWidth: 256,
  },
  addressLine3: {
    minWidth: 256,
    maxWidth: 512,
  },
  parish: {
    minWidth: 256,
    maxWidth: 256,
  },
}

```


[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 place-components/react/__fixtures__/graphql/addressSuggestions.fixture.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import {
  Query,
  QueryAddressSuggestionsArgs,
} from 'vtex.geolocation-graphql-interface'
import { MockedResponse } from '@apollo/react-testing'

import ADDRESS_SUGGESTIONS from '../../graphql/addressSuggestions.graphql'
import { DEFAULT_SESSION_TOKEN } from './sessionToken.fixture'

export const simpleSuggestions: MockedResponse = {
  request: {
    query: ADDRESS_SUGGESTIONS,
    variables: {
      searchTerm: 'Praia de Botafogo',
      sessionToken: DEFAULT_SESSION_TOKEN,
      country: 'BRA',
    } as QueryAddressSuggestionsArgs,
  },
  result: {
    data: {
      addressSuggestions: [
        {
          description: 'Praia de Botafogo, 200, Botafogo, Rio de Janeiro, RJ',
          mainText: 'Praia de Botafogo, 200',
          mainTextMatchInterval: {
            offset: 0,
            length: 0,
          },
          secondaryText: 'Botafogo, Rio de Janeiro, RJ',
          externalId: '1',
        },
        {
          description: 'Praia de Botafogo, 300, Botafogo, Rio de Janeiro, RJ',
          mainText: 'Praia de Botafogo, 300',
          mainTextMatchInterval: {
            offset: 0,
            length: 0,
          },
          secondaryText: 'Botafogo, Rio de Janeiro, RJ',
          externalId: '2',
        },
      ],
    } as Query,
  },
}

export const simpleSuggestionWithoutToken: MockedResponse = {
  ...simpleSuggestions,
  request: {
    ...simpleSuggestions.request,
    variables: {
      ...simpleSuggestions.request.variables,
      sessionToken: null,
    } as QueryAddressSuggestionsArgs,
  },
}

export const noSuggestions: MockedResponse = {
  request: {
    query: ADDRESS_SUGGESTIONS,
    variables: {
      searchTerm: 'asdfasdfasdf',
      sessionToken: DEFAULT_SESSION_TOKEN,
      country: 'BRA',
    } as QueryAddressSuggestionsArgs,
  },
  result: {
    data: {
      addressSuggestions: [] as Query['addressSuggestions'],
    } as Query,
  },
}

```


[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 place-components/react/__fixtures__/graphql/reverseGeocode.fixture.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { MockedResponse } from '@apollo/react-testing'
import { Query, QueryReverseGeocodeArgs } from 'vtex.places-graphql'

import { vtexOfficeAddress } from '../address.fixture'
import REVERSE_GEOCODE_QUERY from '../../graphql/reverseGeocode.graphql'

const [lat, lng] = vtexOfficeAddress.geoCoordinates.map((coordinate) =>
  coordinate.toString()
)

export const reverseGeocode: MockedResponse = {
  request: {
    query: REVERSE_GEOCODE_QUERY,
    variables: {
      lat,
      lng,
    } as QueryReverseGeocodeArgs,
  },
  result: {
    data: {
      reverseGeocode: vtexOfficeAddress,
    } as Query,
  },
}

```


[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 place-components/react/__fixtures__/graphql/sessionToken.fixture.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { Query } from 'vtex.geolocation-graphql-interface'
import { MockedResponse } from '@apollo/react-testing'

import SESSION_TOKEN from '../../graphql/sessionToken.graphql'

export const DEFAULT_SESSION_TOKEN = 'default session token'

export const defaultSessionToken: MockedResponse = {
  request: {
    query: SESSION_TOKEN,
  },
  result: {
    data: {
      sessionToken: DEFAULT_SESSION_TOKEN,
    } as Query,
  },
}

```


[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 place-components/react/__fixtures__/graphql/providerLogo.fixture.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { Query } from 'vtex.geolocation-graphql-interface'
import { MockedResponse } from '@apollo/react-testing'

import PROVIDER_LOGO from '../../graphql/providerLogo.graphql'

export const googleLogo: MockedResponse = {
  request: {
    query: PROVIDER_LOGO,
  },
  result: {
    data: {
      providerLogo: {
        src:
          'https://user-images.githubusercontent.com/26108090/100493516-45802680-3116-11eb-9028-06c336a587a7.png',
        alt: 'Google logo',
      },
    } as Query,
  },
}

```


[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 place-components/react/__fixtures__/graphql/getAddressFromPostalCode.fixture.ts from the place-components VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { Query, QueryGetAddressFromPostalCodeArgs } from 'vtex.places-graphql'
import { MockedResponse } from '@apollo/react-testing'

import GET_ADDRESS_FROM_POSTAL_CODE from '../../graphql/getAddressFromPostalCode.graphql'

export const validPostalCode: MockedResponse = {
  request: {
    query: GET_ADDRESS_FROM_POSTAL_CODE,
    variables: {
      countryCode: 'BRA',
      postalCode: '22250-040',
    } as QueryGetAddressFromPostalCodeArgs,
  },
  result: {
    data: {
      getAddressFromPostalCode: {
        addressId: null,
        addressType: null,
        city: 'Rio de Janeiro',
        complement: '',
        country: 'BRA',
        geoCoordinates: [-43.18218231201172, -22.94549560546875],
        neighborhood: 'Botafogo',
        number: '',
        postalCode: '22250040',
        receiverName: null,
        reference: '',
        state: 'RJ',
        street: 'Praia Botafogo',
      },
    } as Query,
  },
}

```


[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 place-components/react/__fixtures__/graphql/address.fixture.tsx from the place-components VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { Query, QueryAddressArgs } from 'vtex.geolocation-graphql-interface'
import { MockedResponse } from '@apollo/react-testing'

import ADDRESS from '../../graphql/address.graphql'
import { DEFAULT_SESSION_TOKEN } from './sessionToken.fixture'
import { vtexOfficeAddress } from '../address.fixture'

export const simpleSuggestedAddress: MockedResponse = {
  request: {
    query: ADDRESS,
    variables: {
      externalId: '1',
      sessionToken: DEFAULT_SESSION_TOKEN,
    } as QueryAddressArgs,
  },
  result: {
    data: {
      address: vtexOfficeAddress,
    } as Query,
  },
}

```


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

[Assistant]
Here's the implementation:

```markdown
# Broadcaster Adapter

App in VTEX IO designed to adapat broadcaster catalog changes to an event in IO's Events system.

### How it works?

The broadcaster adapter will recieve a POST request with the data of the SKU that changed and then it will push an event to the Event system to broadcast to apps that want to listen to this changes.

### Testing

You can do a `POST` request to
`app.io.vtex.com/vtex.broadcaster-adapter/v0/{{account}}/{{workspace}}/notify`
with the body:
```
{
	"HasStockKeepingUnitModified": "true",
	"IdSku": {{SKU 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 broadcaster-adapter/node/service.json from the broadcaster-adapter VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 128,
  "ttl": 10,
  "timeout": 2,
  "minReplicas": 2,
  "maxReplicas": 10,
  "workers": 4,
  "routes": {
    "notify": {
      "path": "/notify",
      "public": 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 broadcaster-adapter/node/package.json from the broadcaster-adapter VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "co-body": "^6.0.0"
  },
  "devDependencies": {
    "@types/co-body": "^0.0.3",
    "@types/node": "12.x",
    "@vtex/api": "6.17.0",
    "eslint": "^6.3.0",
    "eslint-config-vtex": "^11.0.0",
    "prettier": "^1.18.2",
    "typescript": "3.8.3"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty && eslint -c .eslintrc.json --fix './**/*.ts'"
  },
  "version": "0.0.1"
}

```


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

[User] Show me the implementation of broadcaster-adapter/node/typings.ts from the broadcaster-adapter VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { RecorderState, IOClients, ServiceContext, ParamsContext } from '@vtex/api'

declare global {
  type Context = ServiceContext<IOClients, State, ParamsContext>

  interface State extends RecorderState, BroadcasterEvent {
    payload: BroadcasterEvent
  }

  interface BroadcasterEvent {
    HasStockKeepingUnitModified: boolean
    IdSku: string
  }

  type ID = string
  type Float = number
  type Int = number
}

```


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

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

[Assistant]
Here's the implementation:

```typescript
export const ENABLED_GLOBALLY = false

export const BROADCASTER_NOTIFICATION = 'broadcaster.notification'
```


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

[Assistant]
Here's the implementation:

```typescript
import { Service, IOClients, ParamsContext, method } from '@vtex/api'

import { parseAndValidate } from './middlewares/parse'
import { throttle } from './middlewares/throttle'
import { pushNotification } from './middlewares/pushNotification'

const TREE_SECONDS_MS = 3 * 1000
const CONCURRENCY = 10

export default new Service<IOClients, State, ParamsContext>({
  clients: {
    options: {
      events: {
        exponentialTimeoutCoefficient: 2,
        exponentialBackoffCoefficient: 2,
        initialBackoffDelay: 50,
        retries: 1,
        timeout: TREE_SECONDS_MS,
        concurrency: CONCURRENCY,
      }
    },
  },
  routes: {
    notify: method({
      POST: [throttle, parseAndValidate, pushNotification],
    }),
  }
})

```


[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 broadcaster-adapter/node/middlewares/pushNotification.ts from the broadcaster-adapter VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { BROADCASTER_NOTIFICATION } from './../constants'

export async function pushNotification(ctx: Context, next: () => Promise<any>) {
  const { clients: { events } } = ctx

  await events.sendEvent('', BROADCASTER_NOTIFICATION, ctx.state.payload)
  ctx.status = 200

  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 broadcaster-adapter/node/middlewares/throttle.ts from the broadcaster-adapter VTEX app.

[Assistant]
Here's the implementation:

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

const MAX_REQUEST = 50
let COUNTER = 0

export async function throttle(
  _: Context,
  next: () => Promise<void>
) {
  COUNTER++
  try {
    if (COUNTER > MAX_REQUEST) {
      throw new TooManyRequestsError()
    }
    await next()
  } finally {
    COUNTER--
  }
}
```


[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 broadcaster-adapter/node/middlewares/parse.ts from the broadcaster-adapter VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { json } from 'co-body'
import { ENABLED_GLOBALLY } from './../constants'

export async function parseAndValidate(ctx: Context, next: () => Promise<any>) {
  if (!ENABLED_GLOBALLY) {
    ctx.body = 'Service not enabled.'
    ctx.status = 200
    return
  }

  const body = (await json(ctx.req)) as BroadcasterEvent

  // Temporary if, in the near future broadcaster will only notify us modifications in SKUs or product.
  if (!body.HasStockKeepingUnitModified) {
    ctx.status = 204
    return
  }

  ctx.state.payload = body

  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 shipping-estimate-translator/test-utils/index.js from the shipping-estimate-translator VTEX app.

[Assistant]
Here's the implementation:

```javascript
import React from 'react'
import { IntlProvider } from 'react-intl'
import { render } from 'react-testing-library'
import messages from '../messages/en.json'

const renderWithIntl = node => {
  return render(
    <IntlProvider locale="en" defaultLocale="en" messages={messages}>
      {node}
    </IntlProvider>
  )
}

export * from 'react-testing-library'

export { renderWithIntl }

```


[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 shipping-estimate-translator/messages/sl.json from the shipping-estimate-translator VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "shippingEstimate-bd": "{timeAmount, plural, =0 {Danes} one {V # delovnem dnevu} two {Do # delovnih dni} few {Do # delovnih dni} other {Do # delovnih dni}}",
  "shippingEstimate-d": "{timeAmount, plural, =0 {Danes} one {V # dnevu} two {Do # dneh} few {Do # dni} other {Do # dni}}",
  "shippingEstimate-h": "{timeAmount, plural, =0 {Zdaj} one {V # uri} two {Do # ur} few {Do # ur} other {Do # ur}}",
  "shippingEstimate-m": "{timeAmount, plural, =0 {Zdaj} one {V # minuti} two {Do # minut} few {Do # minut} other {Do # minut}}",
  "shippingEstimate-scheduled": "{date}, med {startDate} in {endDate}",
  "shippingEstimate-scheduled-no-dates": "Načrtovano",
  "shippingEstimatePickup-bd": "{timeAmount, plural, =0 {Pripravljeno danes} one {Pripravljeno v # delovnem dnevu} two {Pripravljeno v # delovnih dneh} few {Pripravljeno v # delovnih dneh} other {Pripravljeno v # delovnih dneh}}",
  "shippingEstimatePickup-d": "{timeAmount, plural, =0 {Pripravljeno danes} one {Pripravljeno v # delovnem dnevu} two {Pripravljeno v # delovnih dneh} few {Pripravljeno v # delovnih dneh} other {Pripravljeno v # delovnih dneh}}",
  "shippingEstimatePickup-h": "{timeAmount, plural, =0 {Pripravljeno za prevzem} one {Pripravljeno v do # uri} two {Pripravljeno v do # urah} few {Pripravljeno v do # urah} other {Pripravljeno v do # urah}}",
  "shippingEstimatePickup-m": "{timeAmount, plural, =0 {Pripravljeno za prevzem} one {Pripravljeno v do # minuti} two {Pripravljeno v do # minutah} few {Pripravljeno v do # minutah} other {Pripravljeno v do # minutah}}"
}

```


[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 shipping-estimate-translator/messages/hu.json from the shipping-estimate-translator VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "shippingEstimate-bd": "{timeAmount, plural, =0 {Ma} one {# munkanapon belül} other {Legfeljebb # munkanapon belül}}",
  "shippingEstimate-d": "{timeAmount, plural, =0 {Ma} one {# napon belül} other {Legfeljebb # napon belül}}",
  "shippingEstimate-h": "{timeAmount, plural, =0 {Most} one {# órán belül} other {Legfeljebb # órán belül}}",
  "shippingEstimate-m": "{timeAmount, plural, =0 {Most} one {# percen belül} other {Legfeljebb # percen belül}}",
  "shippingEstimate-scheduled": "{date}, {startDate} és {endDate} között",
  "shippingEstimate-scheduled-no-dates": "Ütemezett",
  "shippingEstimatePickup-bd": "{timeAmount, plural, =0 {Kész ma} one {Kész # munkanapon belül} other {Kész # munkanapon belül}}",
  "shippingEstimatePickup-d": "{timeAmount, plural, =0 {Kész ma} one {Kész # napon belül} other {Kész # napon belül}}",
  "shippingEstimatePickup-h": "{timeAmount, plural, =0 {Kész az átvételre} one {Kész # órán belül} other {Kész # órán belül}}",
  "shippingEstimatePickup-m": "{timeAmount, plural, =0 {Kész az átvételre} one {Kész # percen belül} other {Kész # percen belül}}"
}

```


[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 shipping-estimate-translator/messages/nl.json from the shipping-estimate-translator VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "shippingEstimate-bd": "{timeAmount, plural, =0 {Vandaag} one {In # werkdag} other {Tot # werkdagen}}",
  "shippingEstimate-d": "{timeAmount, plural, =0 {Vandaag} one {In # dag} other {Tot # dagen}}",
  "shippingEstimate-h": "{timeAmount, plural, =0 {Nu} one {In # uur} other {Tot # uren}}",
  "shippingEstimate-m": "{timeAmount, plural, =0 {Nu} one {In # minuut} other {Tot # minuten}}",
  "shippingEstimate-scheduled": "{date}, tussen {startDate} en {endDate}",
  "shippingEstimate-scheduled-no-dates": "Gepland",
  "shippingEstimatePickup-bd": "{timeAmount, plural, =0 {Klaar vandaag} one {Klaar in # werkdag} other {Klaar in # werkdagen}}",
  "shippingEstimatePickup-d": "{timeAmount, plural, =0 {Klaar vandaag} one {Klaar in tot # dag} other {Klaar in tot # dagen}}",
  "shippingEstimatePickup-h": "{timeAmount, plural, =0 {Klaar om af te halen} one {Klaar in maximaal # uur} other {Klaar in maximaal # uren}}",
  "shippingEstimatePickup-m": "{timeAmount, plural, =0 {Klaar om af te halen} one {Klaar in # minuut} other {Klaar in maximaal # minuten}}"
}

```


[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 shipping-estimate-translator/messages/ja.json from the shipping-estimate-translator VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "shippingEstimate-bd": "{timeAmount, plural, =0 {今日} one {# 営業日} other {最大 # 営業日}}",
  "shippingEstimate-d": "{timeAmount, plural, =0 {今日} one {# 日} other {最大 # 日}}",
  "shippingEstimate-h": "{timeAmount, plural, =0 {今} one {# 時間} other {最大 # 時間}}",
  "shippingEstimate-m": "{timeAmount, plural, =0 {今} one {# 分間} other {最大 # 分間}}",
  "shippingEstimate-scheduled": "{date}, {startDate} と {endDate} の間",
  "shippingEstimate-scheduled-no-dates": "スケジュール済み",
  "shippingEstimatePickup-bd": "{timeAmount, plural, =0 {今日で準備完了} one {最大 # 営業日で準備完了} other {最大 # 営業日で準備完了}}",
  "shippingEstimatePickup-d": "{timeAmount, plural, =0 {今日で準備完了} one {最大 # 日で準備完了} other {最大 # 日で準備完了}}",
  "shippingEstimatePickup-h": "{timeAmount, plural, =0 {ピックアップの準備完了} one {最大 # 時間で準備完了} other {最大 # 時間で準備完了}}",
  "shippingEstimatePickup-m": "{timeAmount, plural, =0 {ピックアップの準備完了} one {最大 # 分間で準備完了} other {最大 # 分間で準備完了}}"
}

```


[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 shipping-estimate-translator/messages/de.json from the shipping-estimate-translator VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "shippingEstimate-bd": "{timeAmount, plural, =0 {Heute} one {In # Werktag} other {Bis zu # Werktagen}}",
  "shippingEstimate-d": "{timeAmount, plural, =0 {Heute} one {In # Tag} other {Bis zu # Tage}}",
  "shippingEstimate-h": "{timeAmount, plural, =0 {Jetzt} one {In # Stunden} other {Bis zu # Stunden}}",
  "shippingEstimate-m": "{timeAmount, plural, =0 {Jetzt} one {In # Minute} other {Bis zu # Minuten}}",
  "shippingEstimate-scheduled": "{date}, zwischen {startDate} und {endDate}",
  "shippingEstimate-scheduled-no-dates": "Geplant",
  "shippingEstimatePickup-bd": "{timeAmount, plural, =0 {Heute fertig} one {Fertig in # Werktag} other {Fertig in # Werktagen}}",
  "shippingEstimatePickup-d": "{timeAmount, plural, =0 {Heute fertig} one {Fertig in # Tag} other {Fertig in # Tagen}}",
  "shippingEstimatePickup-h": "{timeAmount, plural, =0 {Abholbereit} one {Abholbereit in # Stunde} other {Abholbereit in # Stunden}}",
  "shippingEstimatePickup-m": "{timeAmount, plural, =0 {Abholbereit} one {Fertig in # Minute} other {Fertig in # Minuten}}"
}

```