[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 pickup-availability/react/typings/global.d.ts from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'google.maps' {
  export * from '@types/googlemaps'
}

```


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

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  const css: any
  export default css
}

```


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

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

[Assistant]
Here's the implementation:

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

  const value: DocumentNode
  export default value
}

declare module '*.gql' {
  const gql: any
  export default gql
}

```


[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 pickup-availability/react/typings/ContextState.d.ts from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```typescript
type Actions =
  | { type: 'SET_COORDS'; args: { coords: Coords } }
  | { type: 'PICKUP_CHANGE_REQUEST' }
  | { type: 'PICKUP_CHANGE_DONE' }

type DispatchFn = Dispatch<Actions>

interface Coords {
  lat: string | null
  long: string | null
}

interface ContextState {
  coords: Coords
  pickupChangeLoading: boolean
}

```


[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 pickup-availability/react/typings/skuPickupType.d.ts from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

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

type SessionAddress = Omit<CheckoutAddress, 'geoCoordinates'> & {
  geoCoordinate: [number, number]
}

interface SkuPickupStore {
  cacheId: string
  id: string
  shippingEstimate: string | null
  pickupStoreInfo: {
    friendlyName: string
    address: CheckoutAddress
  }
}

interface FavoritePickup {
  name: string
  address: CheckoutAddress
}

```


[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 pickup-availability/react/typings/vtex.styleguide.d.ts from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.styleguide' {
  import { ComponentType } from 'react'

  export const Input: ComponentType<InputProps>
  export const Spinner: ComponentType<InputProps>

  interface InputProps {
    [key: string]: any
  }

  export const Button: ComponentType<{
    onClick: () => void
    variation?: string
    size?: string
  }>

  export const Modal: ComponentType<{
    onClose: () => void
    isOpen: boolean
    centered: boolean
    title?: string
  }>

  export const Radio: ComponentType<{
    checked: boolean
    onChange: () => void
    id: string
    label: string
    name: string
    value: string
  }>
}

```


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

[User] Show me the implementation of pickup-availability/react/queries/logistics.gql from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```graphql
query logistics {
  logistics {
    googleMapsKey
  }
}

```


[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 pickup-availability/react/queries/skuPickupSLAs.gql from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```graphql
query SkuPickupSLAs(
  $itemId: String
  $seller: String
  $lat: String
  $long: String
  $country: String
) {
  skuPickupSLAs(
    itemId: $itemId
    seller: $seller
    long: $long
    lat: $lat
    country: $country
  ) {
    id
    shippingEstimate
    pickupStoreInfo {
      friendlyName
      address {
        street
        number
        cacheId
        addressId
        complement
        neighborhood
        country
        state
        geoCoordinates
        postalCode
        city
      }
    }
  }
}

```


[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 pickup-availability/react/queries/skuPickupSLA.gql from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```graphql
query SkupPickupSLA(
  $itemId: String
  $seller: String
  $lat: String
  $long: String
  $country: String
  $pickupId: String
) {
  skuPickupSLA(
    itemId: $itemId
    seller: $seller
    long: $long
    lat: $lat
    country: $country
    pickupId: $pickupId
  ) {
    id
    shippingEstimate
    pickupStoreInfo {
      friendlyName
      address {
        street
        number
        cacheId
        addressId
        complement
        neighborhood
        country
        state
        geoCoordinates
        postalCode
        city
      }
    }
  }
}

```


[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 pickup-availability/react/components/StoreSelectedQuery.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { useQuery } from 'react-apollo'
import useProduct from 'vtex.product-context/useProduct'
import { Button } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'

import skuPickupSLA from '../queries/skuPickupSLA.gql'

import StorePickupItem from './StorePickupItem'
import ItemLoader from './Loaders/ItemLoader'

const CSS_HANDLES = ['storeSelectedContainer', 'availabilityHeader', 'chooseDifferentStoreButton', 'chooseDifferentStoreButtonText'] as const

interface SkuPickupSLAData {
  skuPickupSLA: SkuPickupStore
}

interface Variables {
  itemId?: string
  seller?: string
  lat: string
  long: string
  country: string
  pickupId: string
}

interface Props {
  pickup: FavoritePickup
  onChangeStoreClick: () => void
}

const getVariablesFromSessionPickup = (pickup: FavoritePickup) => {
  const { geoCoordinates, country, addressId } = pickup.address
  const [long, lat] = geoCoordinates
  return {
    long: long.toString(),
    lat: lat.toString(),
    country: country,
    pickupId: addressId
  }
}

const createSlaFromSessionPickup = (pickup: FavoritePickup) => {
  return {
    cacheId: pickup.address.addressId,
    id: pickup.address.addressId,
    shippingEstimate: null,
    pickupStoreInfo: {
      friendlyName: pickup.name,
      address: pickup.address,
    }
  }
}

const StoreSelectedQuery: FC<Props> = ({ pickup, onChangeStoreClick }) => {
  const { selectedItem } = useProduct()
  const { long, lat, country, pickupId } = getVariablesFromSessionPickup(pickup)
  const handles = useCssHandles(CSS_HANDLES)

  const { error, data, loading } = useQuery<SkuPickupSLAData, Variables>(skuPickupSLA, {
    ssr: false,
    skip: !selectedItem,
    variables: {
      itemId: selectedItem?.itemId,
      seller: selectedItem?.sellers?.[0]?.sellerId,
      lat,
      long,
      country,
      pickupId,
    }
  })

  if (error || !selectedItem) {
    return null
  }
  const store = !loading && data?.skuPickupSLA ? data.skuPickupSLA : createSlaFromSessionPickup(pickup)
  return (
    <div className={`flex flex-column ${handles.storeSelectedContainer}`}>
      <div className="mh2">
        <div className={`t-body c-muted-2 mv3 ${handles.availabilityHeader}`}>
          <FormattedMessage id="store/pickup-availability.availability-header" />
        </div>
        {!loading ? <StorePickupItem store={store} /> : <ItemLoader />}
      </div>
      <div className={handles.chooseDifferentStoreButton}>
        <Button variation="tertiary" onClick={onChangeStoreClick} size="small">
          <div className={`${handles.chooseDifferentStoreButtonText} t-body nh4`}>
            <FormattedMessage id="store/pickup-availability.choose-different" />
          </div>
        </Button>
      </div>
    </div>
  )
}

export default StoreSelectedQuery

```


[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 pickup-availability/react/components/AddressWithList.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useReducer, useCallback, useMemo } from 'react'
import { Spinner } from 'vtex.styleguide'

import AddressInput from './AddressInput'
import StoreListQuery from './StoreListQuery'
import AddressBarLoader from './Loaders/AddressBarLoader'

interface Props {
  selectedAddressId: string | undefined
  googleMapsKey: string
  onPickupChange: (pickup?: FavoritePickup) => void
}

const LoadingOverlay: FC<{ loading: boolean }> = ({ children, loading }) => {
  return (
    <div className="relative justify-center flex-column">
      {loading && <div className="absolute w-100 h-100 z-2" style={{ background: 'rgba(255, 255, 255, .6)' }}>
        <div className="absolute top-0 bottom-0 left-0 right-0 flex justify-center items-center">
          <Spinner />
        </div>
      </div>}
      {children}
    </div>
  )
}

const intialState = {
  coords: { lat: null, long: null },
  pickupChangeLoading: false,
}

function reducer(state: ContextState, action: Actions): ContextState {
  switch (action.type) {
    case 'SET_COORDS': {
      return {
        ...state,
        coords: action.args.coords,
      }
    }
    case 'PICKUP_CHANGE_REQUEST': {
      return {
        ...state,
        pickupChangeLoading: true,
      }
    }
    case 'PICKUP_CHANGE_DONE': {
      return {
        ...state,
        pickupChangeLoading: false,
      }
    }
    default:
      return state
  }
}

const AddressWithList: FC<Props> = ({ googleMapsKey, selectedAddressId, onPickupChange }) => {
  const [state, dispatch] = useReducer(reducer, intialState)

  const onPlaceSelected = useCallback((place: google.maps.places.PlaceResult) => {
    const { geometry } = place
    if (!geometry) {
      // do nothing for now
      return
    }
    dispatch({
      type: 'SET_COORDS',
      args: {
        coords: {
          lat: geometry.location.lat().toString(),
          long: geometry.location.lng().toString(),
        }
      }
    })
  }, [])

  const onCurrentPositionReceived = useCallback(({
    lat,
    long,
  }: Coords) => {
    dispatch({
      type: 'SET_COORDS',
      args: {
        coords: {
          lat,
          long,
        }
      }
    })
  }, [])

  const loadingElement = useMemo(() => <AddressBarLoader />, [])

  return (
    <div>
      <AddressInput
        googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${googleMapsKey}&v=3.exp&libraries=places`}
        loadingElement={loadingElement}
        onPlaceSelected={onPlaceSelected}
        onCurrentPositionReceived={onCurrentPositionReceived}
        googleMapsKey={googleMapsKey}
      />
      <LoadingOverlay loading={state.pickupChangeLoading}>
        <StoreListQuery
          coords={state.coords}
          selectedAddressId={selectedAddressId}
          onPickupChange={onPickupChange}
          dispatch={dispatch}
        />
      </LoadingOverlay>
    </div>

  )
}

export default AddressWithList
```


[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 pickup-availability/react/components/LocationInputIcon.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

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

import { IconLocationInput } from 'vtex.store-icons'

interface Props {
  onClick: (e: any) => void
}

const LocationInputIcon: FC<Props> = ({ onClick }) => {
  return (
    <span
      onClick={onClick}
      className="pointer c-action-primary"
    >
      <IconLocationInput size={18} viewBox="0 0 18 18" />
    </span>
  )
}

export default LocationInputIcon

```


[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 pickup-availability/react/components/ReactGooogleAutocomplete.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { RefObject } from 'react'
import { Input, Spinner } from 'vtex.styleguide'
import { injectIntl, InjectedIntlProps } from 'react-intl'

import LocationInputIcon from './LocationInputIcon'

/*

Based on: https://github.com/ErrorPro/react-google-autocomplete/blob/master/src/index.js

*/

type AutocompletionRequest = google.maps.places.AutocompletionRequest
interface Props {
  isLoading: boolean
  types?: AutocompletionRequest['types']
  componentRestrictions?: AutocompletionRequest['componentRestrictions']
  bounds?: AutocompletionRequest['bounds']
  onPlaceSelected: (place: google.maps.places.PlaceResult) => void
  value?: string
  errorMessage?: string
  onChange?: (e: any) => void
  onSuffixPress: (e: any) => void
  isFetchingPosition: boolean
}

class ReactGoogleAutocomplete extends React.Component<Props & InjectedIntlProps> {
  input: RefObject<HTMLInputElement>
  autocomplete: google.maps.places.Autocomplete | null
  event: google.maps.MapsEventListener | null

  constructor(props: Props & InjectedIntlProps) {
    super(props)
    this.input = React.createRef()
    this.autocomplete = null
    this.event = null
  }

  componentDidMount() {
    if (!this.props.isLoading) {
      this.setup()
    }
  }

  setup = () => {
    if (!this.input.current) {
      return
    }
    const { types = ['(cities)'], componentRestrictions, bounds } = this.props
    const config = {
      types,
      bounds,
    } as google.maps.places.AutocompleteOptions

    if (componentRestrictions) {
      config.componentRestrictions = componentRestrictions
    }

    this.disableAutofill()

    this.autocomplete = new google.maps.places.Autocomplete(
      this.input.current,
      config
    )

    this.event = this.autocomplete.addListener(
      'place_changed',
      this.onSelected.bind(this)
    )
  }

  componentDidUpdate(prevProps: Props) {
    if (prevProps.isLoading && !this.props.isLoading) {
      this.setup()
    }
  }

  disableAutofill() {
    // Autofill workaround adapted from https://stackoverflow.com/questions/29931712/chrome-autofill-covers-autocomplete-for-google-maps-api-v3/49161445#49161445
    if ((window as any).MutationObserver) {
      const observerHack = new MutationObserver(() => {
        observerHack.disconnect()
        if (this.input.current) {
          this.input.current.autocomplete = 'disable-autofill'
        }
      })
      if (this.input.current) {
        observerHack.observe(this.input.current, {
          attributes: true,
          attributeFilter: ['autocomplete'],
        })
      }
    }
  }

  componentWillUnmount() {
    this.event && this.event.remove()
  }

  onSelected() {
    if (this.autocomplete && this.props.onPlaceSelected) {
      this.props.onPlaceSelected(this.autocomplete.getPlace())
    }
  }

  render() {
    const {
      value,
      errorMessage,
      onChange,
      onSuffixPress,
      isFetchingPosition,
      intl: { formatMessage }
    } = this.props

    return (
      <Input
        ref={this.input}
        key="input"
        type="text"
        value={value}
        errorMessage={errorMessage}
        placeholder={formatMessage({ id: 'store/pickup-availability.input-placeholder' })}
        size="large"
        onChange={onChange}
        suffix={
          isFetchingPosition ? (
            <Spinner size={16} />
          ) : (
              <LocationInputIcon onClick={onSuffixPress} />
            )
        }
      />
    )
  }
}

export default injectIntl(ReactGoogleAutocomplete)

```


[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 pickup-availability/react/components/SelectSkuMessage.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { FormattedMessage } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'

const CSS_HANDLES = ['selectSkuContainer', 'availabilityHeader', 'selectSkuMessage'] as const

const SelectSkuMessage = () => {
  const handles = useCssHandles(CSS_HANDLES)
  return (
    <div className={`flex flex-column lh-copy ${handles.selectSkuContainer}`}>
      <div className={`c-muted-2 t-body ${handles.availabilityHeader}`}>
        <FormattedMessage id="store/pickup-availability.availability-header" />
      </div>
      <div className={`c-on-base t-body ${handles.selectSkuMessage}`}>
        <FormattedMessage id="store/pickup-availability.select-sku" />
      </div>
    </div>
  )
}

export default SelectSkuMessage
```


[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 pickup-availability/react/components/StorePickupItem.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import TranslateEstimate from 'vtex.shipping-estimate-translator/TranslateEstimate'
import { FormattedMessage } from 'react-intl'
import { applyModifiers, useCssHandles } from 'vtex.css-handles'

const CSS_HANDLES = ['estimateTranslated', 'pickupItem', 'pickupName', 'pickupAddress', 'pickupEstimate', 'pickupUnavailable'] as const

interface Props {
  store: SkuPickupStore
}

const StorePickupItem: FC<Props> = ({ store }) => {
  const handles = useCssHandles(CSS_HANDLES)
  const { pickupStoreInfo: { address, friendlyName }, shippingEstimate } = store
  const estimate = shippingEstimate && (
    <div className={`${handles.estimateTranslated} ml2`}>
      <TranslateEstimate shippingEstimate={shippingEstimate} isPickup />
    </div>
  )

  return (
    <div className={`flex flex-column t-body lh-copy c-muted-2 ${handles.pickupItem}`}>
      <span className={`t-heading-6 c-on-base ${handles.pickupName}`}>{`${friendlyName}`}</span>
      <span className={handles.pickupAddress}>{`${address.street}${address.number ? `, ${address.number}` : ''}`}</span>
      <div className={`${shippingEstimate ?
        applyModifiers(handles.pickupEstimate, shippingEstimate) :
        handles.pickupUnavailable} flex`}>
        {shippingEstimate ? (
          <FormattedMessage id="store/pickup-availability.pickup-estimate" values={{ estimate }} />
        ) : (
            <FormattedMessage id="store/pickup-availability.pickup-unavailable" />
          )}
      </div>
    </div>
  )
}

export default StorePickupItem

```


[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 pickup-availability/react/components/StoreListQuery.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, Fragment } from 'react'
import { useQuery } from 'react-apollo'
import useProduct from 'vtex.product-context/useProduct'
import { useRuntime } from 'vtex.render-runtime'
import { FormattedMessage } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'

import skuPickupSLAs from '../queries/skuPickupSLAs.gql'
import SeeAllStoresModal from './SeeAllStoresModal'
import StoreList from './StoreList'
import ItemLoader from './Loaders/ItemLoader'

const CSS_HANDLES = ['storeListEmptyMessage', 'storeList', 'storeListContainer', 'availableAtHeader'] as const

const MAX_ITEMS = 3

interface SkuPickupStoresData {
  skuPickupSLAs: SkuPickupStore[]
}

interface Variables {
  itemId?: string | null
  seller?: string | null
  lat?: string | null
  long?: string | null
  country?: string | null
}

const Wrapper: FC<{ handles: Record<string, string> }> = ({ children, handles }) => (
  <div className={`flex flex-column flex-grow-1 mv5 ${handles.storeListContainer}`}>
    {children}
  </div>
)

interface Props {
  coords: Coords
  selectedAddressId?: string
  onPickupChange: (pickup?: FavoritePickup) => void
  dispatch: DispatchFn
}

const StoreListQuery: FC<Props> = ({ coords, selectedAddressId, onPickupChange, dispatch }) => {
  const { selectedItem } = useProduct()
  const handles = useCssHandles(CSS_HANDLES)
  const {
    culture: { country },
  } = useRuntime()

  const validVars = coords.lat && coords.long && selectedItem

  const { data, loading, error } = useQuery<SkuPickupStoresData, Variables>(skuPickupSLAs, {
    ssr: false,
    skip: !validVars,
    variables: {
      itemId: selectedItem?.itemId,
      seller: selectedItem?.sellers?.[0]?.sellerId,
      lat: coords.lat,
      long: coords.long,
      country,
    },
  })

  if (!coords.lat || !coords.long || !selectedItem) {
    return null
  }

  const hasItems = (data?.skuPickupSLAs?.length ?? 0) > 0
  if (!loading && (error || !hasItems)) {
    return (
      <Wrapper handles={handles}>
        <div className={`t-body c-muted-2 ${handles.storeListEmptyMessage}`}>
          <FormattedMessage id="store/pickup-availability.empty-list" />
        </div>
      </Wrapper>
    )
  }

  const Header = (
    <div className={`${handles.availableAtHeader} mb3 c-muted-2 t-body`}>
      <FormattedMessage id="store/pickup-availability.available-header" />
    </div>
  )

  return (
    <Wrapper handles={handles}>
      {loading ? (
        <ItemLoader header={Header} />
      ) :
        (
          <Fragment>
            {Header}
            <div className={handles.storeList}>
              <StoreList
                stores={data!.skuPickupSLAs}
                maxItems={MAX_ITEMS}
                selectedAddressId={selectedAddressId}
                onPickupChange={onPickupChange}
                dispatch={dispatch}
              />
            </div>
            <SeeAllStoresModal
              stores={data!.skuPickupSLAs}
              selectedAddressId={selectedAddressId}
              onPickupChange={onPickupChange}
              dispatch={dispatch}
              minimumItems={MAX_ITEMS}
            />
          </Fragment>
        )
      }
    </Wrapper>
  )
}

export default StoreListQuery
```


[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 pickup-availability/react/components/ContainerStateSelector.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useState, useEffect } from 'react'
import { Button } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'

import SelectSkuMessage from './SelectSkuMessage'
import StoreSelectedQuery from './StoreSelectedQuery'
import AddressWithList from './AddressWithList'

const CSS_HANDLES = [
  'innerContainer',
  'availabilityHeader',
  'availabilityMessage',
  'availabilityChooseStoreText',
  'availabilityChooseStoreButton',
] as const

interface Props {
  googleMapsKey?: string
  showSelectSkuMessage: boolean
}

function usePickupFromSession() {
  const [favoritePickup, setFavoritePickup] = useState<
    FavoritePickup | undefined
  >(undefined)

  useEffect(() => {
    let isCurrent = true
    const sessionPromise = (window as any).__RENDER_8_SESSION__.sessionPromise
    if (sessionPromise) {
      sessionPromise.then((data: SessionData) => {
        const favoritePickupData =
          data?.response?.namespaces?.public?.favoritePickup?.value
        if (!favoritePickupData) {
          return
        }

        const { name, address } = favoritePickupData
        const { geoCoordinate, ...rest } = address

        if (isCurrent) {
          setFavoritePickup({
            name,
            address: { ...rest, geoCoordinates: geoCoordinate },
          })
        }
      })
    }
    return () => {
      isCurrent = false
    }
  }, [])

  return { favoritePickup, setFavoritePickup }
}

const ContainerStateSelector: FC<Props> = ({
  showSelectSkuMessage,
  googleMapsKey,
}) => {
  const handles = useCssHandles(CSS_HANDLES)
  const [showAddressForm, setShowForm] = useState(false)
  const { favoritePickup, setFavoritePickup } = usePickupFromSession()

  if (showSelectSkuMessage) {
    return <SelectSkuMessage />
  }

  if (!showAddressForm && favoritePickup) {
    return (
      <StoreSelectedQuery
        pickup={favoritePickup}
        onChangeStoreClick={() => setShowForm(true)}
      />
    )
  }

  if (showAddressForm && googleMapsKey) {
    return (
      <AddressWithList
        googleMapsKey={googleMapsKey}
        selectedAddressId={favoritePickup?.address?.addressId}
        onPickupChange={(pickup?: FavoritePickup) => {
          setShowForm(false)
          setFavoritePickup(pickup)
        }}
      />
    )
  }

  return (
    <div className={`${handles.innerContainer} flex flex-column`}>
      <div className={`${handles.availabilityHeader} c-muted-2 t-body mb1 ml3`}>
        <FormattedMessage id="store/pickup-availability.availability-header" />
      </div>
      <div
        className={`${handles.availabilityMessage} c-on-base t-body mb1 ml3 mt3`}
      >
        <FormattedMessage id="store/pickup-availability.available-for-pickup" />
      </div>
      <div className={`${handles.availabilityChooseStoreButton}`}>
        <Button onClick={() => setShowForm(true)} variation="tertiary">
          <div className={`${handles.availabilityChooseStoreText} t-body nh5`}>
            <FormattedMessage id="store/pickup-availability.choose-store" />
          </div>
        </Button>
      </div>
    </div>
  )
}

export default ContainerStateSelector

```


[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 pickup-availability/react/components/ListItem.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { Radio } from 'vtex.styleguide'
import StorePickupItem from './StorePickupItem'
import { useCssHandles, applyModifiers } from 'vtex.css-handles'

const CSS_HANDLES = ['storeListItem'] as const

interface Props {
  isSelected: boolean
  store: SkuPickupStore
  onSelectItem: () => void
}

const noop = () => { }

const ListItem: FC<Props> = ({ store, isSelected, onSelectItem }) => {
  const bgColor = isSelected ? 'bg-near-white' : 'bg-base'
  const handles = useCssHandles(CSS_HANDLES)
  const classes = applyModifiers(handles.storeListItem, isSelected ? 'selected' : 'unselected')

  return (
    <div
      role="button"
      className={`pointer flex ${bgColor} pa4 bt bb b--muted-4 ph7-l ${classes}`}
      onClick={onSelectItem}
      onKeyDown={e => e.key === 'Enter' && onSelectItem()}
      tabIndex={0}
    >
      <div className="mt3">
        {/* Decorative Radio element */}
        <Radio
          checked={isSelected}
          id=""
          label=""
          name=""
          value=""
          onChange={noop}
        />
      </div>
      <StorePickupItem store={store} />
    </div>
  )
}

export default ListItem

```


[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 pickup-availability/react/components/SeeAllStoresModal.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, useState, Fragment } from 'react'
import { Button } from 'vtex.styleguide'
import { IconClose } from 'vtex.store-icons'
import { Overlay } from 'vtex.react-portal'
import { useDevice } from 'vtex.device-detector'
import { FormattedMessage } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'

import StoreList from './StoreList'

const CSS_HANDLES = ['seeAllModalButton', 'seeAllModalButtonText', 'modalContainer', 'modalHeader', 'modalCloseIcon', 'modalStoreList'] as const

interface Props {
  stores: SkuPickupStore[]
  selectedAddressId: string | undefined
  onPickupChange: (pickup?: FavoritePickup) => void
  dispatch: DispatchFn
  minimumItems: number
}

const SeeAllStoresModal: FC<Props> = ({ stores, selectedAddressId, onPickupChange, dispatch, minimumItems }) => {
  const [isModalOpen, setModalOpen] = useState(false)
  const handles = useCssHandles(CSS_HANDLES)
  const { isMobile } = useDevice()
  if (stores.length <= minimumItems) {
    return null
  }

  if (!isModalOpen) {
    return (
      <div className={handles.seeAllModalButton}>
        <Button onClick={() => setModalOpen(true)} variation="tertiary">
          <div className={`${handles.seeAllModalButtonText} t-body`}>
            <FormattedMessage id="store/pickup-availability.see-all" />
          </div>
        </Button>
      </div>
    )
  }

  const closeModal = () => setModalOpen(false)

  return (
    <Overlay>
      {
        <Fragment>
          <div className="fixed top-0 left-0 w-100 h-100 bg-black-20" />
          <div
            className="fixed top-0 left-0 w-100 h-100 flex items-center justify-center"
            onClick={closeModal}
          >
            <div
              className={`w-100 h-100 items-center justify-center overflow-y-auto bg-base ${handles.modalContainer}`}
              style={!isMobile ? { maxHeight: '80vh', maxWidth: '90vw', height: 'auto', width: 'auto' } : {}}
              onClick={(e: any) => { e.stopPropagation() }}
            >
              <div className={`flex justify-between items-center ph4 pv5 sticky top-0 bg-base z-999 ${handles.modalHeader}`}>
                <div className="t-body c-muted-2">
                  <FormattedMessage id="store/pickup-availability.select-store" />
                </div>
                <div className={`mh4 pointer h-100 justify-center items-center ${handles.modalCloseIcon}`} onClick={closeModal}>
                  <IconClose size={20} type="line" />
                </div>
              </div>
              <div className={handles.modalStoreList}>
                <StoreList
                  stores={stores}
                  selectedAddressId={selectedAddressId}
                  onPressPickup={closeModal}
                  onPickupChange={onPickupChange}
                  dispatch={dispatch}
                />
              </div>
            </div>
          </div>
        </Fragment>
      }
    </Overlay>
  )
}

export default SeeAllStoresModal
```


[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 pickup-availability/react/components/AddressInput.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment, PureComponent } from 'react'
import { withScriptjs, WithScriptjsProps } from 'react-google-maps'
import { withRuntimeContext, RenderContextProps } from 'vtex.render-runtime'
import ReactGoogleAutocomplete from './ReactGooogleAutocomplete'
import { FormattedMessage, injectIntl, InjectedIntlProps } from 'react-intl'

const GEOLOCATION_TIMEOUT = 30 * 1000
const MAXIMUM_AGE = 3 * 1000

const getCurrentPositionPromise = (): Promise<Position> => {
  const geolocationOptions = {
    enableHighAccuracy: true,
    timeout: GEOLOCATION_TIMEOUT,
    maximumAge: MAXIMUM_AGE,
  }
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (position: Position) => resolve(position),
      (error: any) => reject(error.code),
      geolocationOptions
    )
  })
}

interface GoogleRequestParams {
  lat: string
  long: string
  googleMapsKey: string
}

const requestGoogleMapsApi = async (params: GoogleRequestParams): Promise<GoogleResponse> => {
  const { lat, long, googleMapsKey } = params
  try {
    const response =
      await fetch(`https://maps.googleapis.com/maps/api/geocode/json?key=${googleMapsKey}&latlng=${lat},${long}`)
    return await response.json()
  } catch (err) {
    return { results: [] }
  }
}

interface GoogleResponse {
  results: Array<{
    formatted_address: string
  }>
}

interface Props {
  onPlaceSelected: (place: google.maps.places.PlaceResult) => void
  onCurrentPositionReceived: (coords: Coords) => void
  googleMapsKey: string
}

interface State {
  isFetchingPosition: boolean
  showError: boolean
  formattedAddress: string | undefined
}

class AddressInput extends PureComponent<Props & WithScriptjsProps & RenderContextProps & InjectedIntlProps, State> {
  state = {
    isFetchingPosition: false,
    showError: false,
    formattedAddress: undefined
  }

  onSuffixPress = async () => {
    const { onCurrentPositionReceived, googleMapsKey } = this.props
    this.setState({ isFetchingPosition: true, showError: false })
    const position = await getCurrentPositionPromise().catch(() => null)
    if (!position) {
      this.setState({ isFetchingPosition: false, showError: true })
      return
    }
    const lat = position.coords.latitude.toString()
    const long = position.coords.longitude.toString()
    onCurrentPositionReceived({
      lat,
      long,
    })

    const googleResponse = await requestGoogleMapsApi({
      googleMapsKey,
      lat,
      long,
    })
    if (googleResponse.results.length > 0) {
      const [closestMatch] = googleResponse.results
      this.setState({ formattedAddress: closestMatch['formatted_address'] })
    }

    this.setState({ isFetchingPosition: false })
  }

  onChange = (e: any) => {
    if (this.state.showError) {
      this.setState({ showError: false })
    }
    this.setState({ formattedAddress: e.target.value })
  }

  render() {
    const {
      runtime: {
        culture: { country },
      },
      onPlaceSelected,
      intl: { formatMessage }
    } = this.props

    return (
      <Fragment>
        <div className="t-body c-on-base mv4">
          <FormattedMessage id="store/pickup-availability.input-form-header" />
        </div>
        <ReactGoogleAutocomplete
          isLoading={false}
          isFetchingPosition={this.state.isFetchingPosition}
          onPlaceSelected={onPlaceSelected}
          onSuffixPress={this.onSuffixPress}
          types={['address']}
          componentRestrictions={{ country }}
          onChange={this.onChange}
          errorMessage={this.state.showError ? formatMessage({ id: 'store/pickup-availability.error-position-message' }) : undefined}
          value={this.state.formattedAddress}
        />
      </Fragment>
    )
  }
}

export default injectIntl(withRuntimeContext(withScriptjs(AddressInput)))
```


[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 pickup-availability/react/components/StoreList.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment, FC } from 'react'
import { useMutation } from 'react-apollo'

import savePickupInSessionMutation from '../mutations/savePickupInSession.gql'

import ListItem from './ListItem'

interface Variables {
  name: string
  address: {
    addressId: string
    postalCode: string
    city: string
    complement: string
    country: string
    state: string
    street: string
    number: string
    neighborhood: string
    geoCoordinates: [number, number]
  }
}

interface Props {
  stores: SkuPickupStore[]
  maxItems?: number
  selectedAddressId: string | undefined
  onPickupChange: (pickup?: FavoritePickup) => void
  dispatch: DispatchFn
  onPressPickup?: () => void
}

const StoreList: FC<Props> = ({ stores, maxItems, selectedAddressId, onPickupChange, dispatch, onPressPickup }) => {
  const items = maxItems && stores.length > maxItems ? stores.slice(0, maxItems) : stores
  const [savePickupInSession] = useMutation<{ savePickupInSession: { favoritePickup: FavoritePickup } }, Variables>(savePickupInSessionMutation)

  const saveMutation = (store: SkuPickupStore) => {
    const { address, friendlyName } = store.pickupStoreInfo
    return savePickupInSession({
      variables: {
        name: friendlyName,
        address: {
          addressId: address.addressId,
          postalCode: address.postalCode,
          city: address.city,
          complement: address.complement,
          country: address.country,
          state: address.state,
          street: address.street,
          number: address.number,
          neighborhood: address.neighborhood,
          geoCoordinates: address.geoCoordinates,
        }
      },
    })
  }

  return (
    <Fragment>
      {items.map(store => {
        return (
          <ListItem
            key={store.id}
            isSelected={store.pickupStoreInfo.address.addressId === selectedAddressId}
            store={store}
            onSelectItem={() => {
              onPressPickup && onPressPickup()
              dispatch({ type: 'PICKUP_CHANGE_REQUEST' })
              saveMutation(store).then(response => {
                dispatch({ type: 'PICKUP_CHANGE_DONE' })
                onPickupChange(response?.data?.savePickupInSession?.favoritePickup)
              }).catch(() => {
                dispatch({ type: 'PICKUP_CHANGE_DONE' })
              })
            }}
          />
        )
      })}
    </Fragment>
  )
}

export default StoreList

```


[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 pickup-availability/react/__tests__/StoreSelectedQuery.test.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render, wait, fireEvent } from '@vtex/test-tools/react'
import { MockedProvider } from '@apollo/react-testing'
import StoreSelectedQuery from '../components/StoreSelectedQuery'

import { getProduct } from '../__mocks__/productMock'

import ProductContextProvider from '../__mocks__/vtex.product-context/ProductContextProvider'

import logisticsQuery from '../queries/logistics.gql'
import skuPickupSLA from '../queries/skuPickupSLA.gql'

const favoritePickup = {
  cacheId: 'ppbotafogo',
  name: 'Pickup Botafogo',
  address: {
    street: 'Praia de Botafogo',
    number: '300',
    addressId: 'ppbotafogo',
    state: 'RJ',
    country: 'BRA',
    geoCoordinates: [-43, -20],
    postalCode: '2250040',
    complement: '',
    neighborhood: 'Botafogo'
  }
}

const fakeSession = {
  id: 'a',
  namespaces: {
    public: {
      favoritePickup: {
        value: favoritePickup,
      }
    }
  }
}

const noop = () => { }

const renderComponent = (customProps: any = {}) => {

  const product = customProps.product || getProduct()
  const skuSelector = customProps.skuSelector || { isVisible: false }

  const sessionPromise = new Promise(resolve => {
    resolve({ response: customProps.sessionMock || fakeSession })
  })

  global.__RENDER_8_SESSION__ = {
    sessionPromise
  }

  return render(<ProductContextProvider product={product} skuSelector={skuSelector}>
    <StoreSelectedQuery pickup={favoritePickup as any} onChangeStoreClick={customProps.onChangeStoreClick || noop} />
  </ProductContextProvider>, {
    graphql: { mocks: customProps.mocks || [] },
    MockedProvider
  })
}

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

test('should render unavailable pickup properly if no sku pickup was found', async () => {
  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupMock = {
    request: {
      query: skuPickupSLA,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-20',
        long: '-43',
        country: 'BRA',
        pickupId: 'ppbotafogo'
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLA: null,
      }
    }
  }

  const onChangeStoreClickFn = jest.fn()

  const { getByText } = renderComponent({
    mocks: [logisticsMock, skuPickupMock],
    onChangeStoreClick: onChangeStoreClickFn,
  })

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

  expect(getByText(new RegExp(fakeSession.namespaces.public.favoritePickup.value.name))).toBeDefined()
  expect(getByText(new RegExp(fakeSession.namespaces.public.favoritePickup.value.address.street))).toBeDefined()
  expect(getByText(new RegExp(fakeSession.namespaces.public.favoritePickup.value.address.number))).toBeDefined()
  expect(getByText(/Unavailable for pickup/)).toBeDefined()

  const button = getByText(/Choose a different store/)
  await wait(() => {
    fireEvent.click(button)
  })
  expect(onChangeStoreClickFn).toBeCalledTimes(1)
})

test('should render item loader when loading is true', async () => {
  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupMock = {
    request: {
      query: skuPickupSLA,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-20',
        long: '-43',
        country: 'BRA',
        pickupId: 'ppbotafogo'
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLA: null,
      }
    }
  }

  const { getByTestId, queryByTestId } = renderComponent({
    mocks: [logisticsMock, skuPickupMock],
  })
  getByTestId('item-loader')
  await wait(() => {
    jest.runAllTimers()
  })
  expect(queryByTestId('item-loader')).toBe(null)
})
```


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

[User] Show me the implementation of pickup-availability/react/__tests__/StoreListQuery.test.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { render, wait } from '@vtex/test-tools/react'
import { MockedProvider } from '@apollo/react-testing'
import { clone } from 'ramda'
import StoreListQuery from '../components/StoreListQuery'

import { getProduct } from '../__mocks__/productMock'

import ProductContextProvider from '../__mocks__/vtex.product-context/ProductContextProvider'

import logisticsQuery from '../queries/logistics.gql'
import skuPickupSLAs from '../queries/skuPickupSLAs.gql'

const TestComponent: FC<any> = ({ product, skuSelector, coords, selectedAddressId, onPickupChange, dispatch }) => (
  <ProductContextProvider product={product} skuSelector={skuSelector}>
    <StoreListQuery coords={coords} selectedAddressId={selectedAddressId} onPickupChange={onPickupChange} dispatch={dispatch} />
  </ProductContextProvider>
)

const renderComponent = (customProps: any = {}) => {

  const product = customProps.product || getProduct()
  const skuSelector = customProps.skuSelector || { isVisible: false }

  const result = render(<TestComponent product={product} skuSelector={skuSelector} coords={customProps.coords || { lat: '-23', long: '-43' }} selectedAddressId={customProps.selectedAddressId} onPickupChange={() => { }} dispatch={() => { }} />, {
    graphql: { mocks: customProps.mocks || [] },
    MockedProvider
  })

  const { rerender } = result
  const customRerender = (customProps: any) => rerender(<TestComponent product={product} skuSelector={skuSelector} coords={customProps.coords || { lat: '-23', long: '-43' }} selectedAddressId={customProps.selectedAddressId} onPickupChange={() => { }} dispatch={() => { }} />)
  return {
    ...result,
    rerender: customRerender,
  }
}

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

test('should render store list properly, do not show see all modal', async () => {
  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupsMock = {
    request: {
      query: skuPickupSLAs,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-23',
        long: '-43',
        country: 'BRA',
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLAs: [{
          id: 'ppbotafogo',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Botafogo',
            address: {
              cacheId: 'a',
              street: 'Praia de Botafogo',
              number: '300',
              addressId: 'ppbotafogo',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Botafogo',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppipanema',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Ipanema',
            address: {
              cacheId: 'a',
              street: 'Praia de Ipanema',
              number: '302',
              addressId: 'ppipanema',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Ipanema',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppleblon',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Leblon',
            address: {
              cacheId: 'a',
              street: 'Praia de Leblon',
              number: '303',
              addressId: 'ppleblon',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Leblon',
              city: 'Rio de Janeiro'
            }
          }
        }],
      }
    }
  }

  const { getByText } = renderComponent({
    mocks: [logisticsMock, skuPickupsMock]
  })

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

  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.number))).toBeDefined()
})

test('should render store list properly, show top three only and see all button', async () => {
  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupsMock = {
    request: {
      query: skuPickupSLAs,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-23',
        long: '-43',
        country: 'BRA',
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLAs: [{
          id: 'ppbotafogo',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Botafogo',
            address: {
              cacheId: 'a',
              street: 'Praia de Botafogo',
              number: '300',
              addressId: 'ppbotafogo',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Botafogo',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppipanema',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Ipanema',
            address: {
              cacheId: 'a',
              street: 'Praia de Ipanema',
              number: '302',
              addressId: 'ppipanema',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Ipanema',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppleblon',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Leblon',
            address: {
              cacheId: 'a',
              street: 'Praia de Leblon',
              number: '303',
              addressId: 'ppleblon',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Leblon',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppgloria',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Gloria',
            address: {
              cacheId: 'a',
              street: 'Praia de Gloria',
              number: '304',
              addressId: 'ppgloria',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Gloria',
              city: 'Rio de Janeiro'
            }
          }
        }],
      }
    }
  }

  const { queryByText, getByText } = renderComponent({
    mocks: [logisticsMock, skuPickupsMock]
  })

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

  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.number))).toBeDefined()

  // Fourth element should not be found
  expect(queryByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[3].pickupStoreInfo.friendlyName))).toBeNull()

  //See all stores button should appear
  expect(getByText(/See all stores/)).toBeDefined()
})

test('test that changing coords pased to component reults in a different query and works flawless', async () => {
  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupsMock = {
    request: {
      query: skuPickupSLAs,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-23',
        long: '-43',
        country: 'BRA',
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLAs: [{
          id: 'ppbotafogo',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Botafogo',
            address: {
              cacheId: 'a',
              street: 'Praia de Botafogo',
              number: '300',
              addressId: 'ppbotafogo',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Botafogo',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppipanema',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Ipanema',
            address: {
              cacheId: 'a',
              street: 'Praia de Ipanema',
              number: '302',
              addressId: 'ppipanema',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Ipanema',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppleblon',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Leblon',
            address: {
              cacheId: 'a',
              street: 'Praia de Leblon',
              number: '303',
              addressId: 'ppleblon',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Leblon',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppgloria',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Gloria',
            address: {
              cacheId: 'a',
              street: 'Praia de Gloria',
              number: '304',
              addressId: 'ppgloria',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Gloria',
              city: 'Rio de Janeiro'
            }
          }
        }],
      }
    }
  }

  const skuPickupsMockClone = clone(skuPickupsMock)
  skuPickupsMockClone.request.variables.lat = '-21'
  skuPickupsMockClone.request.variables.long = '-30'
  skuPickupsMockClone.result.data.skuPickupSLAs = [
    {
      id: 'ppleme',
      shippingEstimate: '30m',
      pickupStoreInfo: {
        friendlyName: 'Pickup Leme',
        address: {
          cacheId: 'a',
          street: 'Praia do Leme',
          number: '300',
          addressId: 'ppleme',
          state: 'RJ',
          country: 'BRA',
          geoCoordinates: [-43, -20],
          postalCode: '2250040',
          complement: '',
          neighborhood: 'Leme',
          city: 'Rio de Janeiro'
        }
      }
    }
  ]

  const { getByText, rerender, queryByText } = renderComponent({
    mocks: [logisticsMock, skuPickupsMock, skuPickupsMockClone]
  })

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

  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.number))).toBeDefined()

  // Fourth element should not be found
  expect(queryByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[3].pickupStoreInfo.friendlyName))).toBeNull()

  //See all stores button should appear
  expect(getByText(/See all stores/)).toBeDefined()

  // Switch props
  rerender({ coords: { lat: '-21', long: '-30' } })

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

  expect(getByText(new RegExp(skuPickupsMockClone.result.data.skuPickupSLAs[0].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMockClone.result.data.skuPickupSLAs[0].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMockClone.result.data.skuPickupSLAs[0].pickupStoreInfo.address.number))).toBeDefined()
  expect(queryByText(/See all stores/)).toBeNull()
})

test('Should render empty list message', async () => {
  jest.useFakeTimers()

  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupsMock = {
    request: {
      query: skuPickupSLAs,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-23',
        long: '-43',
        country: 'BRA',
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLAs: [],
      }
    }
  }

  const { getByText, queryByText } = renderComponent({
    mocks: [logisticsMock, skuPickupsMock]
  })

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

  expect(getByText(/Could not find pickup locations near specified address/)).toBeDefined()
  expect(queryByText(/See all stores/)).toBeNull()
})

test('ensure loader is appearing when loading is true', async () => {
  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupsMock = {
    request: {
      query: skuPickupSLAs,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-23',
        long: '-43',
        country: 'BRA',
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLAs: [{
          id: 'ppbotafogo',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Botafogo',
            address: {
              cacheId: 'a',
              street: 'Praia de Botafogo',
              number: '300',
              addressId: 'ppbotafogo',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Botafogo',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppipanema',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Ipanema',
            address: {
              cacheId: 'a',
              street: 'Praia de Ipanema',
              number: '302',
              addressId: 'ppipanema',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Ipanema',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppleblon',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Leblon',
            address: {
              cacheId: 'a',
              street: 'Praia de Leblon',
              number: '303',
              addressId: 'ppleblon',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Leblon',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppgloria',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Gloria',
            address: {
              cacheId: 'a',
              street: 'Praia de Gloria',
              number: '304',
              addressId: 'ppgloria',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Gloria',
              city: 'Rio de Janeiro'
            }
          }
        }],
      }
    }
  }

  const { getByTestId, queryByTestId } = renderComponent({
    mocks: [logisticsMock, skuPickupsMock]
  })

  getByTestId('item-loader')

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

  expect(queryByTestId('item-loader')).toBe(null)
})
```


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

[User] Show me the implementation of pickup-availability/react/__tests__/index.test.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render, wait } from '@vtex/test-tools/react'
import { MockedProvider } from "@apollo/react-testing"
import Index from '../index'

import { getProduct } from '../__mocks__/productMock'

import ProductContextProvider from '../__mocks__/vtex.product-context/ProductContextProvider'

import logisticsQuery from '../queries/logistics.gql'
import skuPickupSLA from '../queries/skuPickupSLA.gql'

const fakeSession = {
  id: 'a',
  namespaces: {
    public: {}
  }
}

const renderComponent = (customProps: any = {}) => {
  const sessionPromise = new Promise(resolve => {
    resolve({ response: customProps.sessionMock || fakeSession })
  })

  global.__RENDER_8_SESSION__ = {
    sessionPromise
  }

  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }
  const product = customProps.product || getProduct()
  const skuSelector = customProps.skuSelector || { isVisible: false }

  const moreMock = customProps.otherMocks || []

  return render(<ProductContextProvider product={product} skuSelector={skuSelector}>
    <Index />
  </ProductContextProvider>, {
    graphql: { mocks: [logisticsMock, ...moreMock] },
    MockedProvider,
  })
}

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

test('should render choose store view when no favorite pickup in session', async () => {
  const { getByText } = renderComponent()

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

  expect(getByText(/Choose store/)).toBeDefined()
  expect(getByText(/This product is available for pickup/)).toBeDefined()
})

test('should render select sku message if sku selector is invalid state', async () => {
  const { getByText } = renderComponent({
    skuSelector: { isVisible: true, areAllVariationsSelected: false }
  })

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

  expect(getByText(/Select SKUs above to check availability for pickup/)).toBeDefined()
})

test('should render properly if sku selector is visible and valid', async () => {
  const { getByText } = renderComponent({
    skuSelector: { isVisible: true, areAllVariationsSelected: true }
  })

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

  expect(getByText(/Choose store/)).toBeDefined()
  expect(getByText(/This product is available for pickup/)).toBeDefined()
})

test('should render store selected component with shipping estimate properly', async () => {
  const sessionMock = {
    id: 'a',
    namespaces: {
      public: {
        favoritePickup: {
          value: {
            name: 'Pickup Botafogo',
            address: {
              street: 'Praia de Botafogo',
              number: '300',
              addressId: 'ppbotafogo',
              state: 'RJ',
              country: 'BRA',
              geoCoordinate: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Botafogo'
            }
          }
        }
      }
    }
  }

  const skuPickupMock = {
    request: {
      query: skuPickupSLA,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-20',
        long: '-43',
        country: 'BRA',
        pickupId: 'ppbotafogo'
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLA: {
          id: 'ppbotafogo',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Botafogo',
            address: {
              cacheId: 'a',
              street: 'Praia de Botafogo',
              number: '300',
              addressId: 'ppbotafogo',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Botafogo',
              city: 'Rio de Janeiro'
            }
          }
        },
      }
    }
  }

  const otherMocks = [skuPickupMock]

  const { getByText } = renderComponent({
    sessionMock,
    otherMocks,
  })

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

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

  expect(getByText(new RegExp(skuPickupMock.result.data.skuPickupSLA.pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupMock.result.data.skuPickupSLA.pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupMock.result.data.skuPickupSLA.pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(`shipping estimate: ${skuPickupMock.result.data.skuPickupSLA.shippingEstimate}, isPickup: true`))).toBeDefined()
  expect(getByText(/Choose a different store/)).toBeDefined()
})
```


[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 pickup-availability/react/__tests__/AddressWithList.test.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render, wait } from '@vtex/test-tools/react'
import { MockedProvider } from '@apollo/react-testing'
import AddressWithList from '../components/AddressWithList'

import { getProduct } from '../__mocks__/productMock'

import ProductContextProvider from '../__mocks__/vtex.product-context/ProductContextProvider'

import logisticsQuery from '../queries/logistics.gql'
import skuPickupSLA from '../queries/skuPickupSLA.gql'
import skuPickupSLAs from '../queries/skuPickupSLAs.gql'

let currentAutocomplete: any = null

const event = new Event('place_changed')

class Autcomplete {
  public eventListening: string | null = null
  count = -1

  public addListener(eventName: string, fn: any) {
    currentAutocomplete = this
    this.eventListening = eventName
    window.addEventListener(eventName, fn)
  }

  public getPlace() {
    // Make like this so each dispatched event returns something new
    this.count += 1
    return {
      geometry: {
        location: {
          lat: () => -23 - this.count,
          lng: () => -43 - this.count,
        }
      }
    }
  }
}

jest.mock('react-google-maps', () => {
  return {
    withScriptjs: (WrappedComponent) => props => <WrappedComponent {...props} />
  }
})

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

const renderComponent = (customProps: any = {}) => {

  const product = customProps.product || getProduct()
  const skuSelector = customProps.skuSelector || { isVisible: false }

  global.google = {
    maps: {
      places: {
        Autocomplete: Autcomplete,
      }
    }
  }

  return render(<ProductContextProvider product={product} skuSelector={skuSelector}>
    <AddressWithList googleMapsKey={'a'} selectedAddressId={'a'} onPickupChange={() => { }} />
  </ProductContextProvider>, {
    graphql: { mocks: customProps.mocks || [] },
    MockedProvider,
  })
}

test('test place_changed event dispatch triggering and changing coordinas, making store list render pickup list', async () => {
  const logisticsMock = {
    request: {
      query: logisticsQuery,
    },
    result: {
      loading: false,
      data: {
        logistics: {
          googleMapsKey: 'aaaaa',
        }
      }
    }
  }

  const skuPickupMock = {
    request: {
      query: skuPickupSLA,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-20',
        long: '-43',
        country: 'BRA',
        pickupId: 'ppbotafogo'
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLA: null,
      }
    }
  }

  const skuPickupsMock = {
    request: {
      query: skuPickupSLAs,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-23',
        long: '-43',
        country: 'BRA',
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLAs: [{
          id: 'ppbotafogo',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Botafogo',
            address: {
              cacheId: 'a',
              street: 'Praia de Botafogo',
              number: '300',
              addressId: 'ppbotafogo',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Botafogo',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppipanema',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Ipanema',
            address: {
              cacheId: 'a',
              street: 'Praia de Ipanema',
              number: '302',
              addressId: 'ppipanema',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Ipanema',
              city: 'Rio de Janeiro'
            }
          }
        },
        {
          id: 'ppleblon',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Leblon',
            address: {
              cacheId: 'a',
              street: 'Praia de Leblon',
              number: '303',
              addressId: 'ppleblon',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Leblon',
              city: 'Rio de Janeiro'
            }
          }
        }],
      }
    }
  }

  const skuPickupsMockTwo = {
    request: {
      query: skuPickupSLAs,
      variables: {
        itemId: '1',
        seller: '1',
        lat: '-24',
        long: '-44',
        country: 'BRA',
      }
    },
    result: {
      loading: false,
      data: {
        skuPickupSLAs: [{
          id: 'ppgloria',
          shippingEstimate: '30m',
          pickupStoreInfo: {
            friendlyName: 'Pickup Gloria',
            address: {
              cacheId: 'a',
              street: 'Praia de Botafogo',
              number: '131',
              addressId: 'ppgloria',
              state: 'RJ',
              country: 'BRA',
              geoCoordinates: [-43, -20],
              postalCode: '2250040',
              complement: '',
              neighborhood: 'Gloria',
              city: 'Rio de Janeiro'
            }
          }
        }],
      }
    }
  }

  const { getByText } = renderComponent({
    mocks: [logisticsMock, skuPickupMock, skuPickupsMock, skuPickupsMockTwo],
  })

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

  //Dispatch 'place_changed' event
  await wait(() => {
    window.dispatchEvent(event)
  })

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

  expect(currentAutocomplete.eventListening).toBe('place_changed')

  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[0].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[1].pickupStoreInfo.address.number))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMock.result.data.skuPickupSLAs[2].pickupStoreInfo.address.number))).toBeDefined()

  await wait(() => {
    window.dispatchEvent(event)
  })

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

  expect(getByText(new RegExp(skuPickupsMockTwo.result.data.skuPickupSLAs[0].pickupStoreInfo.friendlyName))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMockTwo.result.data.skuPickupSLAs[0].pickupStoreInfo.address.street))).toBeDefined()
  expect(getByText(new RegExp(skuPickupsMockTwo.result.data.skuPickupSLAs[0].pickupStoreInfo.address.number))).toBeDefined()
})
```


[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 pickup-availability/react/typings/vtex.shipping-estimate-translator/TranslateEstimate.d.ts from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.shipping-estimate-translator/TranslateEstimate' {
  import { ComponentType } from 'react'

  interface Props {
    shippingEstimate: string
    isPickup?: boolean
  }

  const TranslateEstimate: ComponentType<Props>
  export default TranslateEstimate
}

```


[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 pickup-availability/react/components/hooks/useShowWithDelay.ts from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useState, useEffect } from 'react'

export const useShowWithDelay = () => {
  const [canShow, setCanShow] = useState(false)
  useEffect(() => {
    const timeout = setTimeout(() => setCanShow(true), 300)
    return () => {
      if (timeout) {
        clearTimeout(timeout)
      }
    }
  }, [])
  return canShow
}

```


[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 pickup-availability/react/components/Loaders/ItemLoader.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, Fragment } from 'react'
import { useShowWithDelay } from '../hooks/useShowWithDelay'
import { RectShape } from 'react-placeholder/lib/placeholders'

interface Props {
  header?: JSX.Element
}

const ItemLoader: FC<Props> = ({ header }) => {
  const canShow = useShowWithDelay()

  if (!canShow) {
    return (
      <div className="w-100" style={{ height: 80 }} data-testid="item-loader" />
    )
  }

  return (
    <Fragment>
      {header}
      <div style={{ marginLeft: '10px' }}>
        <RectShape color="#f3f3f3" style={{ height: 28, width: '160px' }} />
        <RectShape color="#f3f3f3" style={{ height: 22, width: '200px', marginTop: '6px' }} />
        <RectShape color="#f3f3f3" style={{ height: 22, width: '200px', marginTop: '6px' }} />
      </div>
    </Fragment>
  )
}

export default ItemLoader

```


[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 pickup-availability/react/components/Loaders/AddressBarLoader.tsx from the pickup-availability VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC, Fragment } from 'react'
import { RectShape } from 'react-placeholder/lib/placeholders'

import { useShowWithDelay } from '../hooks/useShowWithDelay'

const AddressBarLoader: FC = () => {
  const canShow = useShowWithDelay()

  if (!canShow) {
    return (
      <div className="w-100" style={{ height: 60 }} />
    )
  }

  return (
    <Fragment>
      <RectShape color="#f3f3f3" style={{ height: 16, width: '200px' }} />
      <RectShape color="#f3f3f3" style={{ height: 48, width: '100%', marginTop: '6px' }} />
    </Fragment>
  )
}

export default AddressBarLoader

```


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

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

[Assistant]
Here's the implementation:

```json
{
  "store/common.header.counter": "Számláló több kézbesítéshez és/vagy átvételhez",
  "store/items.attachments.subscription": "Előfizetés",
  "store/items.attachments.subscription.frequency.day": "A következő időtartamonként: {frequencyNumber, plural, one {# nap} other {# nap}}",
  "store/items.attachments.subscription.frequency.month": "A következő időtartamonként: {frequencyNumber, plural, one {# hónap} other {# hónap}}",
  "store/items.attachments.subscription.frequency.week": "A következő időtartamonként: {frequencyNumber, plural, one {# hét} other {# hét}}",
  "store/items.attachments.subscription.frequency.year": "A következő időtartamonként: {frequencyNumber, plural, one {# év} other {# év}}",
  "store/items.attachments.subscription.purchaseday": "Havi fizetés a következő napon: {purchaseday}",
  "store/order.header.cancel.button": "Megrendelés lemondása",
  "store/order.header.date": "Leadás: {orderDate} – {orderTime}",
  "store/order.header.myorders.button": "Saját megrendelések",
  "store/order.header.number": "#{orderId} megrendelés",
  "store/order.header.receipt": "Nyugta megtekintése",
  "store/order.header.seller": "Értékesítő és kézbesítő: {seller}",
  "store/order.header.takeaway.cancel.button": "Vásárlás lemondása",
  "store/order.header.takeaway.printreceipt.button": "Nyugta újranyomtatása",
  "store/order.header.update.button": "Megrendelés frissítése",
  "store/order.split.n.pickup.n.takeaway": "{deliveries} kézbesítésre bontottuk a megrendelést, {pickups, plural, one {, egy üzletben történő átvétel} other {, # üzletben történő átvétel}}{takeaways, plural, one {és egy elviteles termék} other {és # elviteles termék}}. Így gyorsabban megkaphatja azokat a tételeket, amelyek közelebb vannak Önhöz.",
  "store/order.split.n.pickup.no.takeaway": "{deliveries} kézbesítésre bontottuk a megrendelést, {pickups, plural, one {és egy üzletben történő átvétel} other {és # üzletben történő átvétel}}. Így gyorsabban megkaphatja azokat a tételeket, amelyek közelebb vannak Önhöz.",
  "store/order.split.no.pickup.n.takeaway": "{deliveries} kézbesítésre bontottuk a megrendelést, {takeaways, plural, one {és egy elviteles termék} other {és # elviteles termék}}. Így gyorsabban megkaphatja azokat a tételeket, amelyek közelebb vannak Önhöz.",
  "store/order.split.no.pickup.no.takeaway": "{deliveries} kézbesítésre bontottuk a megrendelést. Így gyorsabban megkaphatja azokat a tételeket, amelyek közelebb vannak Önhöz.",
  "store/order.totals.delivery": "Kézbesítés",
  "store/order.totals.pickup": "Átvétel",
  "store/order.totals.pickup.free": "Ingyenes",
  "store/order.totals.subtotal": "Részösszeg ({numItems, plural, one {# tétel} other {# tétel}})",
  "store/order.totals.total": "Összesen",
  "store/payments.bankinvoice.print": "{paymentSystemName} megnyitása",
  "store/payments.creditcard": "Hitelkártya",
  "store/payments.promissory": "Fizetési jegyzet",
  "store/payments.creditcard.lastDigits": "Utolsó számjegyek: {lastDigits}",
  "store/payments.debitcard": "Betéti kártya",
  "store/payments.giftCard": "Ajándékkártya",
  "store/payments.id": "Fizetési azonosító: {id}",
  "store/payments.installments": "({installments}x)",
  "store/payments.transaction.id": "Tranzakcióazonosító: {id}",
  "store/pickup.header.title": "Átvétel",
  "store/products.quantity": "{quantity, plural, one {# egység} other {# egység}}",
  "store/shipping.header.title": "Kézbesítés",
  "store/shipping.header.wishlist.address": "Cím: {giftRegistryName}"
}

```


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

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

[Assistant]
Here's the implementation:

```json
{
  "store/common.header.counter": "複数の配送やピックアップに対するカウンター",
  "store/items.attachments.subscription": "登録",
  "store/items.attachments.subscription.frequency.day": "{frequencyNumber, plural, one {# 日} other {# 日}} ごと",
  "store/items.attachments.subscription.frequency.month": "{frequencyNumber, plural, one {# か月} other {# か月}} ごと",
  "store/items.attachments.subscription.frequency.week": "{frequencyNumber, plural, one {# 週} other {# 週}} ごと",
  "store/items.attachments.subscription.frequency.year": "{frequencyNumber, plural, one {# 年} other {# 年}} ごと",
  "store/items.attachments.subscription.purchaseday": "毎月 {purchaseday} 日に課金",
  "store/order.header.cancel.button": "注文をキャンセル",
  "store/order.header.date": "{orderDate} 日の {orderTime} 時に注文実行",
  "store/order.header.myorders.button": "マイ注文",
  "store/order.header.number": "注文 #{orderId}",
  "store/order.header.receipt": "領収書を表示",
  "store/order.header.seller": "{seller} が販売および発送",
  "store/order.header.takeaway.cancel.button": "購入をキャンセル",
  "store/order.header.takeaway.printreceipt.button": "領収書を再印刷",
  "store/order.header.update.button": "注文を更新",
  "store/order.split.n.pickup.n.takeaway": "注文を {deliveries} 回の配送に分割します。それぞれ、{pickups, plural, one {1 つのストアピックアップ} other {, # 個のストアピックアップ}}{takeaways, plural, one {1 つのテイクアウェイ製品} other {そして # 個のテイクアウェイ製品}}となります。このようにして、近くにある項目を早く受け取ることができます。",
  "store/order.split.n.pickup.no.takeaway": "注文を {deliveries} 回の配送に分割します。それぞれ、 {pickups, plural, one {1 つのストアピックアップ} other {# 個のストアピックアップ}} とします。このようにして、近くにある項目を早く受け取ることができます。",
  "store/order.split.no.pickup.n.takeaway": "注文を {deliveries} 回の配送に分割します。それぞれ、 {takeaways, plural, one {1 つのテイクアウェイ製品} other {# 個のテイクアウェイ製品}}となります。このようにして、近くにある項目を早く受け取ることができます。",
  "store/order.split.no.pickup.no.takeaway": "注文を {deliveries} 回の配送に分割します。このようにして、近くにある項目を早く受け取ることができます。",
  "store/order.totals.delivery": "配送",
  "store/order.totals.pickup": "ピックアップ",
  "store/order.totals.pickup.free": "無料",
  "store/order.totals.subtotal": "小計 ({numItems, plural, one {# 個の項目} other {# 個の項目}})",
  "store/order.totals.total": "合計",
  "store/payments.bankinvoice.print": "{paymentSystemName} を開く",
  "store/payments.creditcard": "クレジットカード",
  "store/payments.creditcard.lastDigits": "最後の桁: {lastDigits}",
  "store/payments.debitcard": "デビットカード",
  "store/payments.giftCard": "ギフトカード",
  "store/payments.id": "支払い ID: {id}",
  "store/payments.installments": "({installments}x)",
  "store/payments.transaction.id": "取引 ID: {id}",
  "store/pickup.header.title": "ピックアップ",
  "store/products.quantity": "{quantity, plural, one {# ユニティ} other {# ユニティ}}",
  "store/shipping.header.title": "配送",
  "store/shipping.header.wishlist.address": "住所登録: {giftRegistryName}"
}

```


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

[User] Show me the implementation of order-details/messages/id-ID.json from the order-details VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/common.header.counter": "Penghitung untuk beberapa pengiriman dan/atau pengambilan",
  "store/items.attachments.subscription": "Langganan",
  "store/items.attachments.subscription.frequency.day": "Tiap {frequencyNumber, plural, one {# hari} other {# hari}}",
  "store/items.attachments.subscription.frequency.month": "Tiap {frequencyNumber, plural, one {# bulan} other {# bulan}}",
  "store/items.attachments.subscription.frequency.week": "Tiap {frequencyNumber, plural, one {# minggu} other {# minggu}}",
  "store/items.attachments.subscription.frequency.year": "Tiap {frequencyNumber, plural, one {# tahun} other {# tahun}}",
  "store/items.attachments.subscription.purchaseday": "Ditagih per bulan pada hari {purchaseday}",
  "store/order.header.cancel.button": "Batalkan pesanan",
  "store/order.header.date": "Dipesan pada {orderDate} pukul {orderTime}",
  "store/order.header.myorders.button": "Pesanan Saya",
  "store/order.header.number": "Pesanan #{orderId}",
  "store/order.header.receipt": "Lihat tanda terima",
  "store/order.header.seller": "Dijual dan dikirim oleh {seller}",
  "store/order.header.takeaway.cancel.button": "Batalkan pembelian",
  "store/order.header.takeaway.printreceipt.button": "Cetak kembali tanda terima",
  "store/order.header.update.button": "Perbarui pesanan",
  "store/order.split.n.pickup.n.takeaway": "Kami membagi pesanan Anda dalam {deliveries} kiriman,{pickups, plural, one {, diambil di toko} other {, # diambil di toko}}{takeaways, plural, one {dan produk yang dibawa pulang} other {dan # produk yang dibawa pulang}}. Dengan begitu, Anda akan menerima item yang lebih dekat dengan lebih cepat.",
  "store/order.split.n.pickup.no.takeaway": "Kami membagi pesanan Anda dalam {deliveries} pesanan{pickups, plural, other {dan # diambil di toko}}. Dengan begitu, Anda akan menerima item yang lebih dekat dengan lebih cepat.",
  "store/order.split.no.pickup.n.takeaway": "Kami membagi pesanan Anda dalam {deliveries} kiriman{takeaways, plural, one {dan satu produk untuk dibawa pulang} other {dan # produk untuk dibawa pulang}}. Dengan begitu, Anda akan menerima item yang lebih dekat dengan lebih cepat.",
  "store/order.split.no.pickup.no.takeaway": "Kami membagi pesanan Anda dalam {deliveries} kiriman. Dengan begitu, Anda akan menerima item yang lebih dekat dengan lebih cepat.",
  "store/order.totals.delivery": "Pengiriman",
  "store/order.totals.pickup": "Ambil",
  "store/order.totals.pickup.free": "Gratis",
  "store/order.totals.subtotal": "Subtotal ({numItems, plural, one {# item} other {# item}})",
  "store/order.totals.total": "Total",
  "store/payments.bankinvoice.print": "Buka {paymentSystemName}",
  "store/payments.creditcard": "Kartu kredit",
  "store/payments.creditcard.lastDigits": "Digit terakhir: {lastDigits}",
  "store/payments.debitcard": "Kartu debit",
  "store/payments.giftCard": "Kartu hadiah",
  "store/payments.id": "ID Pembayaran: {id}",
  "store/payments.installments": "({installments}x)",
  "store/payments.transaction.id": "ID Transaksi: {id}",
  "store/pickup.header.title": "Ambil",
  "store/products.quantity": "{quantity, plural, one {# kesatuan} other {# kesatuan}}",
  "store/shipping.header.title": "Pengiriman",
  "store/shipping.header.wishlist.address": "Alamat dari: {giftRegistryName}"
}

```


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

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

[Assistant]
Here's the implementation:

```json
{
  "store/common.header.counter": "Contador para múltiplas entregas e/ou retiradas",
  "store/items.attachments.subscription": "Assinatura",
  "store/items.attachments.subscription.frequency.day": "{frequencyNumber, plural, one {# diário} other {A cada # dias}}",
  "store/items.attachments.subscription.frequency.month": "{frequencyNumber, plural, one {Mensal} other {A cada # meses}}",
  "store/items.attachments.subscription.frequency.week": "{frequencyNumber, plural, one {Semanal} other {A cada # semanas}}",
  "store/items.attachments.subscription.frequency.year": "{frequencyNumber, plural, one {Anual} other {A cada # anos}}",
  "store/items.attachments.subscription.purchaseday": "Cobrado mensalmente no dia {purchaseday}",
  "store/order.header.cancel.button": "Cancelar pedido",
  "store/order.header.date": "Realizado em {orderDate} às {orderTime}",
  "store/order.header.myorders.button": "Meus pedidos",
  "store/order.header.number": "Pedido #{orderId}",
  "store/order.header.receipt": "Ver nota fiscal",
  "store/order.header.seller": "Vendido e entregue por {seller}",
  "store/order.header.takeaway.cancel.button": "Cancelar compra",
  "store/order.header.takeaway.printreceipt.button": "Reimprimir nota fiscal",
  "store/order.header.update.button": "Atualizar pedido",
  "store/order.split.n.pickup.n.takeaway": "Dividimos seu pedido em {deliveries} entregas{pickups, plural, one {, uma retirada na loja} other {, # retiradas na loja}}{takeaways, plural, one { e um produto para levar agora} other { e # produtos para levar agora}}. Assim, você recebe mais rápido os itens que estão mais próximos do seu endereço.",
  "store/order.split.n.pickup.no.takeaway": "Dividimos seu pedido em {deliveries} entregas{pickups, plural, one { e uma retirada na loja} other {e # retiradas na loja}}. Assim, você recebe mais rápido os itens que estão mais próximos do seu endereço.",
  "store/order.split.no.pickup.n.takeaway": "Dividimos seu pedido em {deliveries} entregas{takeaways, plural, one {e # produto para levar agora} other {e # produtos para levar agora}}. Assim, você recebe mais rápido os itens que estão mais próximos do seu endereço.",
  "store/order.split.no.pickup.no.takeaway": "Dividimos seu pedido em {deliveries} entregas. Assim, você recebe mais rápido os itens que estão mais próximos do seu endereço.",
  "store/order.totals.delivery": "Entrega",
  "store/order.totals.pickup": "Retirada",
  "store/order.totals.pickup.free": "Grátis",
  "store/order.totals.subtotal": "Subtotal ({numItems, plural, one {# item} other {# itens}})",
  "store/order.totals.total": "Total",
  "store/payments.bankinvoice.print": "Abrir {paymentSystemName}",
  "store/payments.creditcard": "Cartão de crédito",
  "store/payments.promissory": "Promissória",
  "store/payments.creditcard.lastDigits": "Últimos dígitos: {lastDigits}",
  "store/payments.debitcard": "Cartão de débito",
  "store/payments.giftCard": "Vale-presente",
  "store/payments.id": "ID do pagamento: {id}",
  "store/payments.installments": "(pague em {installments}x)",
  "store/payments.transaction.id": "ID da transação: {id}",
  "store/pickup.header.title": "Retirada",
  "store/products.quantity": "{quantity, plural, one {# unidade} other {# unidades}}",
  "store/shipping.header.title": "Entrega",
  "store/shipping.header.wishlist.address": "Endereço de: {giftRegistryName}"
}

```


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

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

[Assistant]
Here's the implementation:

```json
{
  "store/common.header.counter": "Counter for multiple deliveries and/or pickups",
  "store/items.attachments.subscription": "Subscription",
  "store/items.attachments.subscription.frequency.day": "{frequencyNumber, plural, one {Daily} other {Every # days}}",
  "store/items.attachments.subscription.frequency.month": "{frequencyNumber, plural, one {Monthly} other {Every # months}}",
  "store/items.attachments.subscription.frequency.week": "{frequencyNumber, plural, one {Weekly} other {Every # weeks}}",
  "store/items.attachments.subscription.frequency.year": "{frequencyNumber, plural, one {Yearly} other {Every # years}}",
  "store/items.attachments.subscription.purchaseday": "Charged monthly on the {purchaseday}",
  "store/order.header.cancel.button": "Cancel order",
  "store/order.header.date": "Placed on {orderDate} at {orderTime}",
  "store/order.header.myorders.button": "My orders",
  "store/order.header.number": "Order #{orderId}",
  "store/order.header.receipt": "View receipt",
  "store/order.header.seller": "Sold and deliveried by {seller}",
  "store/order.header.takeaway.cancel.button": "Cancel purchase",
  "store/order.header.takeaway.printreceipt.button": "Reprint receipt",
  "store/order.header.update.button": "Update order",
  "store/order.split.n.pickup.n.takeaway": "We split your order in {deliveries} deliveries{pickups, plural, one {, # store pickup} other {, # store pickups}}{takeaways, plural, one {, and # item to get now} other {, and # products to get now}}. That way, you'll get items that are closer to you faster.",
  "store/order.split.n.pickup.no.takeaway": "We split your order in {deliveries} deliveries {pickups, plural, one {and # store pickup} other {and # store pickups}}. That way, you'll get items that are closer to you faster.",
  "store/order.split.no.pickup.n.takeaway": "We split your order in {deliveries} deliveries {takeaways, plural, one {and # product to get now} other {and # products to get now}}. That way, you'll get items that are closer to you faster.",
  "store/order.split.no.pickup.no.takeaway": "We split your order in {deliveries} deliveries. That way, you'll get items that are closer to you faster.",
  "store/order.totals.delivery": "Delivery",
  "store/order.totals.pickup": "Pickup",
  "store/order.totals.pickup.free": "Free",
  "store/order.totals.subtotal": "Subtotal ({numItems, plural, one {# item} other {# items}})",
  "store/order.totals.total": "Total",
  "store/payments.bankinvoice.print": "Open {paymentSystemName}",
  "store/payments.creditcard": "Credit card",
  "store/payments.promissory": "Note payable",
  "store/payments.creditcard.lastDigits": "Last digits: {lastDigits}",
  "store/payments.debitcard": "Debit card",
  "store/payments.giftCard": "Gift card",
  "store/payments.id": "Payment ID: {id}",
  "store/payments.installments": "(pay in {installments})",
  "store/payments.transaction.id": "Transaction ID: {id}",
  "store/pickup.header.title": "Pickup",
  "store/products.quantity": "{quantity, plural, one {# item} other {# items}}",
  "store/shipping.header.title": "Delivery",
  "store/shipping.header.wishlist.address": "Address from: {giftRegistryName}"
}

```