[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 sku-list/react/typings.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { ApolloError } from 'apollo-client'
import { ReactNodeArray } from 'react'
import { InjectedIntl } from 'react-intl'

export interface Product {
  productId: string
  description?: string
  productName: string
  productReference: string
  linkText: string
  brand: string
  brandId: number
  items: Item[]
  categories: string[]
}

export interface Item {
  itemId: string
  name: string
  measurementUnit: string
  unitMultiplier: number
  images: Image[]
  sellers: Seller[]
  options?: BuyButtonItemOption[]
  variations: Variation[]
}

export interface Variation {
  name: string
  values: string[]
}

export interface LineItem {
  sellingPriceWithAssemblies: number
  price: number
  quantity: number
}

export interface Image {
  imageUrls?: string[]
  imageUrl: string
  thresholds?: number[]
  thumbnailUrl?: string
  imageText: string
  imageLabel?: string
  imageTag?: string
}

export interface Seller {
  sellerId: string | number
  sellerName: string
  commertialOffer: CommercialOffer
}

export interface CommercialOffer {
  Price: number
  ListPrice: number
  PriceWithoutDiscount: number
  RewardValue: number
  AvailableQuantity: number
  Installments: Installment[]
}

export interface Installment {
  Value: number
  InterestRate: number
  TotalValuePlusInterestRate: number
  NumberOfInstallments: number
  Name: string
}

export interface PriceBreaks {
  priceBreaks: PriceBreak[]
}

export interface PriceBreak {
  itemId: string
  maxQuantity: number
  minQuantity: number
  price: number
  leadTime: string
  totalScheduledTime: string
}

export interface PriceBreakResult {
  loading: boolean
  error?: ApolloError
  data: PriceBreaks
}

export interface MessageProps {
  showItemsPrice?: boolean
  skuItems: LineItem[]
}

export interface BuyButtonItemOption {
  id: string
  quantity: number
  assemblyId: string
  seller?: string
}

export interface InstalledApp {
  version: string
}

export interface CheckoutVersion {
  installedApp: InstalledApp
}

export type GroupId = string

export type InputValues = Record<string, string>

export interface AssemblyOptionItem {
  id: string
  quantity: number
  seller: string
  initialQuantity: number
  choiceType: GroupTypes
  name: string
  price: number
  children: Record<string, AssemblyOptionItem[]> | null
}

export interface AssemblyOptions {
  items: Record<GroupId, AssemblyOptionItem[]>
  inputValues: Record<GroupId, InputValues>
  areGroupsValid: Record<GroupId, boolean>
}

export type Option = ItemOption | InputValuesOption

export interface ItemOption {
  assemblyId: string
  id: string
  quantity: number
  seller: string
  options?: Option[]
}

export type InputValue = Record<string, string | boolean>

export interface InputValuesOption {
  assemblyId: string
  inputValues: InputValue
}

export interface AddedItem {
  id: string
  name: string
  quantity: number
  sellingPrice: number
  sellingPriceWithAssemblies: number
  assemblyOptions?: ParsedAssemblyOptionsMeta
}

export type GroupTypes = 'SINGLE' | 'TOGGLE' | 'MULTIPLE'

export interface CartAddedOption {
  normalizedQuantity: number
  extraQuantity: number
  choiceType: GroupTypes
  item: AddedItem
}

export interface CartRemovedOption {
  name: string
  initialQuantity: number
  removedQuantity: number
}

export interface ParsedAssemblyOptionsMeta {
  added: CartAddedOption[]
  removed: CartRemovedOption[]
  parentPrice: number
}

export interface ParsedAssemblyOptions {
  options: Option[]
  assemblyOptions: ParsedAssemblyOptionsMeta
}

export interface BuyButtonItem {
  skuId: string
  quantity: number
  seller?: string | number
  name?: string
  price?: number
  variant?: string
  brand?: string
  options: BuyButtonItemOption[]
}

export interface CartItem {
  index: number
  quantity: number
  detailUrl: string
  name: string
  brand: string
  category: string
  productRefId: string
  seller: string | number
  price: number
  listPrice: number
  variant: string
  skuId: string
  imageUrl: string
  options: Option[]
  assemblyOptions: ParsedAssemblyOptionsMeta
  sellingPriceWithAssemblies: number
}

export interface MiniCartItem {
  quantity: number
  detailUrl: string
  name: string
  brand: string
  category: string
  productRefId: string
  seller: string | number
  sellingPrice: number
  listPrice: number
  skuName: string
  id: string
  imageUrl: string
  options: Option[]
  assemblyOptions: ParsedAssemblyOptionsMeta
  sellingPriceWithAssemblies: number
}

export interface SkuSelector {
  isVisible: boolean
  areAllVariationsSelected: boolean
}

export interface CustomApp {
  id?: string
  fields?: any
}

export interface Address {
  addressName?: string
  addressType?: string
  city?: string
  complement?: string
  country?: string
  id?: string
  neighborhood?: string
  number?: string
  postalCode?: string
  receiverName?: string
  reference?: string
  state?: string
  street?: string
  userId?: string
}

export interface AddItemResponse {
  data: {
    addItem: {
      items: {
        id: string
        seller: string | number
      }[]
    }
  }
}

export interface OrderFormContext {
  message: {
    isSuccess?: boolean
    message?: string
  }
  loading: boolean
  refetch: () => Promise<void>
  addItem: ({ variables }: { variables: OrderFormArgs }) => AddItemResponse
  updateOrderForm: () => void
  updateOrderFormProfile: () => void
  updateAndRefetchOrderForm: () => void
  updateToastMessage: () => void
  updateOrderFormShipping: () => void
  orderForm: OrderFormArgs
}

export interface TooltipArgs {
  showTooltipOnSkuNotSelected: boolean
  skuSelector: SkuSelector
  orderFormContext: OrderFormContext
}

export interface BuyButtonWrapperProps {
  intl: InjectedIntl
  addToCart: (items: MiniCartItem[]) => AddToCartResponse
  showToast?: () => void
  onAddStart?: () => void
  onAddFinish?: () => void
  children: ReactNodeArray
  isOneClickBuy?: boolean
  shouldOpenMinicart?: boolean
  setMinicartOpen: () => void
  showItemsPrice?: boolean
  available?: boolean
  skuItems: CartItem[]
  large: boolean
  disabled?: boolean
  shouldAddToCart?: boolean
  customToastURL?: string
  showTooltipOnSkuNotSelected?: boolean
  checkoutVersion?: CheckoutVersion
}

export interface AddToCartResponse {
  data: {
    addToCart: {
      id: string
      seller: string | number
    }[]
  }
}

export interface BuyButtonProps {
  intl: InjectedIntl
  large: boolean
  // addToCart: (items: MiniCartItem[]) => AddToCartResponse
  addToCart: any
  skuItems: CartItem[]
  onAddStart?: () => void
  onAddFinish?: () => void
  // setMinicartOpen: (open: true) => void
  setMinicartOpen: any
  available?: boolean
  orderFormContext: OrderFormContext
  isOneClickBuy?: boolean
  children: ReactNodeArray
  disabled?: boolean
  shouldAddToCart?: boolean
  shouldOpenMinicart?: boolean
  showTooltipOnSkuNotSelected?: boolean
  checkoutUrl?: string
  customToastURL?: string
  showToast?: () => void
}

export interface ToastMessageArgs {
  success: boolean
  isNewItem?: boolean
}

export interface OrderFormArgs {
  orderFormId?: string
  value?: number
  items: {
    id: string
    seller: string | number
    options: Option[]
    quantity: number
  }[]
  customData: {
    customApps: CustomApp[]
  }
  shippingData: {
    address: Address
    availableAddresses: any[]
  }
}

export enum InitialSelectionType {
  complete = 'complete',
  image = 'image',
  empty = 'empty',
}

export enum DisplayMode {
  select = 'select',
  default = 'default',
}

export type Variations = Record<string, string[]>

export type Maybe<T> = T | null | undefined

export interface BuyButtonContextState {
  clicked: boolean
}

export interface ProductContextState {
  selectedItem: Maybe<Item>
  product: Maybe<Product>
  selectedQuantity: number
  skuSelector: {
    isVisible: boolean
    areAllVariationsSelected: boolean
  }
  buyButton: BuyButtonContextState
  assemblyOptions: {
    items: Record<string, AssemblyOptionItem[]>
    inputValues: Record<string, InputValues>
    areGroupsValid: Record<string, boolean>
  }
}

export interface AssemblyOptionInput {
  id?: string
  quantity?: number
  assemblyId: string
  seller?: string
  inputValues?: Record<string, string | boolean>
  options?: AssemblyOptionInput[]
}

export interface OrderFormItemInput {
  id?: number
  index?: number
  quantity?: number
  seller?: string
  uniqueId?: string
  options?: AssemblyOptionInput[]
}

```


[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 sku-list/react/SkuQuantitySelector.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SkuQuantitySelector from './components/SkuQuantitySelector'

export default SkuQuantitySelector

```


[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 sku-list/react/SkuImage.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SkuImage from './components/SkuImage'

export default SkuImage

```


[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 sku-list/react/SkuBuyButton.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SkuBuyButton from './components/SkuBuyButton'

export default SkuBuyButton

```


[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 sku-list/react/SellerPrice.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SellerPrice from './components/SellerPrice'

export default SellerPrice

```


[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 sku-list/react/SkuHighlights.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SkuHighlights from './components/SkuHighlights'

export default SkuHighlights

```


[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 sku-list/react/SkuPrice.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SkuPrice from './components/SkuPrice'

export default SkuPrice

```


[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 sku-list/react/SellerInventory.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SellerInventory from './components/SellerInventory'

export default SellerInventory

```


[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 sku-list/react/SkuSpecifications.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import SkuSpecifications from './components/SkuSpecifications'

export default SkuSpecifications

```


[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 sku-list/store/blocks.json from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "sku-list": {
    "blocks": ["sku-content.desktop", "sku-content.mobile"]
  },
  "sku-content.desktop": {
    "children": [
      "sku-name",
      "sku-image",
      "sku-seller",
      "sku-price",
      "sku-inventory",
      "sku-quantity-selector",
      "sku-buy-button",
      "sku-specifications",
      "sku-highlights"
    ]
  },
  "sku-content.mobile": {
    "children": [
      "sku-name",
      "sku-image",
      "sku-seller",
      "sku-price",
      "sku-inventory",
      "sku-quantity-selector",
      "sku-buy-button",
      "sku-specifications",
      "sku-highlights"
    ]
  },
  "sku-seller": {
    "children": ["seller-name", "seller-inventory", "seller-price"]
  },
  "sku-quantity-selector": {
    "blocks": ["item-quantity"]
  },
  "sku-buy-button": {
    "blocks": ["item-buy-button"]
  }
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "sku-list": {
    "component": "SkuList",
    "allowed": ["sku-content.desktop", "sku-content.mobile"]
  },
  "sku-content": {
    "component": "SkuContent",
    "composition": "children",
    "allowed": [
      "flex-layout",
      "sku-name",
      "sku-seller",
      "sku-image",
      "sku-price",
      "sku-inventory",
      "sku-quantity-selector",
      "sku-buy-button",
      "sku-specifications",
      "sku-highlights"
    ]
  },
  "sku-content.desktop": {
    "device": "desktop"
  },
  "sku-content.mobile": {
    "device": "mobile"
  },
  "sku-name": {
    "component": "SkuName"
  },
  "sku-price": {
    "component": "SkuPrice"
  },
  "sku-inventory": {
    "component": "SkuInventory"
  },
  "sku-image": {
    "component": "SkuImage"
  },
  "sku-seller": {
    "component": "SkuSeller",
    "composition": "children",
    "allowed": [
      "flex-layout",
      "seller-name",
      "seller-inventory",
      "seller-price"
    ]
  },
  "seller-name": {
    "component": "SellerName"
  },
  "seller-inventory": {
    "component": "SellerInventory"
  },
  "seller-price": {
    "component": "SellerPrice"
  },
  "item-quantity": {
    "component": "ItemQuantity"
  },
  "sku-quantity-selector": {
    "component": "SkuQuantitySelector",
    "allowed": ["item-quantity"]
  },
  "item-buy-button": {
    "component": "BuyButton"
  },
  "sku-buy-button": {
    "component": "SkuBuyButton",
    "allowed": ["item-buy-button"]
  },
  "sku-specifications": {
    "component": "SkuSpecifications"
  },
  "sku-highlights": {
    "component": "SkuHighlights"
  }
}

```


[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 sku-list/react/mutations/setOpenMinicart.gql from the sku-list VTEX app.

[Assistant]
Here's the implementation:

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

```


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

[User] Show me the implementation of sku-list/react/mutations/addToCart.gql from the sku-list VTEX app.

[Assistant]
Here's the implementation:

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

```


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

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

[Assistant]
Here's the implementation:

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

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

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

```


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

[User] Show me the implementation of sku-list/react/typings/jsx.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import 'react'

declare module 'react' {
  interface ImgHTMLAttributes<T> extends HTMLAttributes<T> {
    loading?: 'lazy' | 'eager' | 'auto'
  }
}

```


[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 sku-list/react/typings/vtex.responsive-values.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.responsive-values' {
  const useResponsiveValues: (props: any) => any
}

```


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

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

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.store-components/BuyButton'
declare module 'vtex.store-components/SKUSelector'
declare module 'vtex.store-components/ProductPrice'
declare module 'vtex.store-components/GradientCollapse'

```


[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 sku-list/react/typings/vtex.product-context.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.product-context'
declare module 'vtex.product-context/useProduct'

declare module 'vtex.product-context/ProductDispatchContext' {
  type DispatchFunction = (payload: { type: string; args?: any }) => void
  export const useProductDispatch: () => DispatchFunction
}

```


[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 sku-list/react/typings/vtex.checkout-resources.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.checkout-resources/Mutations'

```


[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 sku-list/react/typings/vtex.product-quantity.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.product-quantity/ProductQuantity'

```


[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 sku-list/react/typings/vtex.render-runtime.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

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

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

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

  interface ExtensionPointProps {
    id: string
    [key: string]: any
  }

  interface ChildBlock<BlockProps> {
    props: BlockProps
  }

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

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

  interface KeyValue {
    value: string
  }

  interface Session {
    id: string
    namespaces: {
      profile: {
        isAuthenticated: KeyValue
      }
    }
  }

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

  export interface RenderSession {
    sessionPromise: Promise<SessionPromise>
  }

  export interface SessionPromise {
    response: Session | SessionUnauthorized
  }
}

```


[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 sku-list/react/typings/graphql.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

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

  const value: DocumentNode
  export default value
}

```


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

[User] Show me the implementation of sku-list/react/queries/installedApp.gql from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```graphql
query installedApp($slug: String!) {
  installedApp(slug: $slug) {
    version
  }
}

```


[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 sku-list/react/utils/numberFormatter.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
const hasNavigator = typeof navigator !== 'undefined'

export const formatNumber = (numberLiteral?: number) => {
  if (!numberLiteral || isNaN(numberLiteral)) {
    return ''
  }

  return hasNavigator && numberLiteral.toLocaleString(navigator.language)
}

```


[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 sku-list/react/utils/aspectRatioUtil.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { changeImageUrlSize } from './generateUrl'

type AspectRatio = string | number

/** Parses ratio values into a multiplier to set the image height.
 * For example, turns "3:4" into 1.333, so the image height will be
 * 1.333 times its width.
 */
const parseAspectRatio = (input?: AspectRatio | null) => {
  if (!input) {
    return null
  }
  if (typeof input === 'string') {
    if (input === 'auto') {
      return null
    }
    const separator = ':'
    const data = input.split(separator)
    if (data.length !== 2) {
      return null
    }

    const [ width, height ] = data
    const ratio = parseFloat(height) / parseFloat(width)

    if (typeof ratio !== 'number' || isNaN(ratio)) {
      return null
    }

    return ratio
  }

  if (typeof input === 'number') {
    return input
  }

  return null
}

export const imageUrl = (src: string, size: number, maxSize: number, aspectRatio?: AspectRatio) => {
  let width = size
  let height: number | string = 'auto'

  if (aspectRatio && aspectRatio !== 'auto') {
    height = size * (parseAspectRatio(aspectRatio) || 1)

    if (width > maxSize) {
      height = height / (width / maxSize)
      width = maxSize
    }

    if (height > maxSize) {
      width = width / (height / maxSize)
      height = maxSize
    }

    width = Math.round(width)
    height = Math.round(height)
  } else {
    width = Math.min(maxSize, width)
  }

  return changeImageUrlSize(src, width, height)
}

```


[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 sku-list/react/utils/constants.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const MAX_VISIBLE_ITEMS_IN_TABLE = 2
export const MAX_ROWS_PRODUCT_PRICE_BREAKS_TABLE = 12
export const CURRENCY_SYMBOL = '$'

```


[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 sku-list/react/utils/generateImageConfig.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { changeImageUrlSize } from './generateUrl'
import { Image } from '../typings'

const thumbnailSize = 160

export default function generateImageConfig(image: Image) {
  return {
    imageUrl: image.imageUrl,
    thumbnailUrl: changeImageUrlSize(image.imageUrl, thumbnailSize),
    imageText: image.imageText,
    imageLabel: image.imageLabel,
  }
}

```


[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 sku-list/react/utils/enums.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const THUMBS_POSITION_HORIZONTAL = {
  LEFT: 'left',
  RIGHT: 'right',
}

export const THUMBS_ORIENTATION = {
  VERTICAL: 'vertical',
  HORIZONTAL: 'horizontal',
}

export const DEFAULT_EXCLUDE_IMAGE_WITH = 'skuvariation'

```


[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 sku-list/react/utils/generateUrl.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

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

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

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

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

export const changeImageUrlSize = (
  imageUrl?: string,
  width: string | number = DEFAULT_WIDTH,
  height: string | number = DEFAULT_HEIGHT,
) => {
  if (!imageUrl) return
  typeof width === 'number' && (width = Math.min(width, MAX_WIDTH))
  typeof height === 'number' && (height = Math.min(height, MAX_HEIGHT))

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

  return `${normalizedImageUrl}${queryStringSeparator}width=${width}&height=${height}&aspect=true`
}

```


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

[User] Show me the implementation of sku-list/react/components/SkuInventory.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSku } from './SkuContext'
import { Item, Seller } from '../typings'
import { useCssHandles } from 'vtex.css-handles'
import { pathOr } from 'ramda'
import { FormattedMessage } from 'react-intl'

const CSS_HANDLES = ['inventoryContainer', 'inventory'] as const

interface Props {
  showLabel: boolean
}

const SkuInventory = ({ showLabel }: Props) => {
  const { sku }: { sku: Item } = useSku()
  const handles = useCssHandles(CSS_HANDLES)
  const inventory: number = sku.sellers
    .map((seller: Seller) =>
      pathOr(0, ['commertialOffer', 'AvailableQuantity'], seller)
    )
    .reduce(
      (accumulator: number, availableQuantity: number) =>
        accumulator + availableQuantity
    )

  return (
    <div
      className={`pt3 pb5 t-body c-muted-1 lh-copy ${handles.inventoryContainer}`}>
      {showLabel && (
        <span className="t-body c-on-base fw7 pr3">
          <FormattedMessage id="store/sku-list.inventory.title" />:{' '}
        </span>
      )}
      <span className={`${handles.inventory}`}>{inventory}</span>
    </div>
  )
}

SkuInventory.defaultProps = {
  showLabel: true,
}

SkuInventory.schema = {
  title: 'admin/editor.sku-list.inventory.title',
  description: 'admin/editor.sku-list.inventory.description',
  type: 'object',
  properties: {
    showLabel: {
      type: 'boolean',
      title: 'admin/editor.sku-list.inventory.showLabel.title',
      default: true,
      isLayout: false,
    },
  },
}

export default SkuInventory

```


[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 sku-list/react/components/SkuContext.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useReducer } from 'react'
import { createContext, useContext } from 'react'
import { Item, Product } from '../typings'

const SkuContext = createContext<State | undefined>(undefined)
const SkuDispatchContext = createContext<Dispatch | undefined>(undefined)

interface State {
  product: Product
  sku: Item
  isHovering: boolean
  isLoading: boolean
  selectedQuantity: number
  buyButton: {
    clicked: boolean
  }
}

type Dispatch = (action: Action) => void

interface SetHoverAction {
  type: 'SET_HOVER'
  args: {
    isHovering: boolean
  }
}

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

interface SetProductQuantity {
  type: 'SET_QUANTITY'
  args: {
    quantity: number
  }
}

interface SetBuyButtonClicked {
  type: 'SET_BUY_BUTTON_CLICKED'
  args: { clicked: boolean }
}

type Action =
  | SetHoverAction
  | SetLoadingAction
  | SetProductQuantity
  | SetBuyButtonClicked

export function reducer(state: State, action: Action) {
  switch (action.type) {
    case 'SET_HOVER': {
      return {
        ...state,
        isHovering: action.args.isHovering,
      }
    }
    case 'SET_LOADING': {
      return {
        ...state,
        isLoading: action.args.isLoading,
      }
    }
    case 'SET_QUANTITY': {
      return {
        ...state,
        selectedQuantity: action.args.quantity,
      }
    }
    case 'SET_BUY_BUTTON_CLICKED': {
      const args = action.args || {}
      return {
        ...state,
        buyButton: {
          ...state.buyButton,
          clicked: args.clicked,
        },
      }
    }
    default:
      return state
  }
}

interface Props {
  sku: Item
  product: Product
  children: any
}

export const SkuProvider = ({ sku, product, children }: Props) => {
  const initialState = {
    product,
    sku,
    isHovering: false,
    isLoading: false,
    selectedQuantity: 1,
    buyButton: {
      clicked: false,
    },
  }

  const [state, dispatch] = useReducer(reducer, initialState)

  return (
    <SkuContext.Provider value={state}>
      <SkuDispatchContext.Provider value={dispatch}>
        {children}
      </SkuDispatchContext.Provider>
    </SkuContext.Provider>
  )
}

export function useSkuDispatch() {
  const context = useContext(SkuDispatchContext)

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

  return context
}

export function useSku() {
  const context = useContext(SkuContext)

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

  return context
}

```


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

[User] Show me the implementation of sku-list/react/components/SkuBuyButton.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { BuyButtonItem, Item } from '../typings'
import { useSku } from './SkuContext'

import { ExtensionPoint } from 'vtex.render-runtime'
import { path } from 'ramda'

interface Props {
  sku: Item
  selectedQuantity: number
}

const SkuBuyButton = () => {
  const { sku, selectedQuantity }: Props = useSku()
  const buyButtonItem: BuyButtonItem = {
    skuId: sku.itemId,
    seller: path<string | number>(['sellers', 0, 'sellerId'], sku),
    options: sku.options || [],
    quantity: selectedQuantity,
  }

  return (
    <div>
      <ExtensionPoint
        id="item-buy-button"
        selectedItem={sku}
        selectedQuantity={selectedQuantity}
        skuItems={[buyButtonItem]}
        isOneClickBuy={false}
        shouldAddToCart
      />
    </div>
  )
}

export default SkuBuyButton

```


[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 sku-list/react/components/SkuName.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSku } from './SkuContext'
import { Item } from '../typings'
import { useCssHandles } from 'vtex.css-handles'
import { FormattedMessage } from 'react-intl'

const CSS_HANDLES = ['skuName'] as const

interface Props {
  showLabel: boolean
}

const SkuName = ({ showLabel }: Props) => {
  const { sku }: { sku: Item } = useSku()
  const handles = useCssHandles(CSS_HANDLES)
  return (
    <div>
      {showLabel && (
        <span className="t-body c-on-base fw7 pr3">
          <FormattedMessage id="store/sku-list.sku.name.title" />:{' '}
        </span>
      )}
      <h4 className={`${handles.skuName} t-heading-4 c-muted-1`}>{sku.name}</h4>
    </div>
  )
}

export default SkuName

```


[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 sku-list/react/components/SkuImage.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useMemo } from 'react'
import { useSku } from './SkuContext'
import { path, map } from 'ramda'

import generateImageConfig from '../utils/generateImageConfig'
import { Item, Image } from '../typings'
import { useCssHandles } from 'vtex.css-handles'

interface Props {
  images: Image[]
}

const CSS_HANDLES = ['skuImage']

const SkuImagesWrapper = (props: Props) => {
  const { sku }: { sku: Item } = useSku()

  const images: Image[] = useMemo(
    () =>
      props.images != null
        ? props.images
        : map(generateImageConfig, path(['images'], sku) || []),
    [props.images, sku]
  )

  const handles = useCssHandles(CSS_HANDLES)
  return (
    <div className={handles.skuImage}>
      <img
        src={path([0, 'imageUrl'], images)}
        alt={path([0, 'imageText'], images)}
      />
    </div>
  )
}

export default SkuImagesWrapper

```


[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 sku-list/react/components/Loader.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import ContentLoader from 'react-content-loader'

const Loader = () => (
  <ContentLoader
    height={170}
    width={180}
    style={{
      width: '100%'
    }}>
    <rect width="180" height="180" />
  </ContentLoader>
)

export default Loader

```


[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 sku-list/react/components/SellerName.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSkuSeller } from './SkuSellerContext'
import { Seller } from '../typings'
import { useCssHandles } from 'vtex.css-handles'
import { FormattedMessage } from 'react-intl'

const CSS_HANDLES = ['sellerName'] as const

interface Props {
  showLabel: boolean
}

const SellerName = ({ showLabel }: Props) => {
  const { seller }: { seller: Seller } = useSkuSeller()
  const handles = useCssHandles(CSS_HANDLES)
  return seller ? (
    <div>
      {showLabel && (
        <span className="t-body c-on-base fw7 pr3">
          <FormattedMessage id="store/sku-list.seller.name.title" />:{' '}
        </span>
      )}
      <h5 className={`${handles.sellerName} t-heading-5 c-muted-1`}>
        {seller.sellerName}
      </h5>
    </div>
  ) : (
    <div />
  )
}

export default SellerName

```


[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 sku-list/react/components/SkuSellerContext.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { ReactNode, useReducer } from 'react'
import { createContext, useContext } from 'react'
import { Seller, Item, Product } from '../typings'

const SkuSellerContext = createContext<State | undefined>(undefined)
const SkuSellerDispatchContext = createContext<Dispatch | undefined>(undefined)

interface State {
  seller: Seller
  item: Item
  product: Product
  isHovering: boolean
  isLoading: boolean
  selectedQuantity: number
}

type Dispatch = (action: Action) => void

// type SetProductAction = {
//   type: 'SET_PRODUCT',
//   args: {
//     product: any
//   }
// }

// type SetProductQueryAction = {
//   type: 'SET_PRODUCT_QUERY',
//   args: {
//     query: string
//   }
// }

interface SetHoverAction {
  type: 'SET_HOVER'
  args: {
    isHovering: boolean
  }
}

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

interface SetProductQuantity {
  type: 'SET_QUANTITY'
  args: {
    quantity: number
  }
}

type Action = SetHoverAction | SetLoadingAction | SetProductQuantity

export function reducer(state: State, action: Action) {
  switch (action.type) {
    // case 'SET_PRODUCT': {
    //   const product = action.args.product
    //   return {
    //     ...state,
    //     product: product,
    //     //TODO: STOP USING PRODUCT.SKU https://app.clubhouse.io/vtex/story/18547/productsummarycontext-refactor
    //     selectedItem: product.sku
    //   }
    // }
    case 'SET_HOVER': {
      return {
        ...state,
        isHovering: action.args.isHovering,
      }
    }
    case 'SET_LOADING': {
      return {
        ...state,
        isLoading: action.args.isLoading,
      }
    }
    case 'SET_QUANTITY': {
      return {
        ...state,
        selectedQuantity: action.args.quantity,
      }
    }
    // case 'SET_PRODUCT_QUERY':
    //   return {
    //     ...state,
    //     query: action.args.query,
    //   }
    default:
      return state
  }
}

interface Props {
  seller: Seller
  item: Item
  product: Product
  children?: ReactNode[]
}

export const SkuSellerProvider = ({
  seller,
  item,
  product,
  children,
}: Props) => {
  const initialState = {
    seller,
    item,
    product,
    isHovering: false,
    isLoading: false,
    selectedQuantity: 1,
  }

  const [state, dispatch] = useReducer(reducer, initialState)

  return (
    <SkuSellerContext.Provider value={state}>
      <SkuSellerDispatchContext.Provider value={dispatch}>
        {children}
      </SkuSellerDispatchContext.Provider>
    </SkuSellerContext.Provider>
  )
}

export function useSkuSellerDispatch() {
  const context = useContext(SkuSellerDispatchContext)

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

  return context
}

export function useSkuSeller() {
  const context = useContext(SkuSellerContext)

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

  return context
}

```


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

[User] Show me the implementation of sku-list/react/components/SkuPrice.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSku } from './SkuContext'
import { Item } from '../typings'
import { useCssHandles } from 'vtex.css-handles'
import { path } from 'ramda'
import { FormattedCurrency } from 'vtex.format-currency'
import { FormattedMessage } from 'react-intl'

const CSS_HANDLES = ['priceContainer'] as const

interface Props {
  showLabel: boolean
}

const SkuPrice = ({ showLabel }: Props) => {
  const { sku }: { sku: Item } = useSku()
  const sellingPrice: number | undefined = path(
    ['sellers', 0, 'commertialOffer', 'Price'],
    sku
  )
  const handles = useCssHandles(CSS_HANDLES)

  return sellingPrice ? (
    <div
      className={`pt3 pb5 t-body c-muted-1 lh-copy ${handles.priceContainer}`}>
      {showLabel && (
        <span className="t-body c-on-base fw7 pr3">
          <FormattedMessage id="store/sku-list.sku.price.title" />:{' '}
        </span>
      )}
      <span>
        <FormattedCurrency value={sellingPrice} />
      </span>
    </div>
  ) : (
    <div />
  )
}

export default SkuPrice

```


[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 sku-list/react/components/SkuHighlights.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSku } from './SkuContext'
import { useCssHandles } from 'vtex.css-handles'
import { Item, Variation } from '../typings'
import { toVariationArray, useVariations } from '../hooks/useVariations'
import { propOr } from 'ramda'
import HtmlParser from 'react-html-parser'

const CSS_HANDLES = [
  'highlightContent',
  'itemHighlight',
  'highlightTitle',
  'highlightValue',
]

interface Props {
  conditional: {
    typeSpecifications: string
    highlight: string
  }
  skuSelected: Item
  visibleVariations?: string[]
  showLabel: boolean
}

const SkuHighlights = (props: Props) => {

  const valuesFromContext = useSku()
  const { conditional, showLabel } = props
  const skuSelected =
    props.skuSelected != null
      ? props.skuSelected
      : valuesFromContext.sku
  const skuItems = [skuSelected]
  const shouldNotShow =
    skuItems.length === 0 ||
    !skuSelected?.variations ||
    skuSelected.variations.length === 0
  const variations = useVariations(skuItems, shouldNotShow, props.visibleVariations)

  const handles = useCssHandles(CSS_HANDLES)

  if (shouldNotShow || !skuSelected) {
    return null
  }

  const getHighlights = () => {
    const choose: string = propOr('', 'highlight', conditional)
    const allSpecifications: Variation[] = toVariationArray(variations)

    if (choose === 'admin/editor.sku-list.highlights.allSpecifications') {
      return allSpecifications
    }

    if (choose === 'admin/editor.sku-list.highlights.chooseDefaultSpecification') {
      const typeSpecifications: string = propOr('', 'typeSpecifications', conditional)
      const specificationNames: string[] = typeSpecifications.trim().split(',')

      return specificationNames.reduce((acc: Variation[], item: string) => {
        const highlight = allSpecifications.filter(
          x => x.name.toLowerCase() === item.trim().toLowerCase(),
        )
        return acc.concat(highlight)
      }, [])
    }
    return []
  }

  const highlights: Variation[] = getHighlights()

  return (
    <div className={`${handles.highlightContent} pt3 pb5`}>
      {highlights.length == 0 ? <div className={`${handles.itemHighlight} pv2`}>
        <span
          className={`${handles.highlightValue} t-body c-muted-1 lh-copy `}
        >
          {'N/A'}
          </span>
      </div> : highlights.map((item: Variation, i: number) => (
        <div
          className={`${handles.itemHighlight} pv2`}
          data-name={item.name}
          data-value={item.values[0]}
          key={i}
        >
          {showLabel && (<span
            className={`${handles.highlightTitle} t-body c-on-base fw7 pr3 `}
          >
            {HtmlParser(item.name)}
            {': '}
          </span>)}
          <span
            className={`${handles.highlightValue} t-body c-muted-1 lh-copy `}
          >
            {HtmlParser(item.values[0])}
          </span>
        </div>
      ))}
    </div>
  )
}

SkuHighlights.defaultProps = {
  showLabel: true,
}

SkuHighlights.schema = {
  title: 'admin/editor.sku-list.highlights.title',
  description: 'admin/editor.sku-list.highlights.description',
  type: 'object',
  definitions: {
    highlightGroupDefault: {
      title: 'highlightGroupDefault',
      type: 'object',
      properties: {
        highlight: {
          title: 'admin/editor.sku-list.highlights.default',
          type: 'string',
          enum: [
            'admin/editor.sku-list.highlights.allSpecifications',
            'admin/editor.sku-list.highlights.chooseDefaultSpecification',
          ],
          default: 'admin/editor.sku-list.highlights.allSpecifications',
        },
      },
      required: ['highlight'],
      dependencies: {
        highlight: {
          oneOf: [
            {
              properties: {
                highlight: {
                  enum: [
                    'admin/editor.sku-list.highlights.allSpecifications',
                  ],
                },
              },
            },
            {
              properties: {
                highlight: {
                  enum: [
                    'admin/editor.sku-list.highlights.chooseDefaultSpecification',
                  ],
                },
                typeSpecifications: {
                  type: 'string',
                  title:
                    'admin/editor.sku-list.highlights.typeSpecifications.title',
                },
              },
              required: [''],
            },
          ],
        },
      },
    },
  },
  properties: {
    showHighlight: {
      type: 'boolean',
      title: 'admin/editor.sku-list.highlights.showHighlight.title',
      default: false,
      isLayout: false,
    },
    showLabel: {
      type: 'boolean',
      title: 'admin/editor.sku-list.highlights.showLabel.title',
      default: true,
      isLayout: false,
    },
    conditional: {
      title: 'Conditional',
      $ref: '#/definitions/highlightGroupDefault',
    },
  },
}

export default SkuHighlights

```


[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 sku-list/react/components/SkuSeller.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { ReactNode } from 'react'
import { Item, Product, Seller } from '../typings'
import { SkuSellerProvider } from './SkuSellerContext'

interface Props {
  seller: Seller
  item: Item
  product: Product
  children?: ReactNode[]
}

const SkuSeller = ({ seller, item, product, children }: Props) => {
  return (
    <SkuSellerProvider seller={seller} item={item} product={product}>
      {children}
    </SkuSellerProvider>
  )
}

export default SkuSeller

```


[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 sku-list/react/components/SkuList.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { path, pathOr } from 'ramda'
import React, { FunctionComponent, useContext } from 'react'
import { ProductContext } from 'vtex.product-context'
import { ExtensionPoint } from 'vtex.render-runtime'
import { useDevice } from 'vtex.device-detector'
import { Item, Product } from '../typings'

enum Device {
  mobile = 'mobile',
  desktop = 'desktop',
}

const SkuListComponent = React.memo(({ device }: { device: Device }) => {
  const valuesFromContext = useContext(ProductContext)
  const items: Item[] = pathOr([], ['product', 'items'], valuesFromContext)
  const product: Product | undefined = path(['product'], valuesFromContext)

  const renderContent = (item: Item) => {
    switch (device) {
      case Device.mobile:
        return (
          <ExtensionPoint
            id="sku-content.mobile"
            item={item}
            product={product}
            key={`sku-content-${item.itemId}`}
          />
        )
      case Device.desktop:
      default:
        return (
          <ExtensionPoint
            id="sku-content.desktop"
            item={item}
            product={product}
            key={`sku-content-${item.itemId}`}
          />
        )
    }
  }

  return (
    <div className="mw9 center pa3">
      {items.map((item: Item) => renderContent(item))}
    </div>
  )
})

SkuListComponent.displayName = 'SkuListComponent'

const SkuList: FunctionComponent = () => {
  const { isMobile } = useDevice()

  return <SkuListComponent device={isMobile ? Device.mobile : Device.desktop} />
}

export default SkuList

```


[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 sku-list/react/components/SellerInventory.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSkuSeller } from './SkuSellerContext'
import { Seller } from '../typings'
import { useCssHandles } from 'vtex.css-handles'
import { path } from 'ramda'
import { FormattedMessage } from 'react-intl'

const CSS_HANDLES = ['sellerInventoryWrapper', 'sellerInventory'] as const

interface Props {
  showLabel: boolean
}

const SellerInventory = ({ showLabel }: Props) => {
  const { seller }: { seller: Seller } = useSkuSeller()
  const handles = useCssHandles(CSS_HANDLES)
  return seller ? (
    <div className={`${handles.sellerInventoryWrapper} lh-copy`}>
      {showLabel && (
        <span className="t-body c-on-base fw7 pr3">
          <FormattedMessage id="store/sku-list.inventory.title" />:{' '}
        </span>
      )}
      <span className={`${handles.sellerInventory}`}>
        {path(['commertialOffer', 'AvailableQuantity'], seller)}
      </span>
    </div>
  ) : (
    <div />
  )
}

export default SellerInventory

```


[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 sku-list/react/components/SkuSpecifications.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState, Fragment } from 'react'
import HtmlParser from 'react-html-parser'
import { FormattedMessage } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'

import { InitialSelectionType, DisplayMode, Item, Variation } from '../typings'
import { useDevice } from 'vtex.device-detector'
import { useSku } from './SkuContext'
import GradientCollapse from 'vtex.store-components/GradientCollapse'
import { toVariationArray, useVariations } from '../hooks/useVariations'

const CSS_HANDLES = [
  'specificationsTableContainer',
  'specificationsTabsContainer',
  'specificationsTitle',
  'specificationsTable',
  'specificationsTab',
  'specificationsTablePropertyHeading',
  'specificationsTableSpecificationHeading',
  'specificationItemProperty',
  'specificationItemSpecifications',
]

interface Props {
  skuItems: Item[]
  skuSelected: Item
  onSKUSelected?: (skuId: string) => void
  maxItems?: number
  seeMoreLabel: string
  hideImpossibleCombinations?: boolean
  showValueNameForImageVariation?: boolean
  imageHeight?: number | object
  imageWidth?: number | object
  thumbnailImage?: string
  visibleVariations?: string[]
  showVariationsLabels?: boolean
  variationsSpacing?: number
  showVariationsErrorMessage?: boolean
  initialSelection?: InitialSelectionType
  displayMode?: DisplayMode
  collapsible: string
}

const SKUSelectorWrapper: StorefrontFunctionComponent<Props> = props => {
  const valuesFromContext = useSku()

  const { isMobile } = useDevice()

  const skuSelected =
    props.skuSelected != null
      ? props.skuSelected
      : valuesFromContext.sku

  const skuItems = [skuSelected]

  const shouldNotShow =
    skuItems.length === 0 ||
    !skuSelected?.variations ||
    skuSelected.variations.length === 0

  const variations = useVariations(skuItems, shouldNotShow, props.visibleVariations)

  const handles = useCssHandles(CSS_HANDLES)

  const [collapsed, setCollapsed] = useState(true)

  if (shouldNotShow || !skuSelected) {
    return null
  }

  const specifications: Variation[] = toVariationArray(variations)

  const specificationsTable = (
    <table
      className={`${handles.specificationsTable} w-100 bg-base border-collapse`}
    >
      <thead>
      <tr>
        <th
          className={`${handles.specificationsTablePropertyHeading} w-50 b--muted-4 bb bt c-muted-2 t-body tl pa5`}
        >
          <FormattedMessage id="store/product-description.property" />
        </th>
        <th
          className={`${handles.specificationsTableSpecificationHeading} w-50 b--muted-4 bb bt c-muted-2 t-body tl pa5`}
        >
          <FormattedMessage id="store/product-description.specification" />
        </th>
      </tr>
      </thead>
      <tbody>
      {specifications.map((specification: Variation, i: number) => (
        <tr key={i}>
          <td
            className={`${handles.specificationItemProperty} w-50 b--muted-4 bb pa5`}
          >
            {HtmlParser(specification.name)}
          </td>
          <td
            className={`${handles.specificationItemSpecifications} w-50 b--muted-4 bb pa5`}
          >
            {HtmlParser(specification.values.join(', '))}
          </td>
        </tr>
      ))}
      </tbody>
    </table>
  )

  const collapsible = props.collapsible || 'always'

  const shouldBeCollapsible = Boolean(
    collapsible === 'always' ||
    (collapsible === 'mobileOnly' && isMobile) ||
    (collapsible === 'desktopOnly' && !isMobile)
  )

  const specificationTitle = (
    <FormattedMessage id="store/specifications.title">
      {(txt) => (
        <h2 className={`${handles.specificationsTitle} t-heading-5 mb5 mt0`}>
          {HtmlParser(txt as string)}
        </h2>
      )}
    </FormattedMessage>
  )

  const tableView = (
    <Fragment>
      {specifications.length > 0 && (
        <div
          className={`${handles.specificationsTableContainer} mt9 mt0-l pl8-l`}
        >
          {specificationTitle}
          {shouldBeCollapsible ? (
            <GradientCollapse
              collapseHeight={220}
              collapsed={collapsed}
              onCollapsedChange={(_: any, newValue: boolean) => setCollapsed(newValue)}
            >
              {specificationsTable}
            </GradientCollapse>
          ) : (
            specificationsTable
          )}
        </div>
      )}
    </Fragment>
  )

  return tableView
}

SKUSelectorWrapper.schema = {
  title: 'admin/editor.skuSelector.title',
  description: 'admin/editor.skuSelector.description',
}

export default SKUSelectorWrapper

```


[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 sku-list/react/components/SkuQuantitySelector.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { Item } from '../typings'
import { useSku } from './SkuContext'

import { ExtensionPoint } from 'vtex.render-runtime'

interface Props {
  showLabel: boolean
}

const SkuQuantitySelector = ({ showLabel = false }: Props) => {
  const {
    sku,
    selectedQuantity,
  }: { sku: Item; selectedQuantity: number } = useSku()

  return (
    <div>
      <ExtensionPoint
        id="item-quantity"
        selectedItem={sku}
        showLabel={showLabel}
        selectedQuantity={selectedQuantity}
      />
    </div>
  )
}

export default SkuQuantitySelector

```


[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 sku-list/react/components/SellerPrice.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSkuSeller } from './SkuSellerContext'
import { Seller, Item } from '../typings'
import { useCssHandles } from 'vtex.css-handles'
import { path } from 'ramda'
import { FormattedCurrency } from 'vtex.format-currency'
import { FormattedMessage } from 'react-intl'

const CSS_HANDLES = ['sellerPriceContainer'] as const

interface Props {
  showLabel: boolean
}

const SellerPrice = ({ showLabel }: Props) => {
  const { seller }: { seller: Seller; item: Item } = useSkuSeller()
  const sellingPrice: number | undefined = path(
    ['commertialOffer', 'Price'],
    seller
  )
  const handles = useCssHandles(CSS_HANDLES)

  return seller ? (
    <div className={handles.sellerPriceContainer}>
      {showLabel && (
        <span className="t-body c-on-base fw7 pr3">
          <FormattedMessage id="store/sku-list.seller.price.title" />:{' '}
        </span>
      )}
      <span>
        <FormattedCurrency value={sellingPrice} />
      </span>
    </div>
  ) : (
    <div />
  )
}

export default SellerPrice

```


[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 sku-list/react/components/SkuContent.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { ReactNode } from 'react'
import { useCssHandles } from 'vtex.css-handles'
import { ExtensionPoint } from 'vtex.render-runtime'
import { Item, Product, Seller } from '../typings'
import { SkuProvider } from './SkuContext'
import useProduct from 'vtex.product-context/useProduct'
import { useProductDispatch } from 'vtex.product-context/ProductDispatchContext'
import classNames from 'classnames'

const CSS_HANDLES = ['skuContentWrapper', 'selectedSkuContentWrapper'] as const

interface Props {
  product: Product
  item: Item
  children?: ReactNode[]
}

const SkuContent = ({ item, product, children }: Props) => {
  const handles = useCssHandles(CSS_HANDLES)
  const { selectedItem }: { selectedItem: Item } = useProduct()
  const dispatch = useProductDispatch()
  const handleClick = () => {
    if (dispatch) {
      dispatch({ type: 'SET_SELECTED_ITEM', args: { item: item } })
    }
  }
  const containerClasses = classNames(
    'ba mb3 pa5',
    handles.skuContentWrapper,
    {
      [`bw1 b--muted-1 ${handles.selectedSkuContentWrapper}`]:
        selectedItem.itemId != item.itemId,
    },
    {
      [`bw1 b--blue ${handles.selectedSkuContentWrapper}`]:
        selectedItem.itemId == item.itemId,
    }
  )
  return (
    <SkuProvider sku={item} product={product}>
      <div
        className={containerClasses}
        onClick={handleClick}
        role="button"
        tabIndex={parseInt(item.itemId)}
        onKeyDown={handleClick}>
        {children}
        {item.sellers.map((seller: Seller) => (
          <ExtensionPoint
            id="sku-seller"
            seller={seller}
            item={item}
            product={product}
            key={`seller-${seller.sellerId}`}
          />
        ))}
      </div>
    </SkuProvider>
  )
}

export default SkuContent

```


[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 sku-list/react/__tests__/index.test.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
describe('Orders List Scenarios', () => {
  it('should work', () => {
    expect(1).toBe(1)
  })
})

```


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

[User] Show me the implementation of sku-list/react/graphql/checkProfileAllowed.graphql from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```graphql
query checkProfileAllowed {
  checkProfileAllowed @context(provider: "vtex.store-graphql") {
    allowed
  }
}

```


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

[User] Show me the implementation of sku-list/react/hooks/useVariations.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { Item, Variation, Variations } from '../typings'
import { useMemo } from 'react'

export const useVariations = (
  skuItems: Item[],
  shouldNotShow: boolean,
  visibleVariations?: string[]
) => {
  const result = useMemo(() => {
    if (
      shouldNotShow ||
      (visibleVariations && visibleVariations.length === 0)
    ) {
      return {}
    }
    const variations: Variations = {}
    const variationsSet: Record<string, Set<string>> = {}
    if (visibleVariations) {
      visibleVariations = visibleVariations.map(variation => variation.toLowerCase().trim())
    }

    for (const skuItem of skuItems) {
      for (const currentVariation of skuItem.variations) {
        const { name, values } = currentVariation
        if (!visibleVariations || visibleVariations.includes(name.toLowerCase().trim())) {

          const value = values[0]
          const currentSet = variationsSet[name] || new Set()
          currentSet.add(value)
          variationsSet[name] = currentSet
        }
      }
    }
    const variationsNames = Object.keys(variationsSet)
    // Transform set back to array
    for (const variationName of variationsNames) {
      const set = variationsSet[variationName]
      variations[variationName] = Array.from(set)
    }
    return variations
  }, [skuItems, shouldNotShow])
  return result
}

export const toVariationArray = (variations: Variations) => {
  let result: Variation[] = []
  const variationNames = Object.keys(variations)
  for (const variationName of variationNames) {
    result = [
      ...result,
      { name: variationName, values: variations[variationName] },
    ]
  }
  return result
}

```


[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 sku-list/react/modules/session.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { SessionPromise } from 'vtex.render-runtime'

export function getSession() {
  return window &&
    (window as any).__RENDER_8_SESSION__ &&
    (window as any).__RENDER_8_SESSION__.sessionPromise
    ? ((window as any).__RENDER_8_SESSION__.sessionPromise as Promise<
        SessionPromise
      >)
    : 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 sku-list/react/typings/vtex.store-resources/OrderFormContext.d.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.store-resources/OrderFormContext'

```


[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 sku-list/react/components/BuyButton/AddToCartButton.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import { useMutation } from 'react-apollo'
import {
  FormattedMessage,
  injectIntl,
  InjectedIntlProps,
  defineMessages,
} from 'react-intl'
import { Button, Tooltip } from 'vtex.styleguide'
import { OrderForm } from 'vtex.order-manager'
import { useCssHandles } from 'vtex.css-handles'
import { useRuntime } from 'vtex.render-runtime'
import { usePixel } from 'vtex.pixel-manager/PixelContext'
import { addToCart as ADD_TO_CART } from 'vtex.checkout-resources/Mutations'
import { useProductDispatch } from 'vtex.product-context/ProductDispatchContext'
import { usePWA } from 'vtex.store-resources/PWAContext'

import { compareObjects } from './modules/compareObjects'
import { MapCatalogItemToCartReturn } from './modules/catalogItemToCart'
import { OrderFormArgs, OrderFormItemInput } from '../../typings'

interface Props {
  isOneClickBuy: boolean
  available: boolean
  disabled: boolean
  customToastUrl: string
  customOneClickBuyLink: string
  skuItems: MapCatalogItemToCartReturn[]
  showToast: Function
  allSkuVariationsSelected: boolean
}

interface OrderFormContext {
  loading: boolean
  orderForm: OrderFormArgs | undefined
  setOrderForm: (orderForm: Partial<OrderFormArgs>) => void
}

const CSS_HANDLES = ['buttonText', 'buttonDataContainer']
const CHECKOUT_URL = '/checkout/#/cart'

const messages = defineMessages({
  success: { id: 'store/add-to-cart.success', defaultMessage: '' },
  duplicate: { id: 'store/add-to-cart.duplicate', defaultMessage: '' },
  error: { id: 'store/add-to-cart.failure', defaultMessage: '' },
  seeCart: { id: 'store/add-to-cart.see-cart', defaultMessage: '' },
})

const adjustItemsForMutationInput = (
  newItems: MapCatalogItemToCartReturn[]
): OrderFormItemInput[] => {
  return newItems.map(item => ({
    id: Number.parseInt(item.skuId),
    index: item.index,
    seller: item.seller,
    quantity: item.quantity,
    options: item.options,
  }))
}

const adjustSkuItemForPixelEvent = (skuItem: MapCatalogItemToCartReturn) => {
  // Changes this `/Apparel & Accessories/Clothing/Tops/`
  // to this `Apparel & Accessories/Clothing/Tops`
  const category = skuItem.category ? skuItem.category.slice(1, -1) : ''

  return {
    skuId: skuItem.skuId,
    variant: skuItem.variant,
    price: skuItem.price,
    name: skuItem.name,
    quantity: skuItem.quantity,
    productRefId: skuItem.productRefId,
    brand: skuItem.brand,
    category,
  }
}

const AddToCartButton: FC<Props & InjectedIntlProps> = ({
  intl,
  isOneClickBuy,
  customOneClickBuyLink,
  available,
  disabled,
  skuItems,
  customToastUrl,
  showToast,
  allSkuVariationsSelected = true,
}) => {
  const handles = useCssHandles(CSS_HANDLES)
  const {
    orderForm,
    setOrderForm,
    loading,
  }: OrderFormContext = OrderForm.useOrderForm()
  const dispatch = useProductDispatch()
  const { rootPath } = useRuntime()
  const { push } = usePixel()
  const { settings = {}, showInstallPrompt = undefined } = usePWA() || {}
  const { promptOnCustomEvent } = settings
  const translateMessage = (message: FormattedMessage.MessageDescriptor) =>
    intl.formatMessage(message)

  const resolveToastMessage = (success: boolean, isNewItem: boolean) => {
    if (!success) return translateMessage(messages.error)
    if (!isNewItem) return translateMessage(messages.duplicate)

    return translateMessage(messages.success)
  }

  const toastMessage = ({
    success,
    isNewItem,
  }: {
    success: boolean
    isNewItem: boolean
  }) => {
    const message = resolveToastMessage(success, isNewItem)

    const action = success
      ? {
          label: translateMessage(messages.seeCart),
          href: customToastUrl,
        }
      : undefined

    showToast({ message, action })
  }

  const [
    addToCart,
    { error: mutationError, loading: mutationLoading },
  ] = useMutation<
    { addToCart: OrderFormArgs },
    { items: OrderFormItemInput[] }
  >(ADD_TO_CART)

  const handleAddToCart = async (event: React.MouseEvent) => {
    event.stopPropagation()
    event.preventDefault()

    const adjustedSkuItems = adjustItemsForMutationInput(skuItems)

    const mutationResult = await addToCart({
      variables: { items: adjustedSkuItems },
    })

    if (mutationError) {
      console.error(mutationError)
      toastMessage({ success: false, isNewItem: false })
      return
    }

    if (
      mutationResult.data &&
      compareObjects(mutationResult.data.addToCart, orderForm)
    ) {
      toastMessage({ success: true, isNewItem: false })
      return
    }

    // Update OrderForm from the context
    mutationResult.data && setOrderForm(mutationResult.data.addToCart)

    // Send event to pixel-manager
    const pixelEventItems = skuItems.map(adjustSkuItemForPixelEvent)
    push({
      event: 'addToCart',
      items: pixelEventItems,
    })

    if (isOneClickBuy) {
      location.assign(rootPath + (customOneClickBuyLink || CHECKOUT_URL))
    }

    toastMessage({ success: true, isNewItem: true })

    /* PWA */
    if (promptOnCustomEvent === 'addToCart' && showInstallPrompt) {
      showInstallPrompt()
    }
  }

  const handleClick = (e: React.MouseEvent) => {
    if (dispatch) {
      dispatch({ type: 'SET_BUY_BUTTON_CLICKED', args: { clicked: true } })
    }

    if (allSkuVariationsSelected) {
      handleAddToCart(e)
    }
  }

  const availableButtonContent = (
    <div className={`${handles.buttonDataContainer} flex justify-center`}>
      <FormattedMessage id="store/add-to-cart.add-to-cart">
        {message => <span className={handles.buttonText}>{message}</span>}
      </FormattedMessage>
    </div>
  )

  const unavailableButtonContent = (
    <FormattedMessage id="store/buyButton-label-unavailable">
      {message => <span className={handles.buttonText}>{message}</span>}
    </FormattedMessage>
  )

  const tooltipLabel = (
    <FormattedMessage id="store/add-to-cart.select-sku-variations">
      {message => <span className={handles.errorMessage}>{message}</span>}
    </FormattedMessage>
  )

  return allSkuVariationsSelected ? (
    <Button
      block
      disabled={disabled || !available || loading || mutationLoading}
      isLoading={mutationLoading}
      onClick={handleClick}>
      {available ? availableButtonContent : unavailableButtonContent}
    </Button>
  ) : (
    <Tooltip trigger="click" label={tooltipLabel}>
      <Button
        block
        disabled={disabled || !available || loading || mutationLoading}
        isLoading={mutationLoading}
        onClick={handleClick}>
        {available ? availableButtonContent : unavailableButtonContent}
      </Button>
    </Tooltip>
  )
}

export default injectIntl(AddToCartButton)

```


[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 sku-list/react/components/BuyButton/Wrapper.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FC } from 'react'
import useProduct from 'vtex.product-context/useProduct'
import { withToast } from 'vtex.styleguide'

import AddToCartButton from './AddToCartButton'
import { mapCatalogItemToCart } from './modules/catalogItemToCart'
import { Item, Maybe, ProductContextState } from '../../typings'

interface Props {
  isOneClickBuy: boolean
  available: boolean
  disabled: boolean
  customToastUrl: string
  customOneClickBuyLink: string
  showToast: Function
  selectedItem: Maybe<Item>
  selectedQuantity: number
}

const Wrapper: FC<Props> = ({
  isOneClickBuy,
  available,
  disabled,
  customToastUrl,
  showToast,
  customOneClickBuyLink,
  selectedItem,
  selectedQuantity,
}) => {
  const productContext: Maybe<ProductContextState> = useProduct()

  if (!productContext) {
    throw new Error('useProduct must be used within a ProductContextProvider')
  }

  const isEmptyContext = Object.keys(productContext).length === 0

  const product = productContext && productContext.product
  // const selectedItem = productContext && productContext.selectedItem
  const assemblyOptions = productContext && productContext.assemblyOptions
  const selectedSeller =
    productContext &&
    productContext.selectedItem &&
    productContext.selectedItem.sellers[0]
  const quantity = selectedQuantity != null ? selectedQuantity : 1

  const skuItems = mapCatalogItemToCart({
    product,
    selectedItem,
    quantity,
    selectedSeller,
    assemblyOptions,
  })

  const isAvailable =
    isEmptyContext || available != null
      ? available
      : Boolean(
          selectedSeller &&
            selectedSeller.commertialOffer &&
            selectedSeller.commertialOffer.AvailableQuantity > 0
        )

  const groupsValidArray =
    (assemblyOptions &&
      assemblyOptions.areGroupsValid &&
      Object.values(assemblyOptions.areGroupsValid)) ||
    []

  const areAssemblyGroupsValid = groupsValidArray.every(Boolean)
  const isDisabled =
    isEmptyContext || disabled != null ? disabled : !areAssemblyGroupsValid

  const areAllSkuVariationsSelected =
    productContext && productContext.skuSelector.areAllVariationsSelected

  return (
    <AddToCartButton
      allSkuVariationsSelected={areAllSkuVariationsSelected}
      skuItems={skuItems}
      available={isAvailable}
      isOneClickBuy={isOneClickBuy}
      disabled={isDisabled}
      customToastUrl={customToastUrl}
      showToast={showToast}
      customOneClickBuyLink={customOneClickBuyLink}
    />
  )
}

export default withToast(Wrapper)

```


[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 sku-list/react/components/SellerPrice/SellerPriceLegacy.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useCssHandles } from 'vtex.css-handles'
import { FormattedCurrency } from 'vtex.format-currency'
import { Installment } from '../../typings'

const CSS_HANDLES = ['priceContainer'] as const

interface Props {
  sellingPrice?: number
  listPrice?: number
  unitMultiplier?: number
  installments?: Installment[]
}

const SellerPriceLegacy = ({ sellingPrice }: Props) => {
  const handles = useCssHandles(CSS_HANDLES)

  return (
    <div className={handles.priceContainer}>
      <span>
        <FormattedCurrency value={sellingPrice} />
      </span>
    </div>
  )
}

export default SellerPriceLegacy

```


[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 sku-list/react/components/ItemQuantity/ItemQuantity.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { useSkuDispatch } from '../SkuContext'
import { useProductDispatch } from 'vtex.product-context/ProductDispatchContext'
import BaseProductQuantity from './components/BaseItemQuantity'
import { Item } from '../../typings'

const ItemQuantity: StorefrontFunctionComponent<Props> = ({
  selectedItem,
  warningQuantityThreshold,
  selectedQuantity,
  inputType,
  showLabel,
}) => {
  const skuDispatch = useSkuDispatch()
  const productDispatch = useProductDispatch()
  return (
    <BaseProductQuantity
      warningQuantityThreshold={warningQuantityThreshold}
      selectedItem={selectedItem}
      selectedQuantity={selectedQuantity}
      skuDispatch={skuDispatch}
      productDispatch={productDispatch}
      inputType={inputType}
      showLabel={showLabel}
    />
  )
}

interface Props {
  warningQuantityThreshold: number
  selectedItem: Item
  selectedQuantity: number
  inputType: 'stepper' | 'number'
  showLabel: boolean
}

ItemQuantity.schema = {
  title: 'admin/editor.sku-list.item-quantity.title',
  description: 'admin/editor.sku-list.item-quantity.description',
  type: 'object',
  properties: {
    inputType: {
      type: 'string',
      title: 'admin/editor.sku-list.item-quantity.inputType.title',
      enum: ['stepper', 'number'],
      enumNames: [
        'admin/editor.sku-list.item-quantity.inputType.stepper',
        'admin/editor.sku-list.item-quantity.inputType.number',
      ],
      widget: {
        'ui:options': {
          inline: false,
        },
        'ui:widget': 'radio',
      },
      default: 'stepper',
      isLayout: false,
    },
    showLabel: {
      type: 'boolean',
      title: 'admin/editor.sku-list.item-quantity.showLabel.title',
      default: true,
      isLayout: false,
    },
  },
}

export default ItemQuantity

```


[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 sku-list/react/components/BuyButton/modules/compareObjects.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
export function compareObjects(obj1: any, obj2: any) {
  //Loop through properties in object 1
  for (const p in obj1) {
    //Check property exists on both objects
    if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) return false

    switch (typeof obj1[p]) {
      //Deep compare objects
      case 'object':
        if (!compareObjects(obj1[p], obj2[p])) return false
        break
      //Compare function code
      case 'function':
        if (
          typeof obj2[p] == 'undefined' ||
          (p != 'compare' && obj1[p].toString() != obj2[p].toString())
        )
          return false
        break
      //Compare values
      default:
        if (obj1[p] != obj2[p]) return false
    }
  }

  //Check object 2 for any extra properties
  for (const p in obj2) {
    if (typeof obj1[p] == 'undefined') return false
  }
  return true
}

```


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

[User] Show me the implementation of sku-list/react/components/BuyButton/modules/catalogItemToCart.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

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

import {
  transformAssemblyOptions,
  sumAssembliesPrice,
  ParsedAssemblyOptionsMeta,
  Option,
} from './assemblyOptions'
import { AssemblyOptionItem, Item, Maybe, Product } from '../../../typings'

interface MapCatalogItemToCartArgs {
  product: Maybe<Product>
  selectedItem: Maybe<Item>
  quantity: number
  selectedSeller: any
  assemblyOptions?: {
    items: Record<string, AssemblyOptionItem[]>
    inputValues: Record<string, Record<string, string>>
    areGroupsValid: Record<string, boolean>
  }
}

export interface MapCatalogItemToCartReturn {
  index: 0
  quantity: number
  detailUrl: string
  name: string
  brand: string
  category: string
  productRefId: string
  seller: any
  price: number
  listPrice: number
  variant: string
  skuId: string
  imageUrl: string | undefined
  sellingPriceWithAssemblies: number
  options: Option[]
  assemblyOptions: ParsedAssemblyOptionsMeta
}

export function mapCatalogItemToCart({
  product,
  selectedItem,
  quantity,
  selectedSeller,
  assemblyOptions,
}: MapCatalogItemToCartArgs): MapCatalogItemToCartReturn[] {
  return (
    product &&
    selectedItem &&
    selectedSeller &&
    selectedSeller.commertialOffer && [
      {
        index: 0,
        quantity: quantity,
        detailUrl: `/${product.linkText}/p`,
        name: product.productName,
        brand: product.brand,
        category:
          product.categories && product.categories.length > 0
            ? product.categories[0]
            : '',
        productRefId: product.productReference,
        seller: selectedSeller.sellerId,
        price: selectedSeller.commertialOffer.Price,
        listPrice: selectedSeller.commertialOffer.ListPrice,
        variant: selectedItem.name,
        skuId: selectedItem.itemId,
        imageUrl: path(['images', '0', 'imageUrl'], selectedItem),
        ...transformAssemblyOptions(
          path(['items'], assemblyOptions),
          path(['inputValues'], assemblyOptions),
          selectedSeller.commertialOffer.Price,
          quantity
        ),
        sellingPriceWithAssemblies:
          selectedSeller.commertialOffer.Price +
          sumAssembliesPrice(path(['items'], assemblyOptions) || {}),
      },
    ]
  )
}

```


[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 sku-list/react/components/BuyButton/modules/assemblyOptions.ts from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { AssemblyOptionItem } from '../../../typings'

type GroupId = string
type GroupTypes = 'SINGLE' | 'TOGGLE' | 'MULTIPLE'

export function sumAssembliesPrice(
  assemblyOptions: Record<GroupId, AssemblyOptionItem[]>
) {
  const cleanAssemblies = assemblyOptions || {}
  const assembliesGroupItems = Object.values(cleanAssemblies)
  return assembliesGroupItems.reduce<number>(
    (sum: number, groupItems: AssemblyOptionItem[]) => {
      const groupPrice = groupItems.reduce<number>((groupSum, item) => {
        const childrenPrice: number = item.children
          ? sumAssembliesPrice(item.children)
          : 0
        const itemCost = item.price * item.quantity
        return groupSum + itemCost + childrenPrice * item.quantity
      }, 0)
      return groupPrice + sum
    },
    0
  )
}

type InputValue = Record<string, string | boolean>

export interface AssemblyOptions {
  items: Record<GroupId, AssemblyOptionItem[]>
  inputValues: Record<GroupId, InputValue>
  areGroupsValid: Record<string, boolean>
}

export type Option = ItemOption

export interface ItemOption {
  assemblyId: string
  id?: string
  quantity?: number
  seller?: string
  options?: Option[]
  inputValues?: InputValue
}

interface AddedItem {
  id: string
  name: string
  quantity: number
  sellingPrice: number
  sellingPriceWithAssemblies: number
  assemblyOptions?: ParsedAssemblyOptionsMeta
}

interface CartAddedOption {
  normalizedQuantity: number
  extraQuantity: number
  choiceType: GroupTypes
  item: AddedItem
}

interface CartRemovedOption {
  name: string
  initialQuantity: number
  removedQuantity: number
}

export interface ParsedAssemblyOptionsMeta {
  added: CartAddedOption[]
  removed: CartRemovedOption[]
  parentPrice: number
}

interface ParsedAssemblyOptions {
  options: Option[]
  assemblyOptions: ParsedAssemblyOptionsMeta
}

export function transformAssemblyOptions(
  assemblyOptionsItems: Record<GroupId, AssemblyOptionItem[]> = {},
  inputValues: Record<GroupId, InputValue> = {},
  parentPrice: number,
  parentQuantity: number
): ParsedAssemblyOptions {
  // contains options sent as arguments to graphql mutation
  const options: Option[] = []

  // array with added assemblies data to show in minicart optimistic preview
  const added: CartAddedOption[] = []

  // array with removed assemblies data to show in minicart optimistic preview
  const removed: CartRemovedOption[] = []

  const assemblyItemsKeys: GroupId[] = Object.keys(assemblyOptionsItems)

  for (const groupId of assemblyItemsKeys) {
    const items = assemblyOptionsItems[groupId]
    for (const item of items) {
      const childrenAddedData = item.children
        ? transformAssemblyOptions(
            item.children,
            {},
            item.price,
            item.quantity * parentQuantity
          )
        : null

      const {
        options: childrenOptions,
        assemblyOptions: childrenAssemblyOptions,
      } = childrenAddedData || {
        options: undefined,
        assemblyOptions: undefined,
      }

      const { quantity, initialQuantity } = item

      if (quantity >= initialQuantity && quantity > 0) {
        added.push({
          normalizedQuantity: quantity,
          extraQuantity: quantity - initialQuantity,
          choiceType: item.choiceType,
          item: {
            name: item.name,
            sellingPrice: item.price,
            quantity,
            sellingPriceWithAssemblies:
              item.price + sumAssembliesPrice(item.children || {}),
            id: item.id,
            ...(childrenAssemblyOptions
              ? { assemblyOptions: childrenAssemblyOptions }
              : {}),
          },
        })
      }

      if (quantity < initialQuantity && item.choiceType === 'TOGGLE') {
        removed.push({
          name: item.name,
          initialQuantity,
          removedQuantity: initialQuantity - quantity,
        })
      }

      const addedChildrenCount = childrenAddedData
        ? childrenAddedData.options.length
        : 0

      if (quantity !== initialQuantity || addedChildrenCount > 0) {
        options.push({
          assemblyId: groupId,
          id: item.id,
          quantity: quantity * parentQuantity,
          seller: item.seller,
          ...(childrenOptions && childrenOptions.length > 0
            ? { options: childrenOptions }
            : {}),
        })
      }
    }
  }

  const assemblyInputValuesKeys: GroupId[] = Object.keys(inputValues)

  for (const groupId of assemblyInputValuesKeys) {
    const inputValuesObject = inputValues[groupId] || {}
    if (Object.keys(inputValuesObject).length > 0) {
      options.push({
        assemblyId: groupId,
        inputValues: inputValues[groupId],
      })
    }
  }

  return {
    options,
    assemblyOptions: {
      added,
      removed,
      parentPrice,
    },
  }
}

```


[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 sku-list/react/components/ItemQuantity/components/BaseItemQuantity.tsx from the sku-list VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useCallback } from 'react'
import { Input, NumericStepper } from 'vtex.styleguide'
import { FormattedMessage } from 'react-intl'
import { pathOr } from 'ramda'
import { useCssHandles } from 'vtex.css-handles'
import { Item } from '../../../typings'

const CSS_HANDLES = [
  'quantitySelectorContainer',
  'quantitySelectorTitle',
  'quantitySelectorStepper',
  'availableQuantityContainer',
] as const

const BaseItemQuantity: StorefrontFunctionComponent<Props> = ({
  warningQuantityThreshold = 0,
  selectedQuantity,
  selectedItem,
  productDispatch,
  skuDispatch,
  inputType,
  showLabel,
}) => {
  const handles = useCssHandles(CSS_HANDLES)
  const onChange = useCallback(
    e => {
      const quantity = inputType == 'stepper' ? e.value : e.target.value
      productDispatch({ type: 'SET_QUANTITY', args: { quantity: quantity } })
      skuDispatch({ type: 'SET_QUANTITY', args: { quantity: quantity } })
    },
    [inputType, productDispatch, skuDispatch]
  )

  const availableQuantity = pathOr(
    0,
    ['sellers', 0, 'commertialOffer', 'AvailableQuantity'],
    selectedItem
  )

  const showAvailable = availableQuantity <= warningQuantityThreshold

  if (availableQuantity < 1) return null

  return (
    <div
      className={`${handles.quantitySelectorContainer} flex flex-column mb4`}>
      {showLabel && (
        <div
          className={`${handles.quantitySelectorTitle} mb3 t-body c-on-base fw7 pr3`}>
          <FormattedMessage id="store/product-quantity.quantity" />
        </div>
      )}
      <div className={handles.quantitySelectorStepper}>
        {inputType == 'number' ? (
          <Input
            type="number"
            value={selectedQuantity}
            min={1}
            max={availableQuantity ? availableQuantity : undefined}
            onChange={onChange}
          />
        ) : (
          <NumericStepper
            size="small"
            value={selectedQuantity}
            minValue={1}
            maxValue={availableQuantity ? availableQuantity : undefined}
            onChange={onChange}
          />
        )}
      </div>
      {showAvailable && (
        <div
          className={`${handles.availableQuantityContainer} mv4 c-muted-2 t-small`}>
          <FormattedMessage
            id="store/product-quantity.quantity-available"
            values={{ availableQuantity }}
          />
        </div>
      )}
    </div>
  )
}

interface Props {
  warningQuantityThreshold: number
  selectedQuantity: number
  selectedItem: Item
  skuDispatch: any
  productDispatch: any
  inputType: 'stepper' | 'number'
  showLabel?: boolean
}

BaseItemQuantity.defaultProps = {
  warningQuantityThreshold: 0,
  inputType: 'stepper',
  showLabel: true,
}

export default BaseItemQuantity

```


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

[Assistant]
Here's the implementation:

```json
{
  "admin/test": "teste",
  "store/test": "teste"
}
```


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

[Assistant]
Here's the implementation:

```json
{
  "admin/test": "test",
  "store/test": "test"
}

```


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

[Assistant]
Here's the implementation:

```json
{
  "admin/test": "teste",
  "store/test": "teste"
}
```


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

[Assistant]
Here's the implementation:

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

# APP NAME

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

Under the app's name, you should explain the topic, giving a **brief description** of its **functionality** in a store when installed.

Next, **add media** (either an image of a GIF) with the rendered components, so that users can better understand how the app works in practice.

![Media Placeholder](https://user-images.githubusercontent.com/52087100/71204177-42ca4f80-227e-11ea-89e6-e92e65370c69.png)

## Configuration

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

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

Remember to add a table with all blocks exported by the app and their descriptions. You can verify an example of it on the [Search Result documentation](https://vtex.io/docs/components/all/vtex.search-result@3.56.1/).

Next, add the **props table** containing your block's props.

If the app exports more than one block, create several tables - one for each block. For example:

### `block-1` props

| Prop name    | Type            | Description    | Default value                                                                                |
| ------------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `XXXXX`      | `XXXXXX`       | XXXXXXXX         | `XXXXXX`        |

### `block-2` props

| Prop name    | Type            | Description    | Default value                                                                                |
| ------------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `XXXXX`      | `XXXXXX`       | XXXXXXXX         | `XXXXXX`        |

Prop types are:

- `string`
- `enum`
- `number`
- `boolean`
- `object`
- `array`

When documenting a prop whose type is `object` or `array` another prop table will be needed. You can create it following the example below:

- `propName` object:

| Prop name    | Type            | Description    | Default value                                                                                |
| ------------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `XXXXX`      | `XXXXXX`       | XXXXXXXX         | `XXXXXX`        |

Remember to also use this Configuration section to  **showcase any necessary disclaimer** related to the app and its blocks, such as the different behavior it may display during its configuration.

## Modus Operandi *(not mandatory)*

There are scenarios in which an app can behave differently in a store, according to how it was added to the catalog, for example. It's crucial to go through these **behavioral changes** in this section, allowing users to fully understand the **practical application** of the app in their store.

If you feel compelled to give further details about the app, such as it's **relationship with the VTEX admin**, don't hesitate to use this section.

## Customization

The first thing that should be present in this section is the sentence below, showing users the recipe pertaining to CSS customization in apps:

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

Thereafter, you should add a single column table with the available CSS handles for the app, like the one below. Note that the Handles must be ordered alphabetically.

| CSS Handles |
| ----------- |
| `XXXXX` |
| `XXXXX` |
| `XXXXX` |
| `XXXXX` |
| `XXXXX` |

If there are none, add the following sentence instead:

`No CSS Handles are available yet for the app customization.`

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

## Contributors ✨

Thanks goes to these wonderful people:

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

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

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

----

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

```


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

[User] Show me the implementation of react-app-template/react/Greeting.test.tsx from the react-app-template VTEX app.

[Assistant]
Here's the implementation:

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

import Greeting from './Greeting'

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

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

```