[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 return-app/react/store/createReturnRequest/components/PaymentMethods.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import type { ChangeEvent } from 'react'
import { useIntl, defineMessages, FormattedMessage } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'
import type {
  RefundPaymentDataInput,
  PaymentType,
  RefundPaymentMethod,
} from 'vtex.return-app'
import { Input, RadioGroup } from 'vtex.styleguide'

import { useStoreSettings } from '../../hooks/useStoreSettings'
import { useReturnRequest } from '../../hooks/useReturnRequest'
import { CustomMessage } from './layout/CustomMessage'
import { defaultPaymentMethodsMessages } from '../../utils/defaultPaymentMethodsMessages'
import { isValidIBANNumber } from '../../utils/isValidIBANNumber'

interface Props {
  canRefundCard: boolean
}

type PaymentMethodsOptions = {
  value: keyof PaymentType
  label: string
}

const CSS_HANDLES = ['paymentMethodContainer', 'paymentBankWrapper'] as const

const messages = defineMessages({
  formIBAN: { id: 'store/return-app.return-order-details.payment-method.iban' },
  formAccountHolder: {
    id: 'store/return-app.return-order-details.payment-method.account-holder',
  },
})

export const PaymentMethods = ({ canRefundCard }: Props) => {
  const { formatMessage } = useIntl()
  const handles = useCssHandles(CSS_HANDLES)

  const { data } = useStoreSettings()
  const { paymentOptions } = data ?? {}
  const { allowedPaymentTypes, enablePaymentMethodSelection } =
    paymentOptions ?? {}

  const {
    returnRequest,
    inputErrors,
    actions: { updateReturnRequest },
  } = useReturnRequest()

  const { refundPaymentData } = returnRequest

  const handleRefundPaymentChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { value } = event.target

    const refundPaymentPayload = {
      ...refundPaymentData,
      refundPaymentMethod: value as RefundPaymentMethod,
    }

    updateReturnRequest({
      type: 'updateRefundPaymentData',
      payload: refundPaymentPayload,
    })
  }

  const handleBankDetailsChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { name, value } = event.target
    const refundPaymentPayload = {
      ...refundPaymentData,
      refundPaymentMethod: refundPaymentData?.refundPaymentMethod ?? 'bank',
      [name as keyof RefundPaymentDataInput]: value,
    }

    updateReturnRequest({
      type: 'updateRefundPaymentData',
      payload: refundPaymentPayload,
    })
  }

  const paymentMethods = () => {
    if (!allowedPaymentTypes) return []
    const { bank, card, giftCard } = allowedPaymentTypes
    const output: PaymentMethodsOptions[] = []

    if (card && canRefundCard) {
      output.push({
        value: 'card',
        label: formatMessage(defaultPaymentMethodsMessages.card),
      })
    }

    if (giftCard) {
      output.push({
        value: 'giftCard',
        label: formatMessage(defaultPaymentMethodsMessages.giftCard),
      })
    }

    if (bank) {
      output.push({
        value: 'bank',
        label: formatMessage(defaultPaymentMethodsMessages.bank),
      })
    }

    return output
  }

  const paymentMethodError = inputErrors.some(
    (error) => error === 'refund-payment-data'
  )

  const bankDetailsError = inputErrors.some((error) => error === 'bank-details')

  return (
    <div
      className={`${handles.paymentMethodContainer} flex-ns flex-wrap flex-auto flex-column pa4 mb6`}
    >
      <p>
        <FormattedMessage id="store/return-app.return-order-details.payment-method.description" />
      </p>
      {!enablePaymentMethodSelection ? (
        <p className="i-s">
          <FormattedMessage id="store/return-app.return-order-details.payment-method.default" />
        </p>
      ) : (
        <>
          <RadioGroup
            hideBorder
            name="refundPaymentMethod"
            options={paymentMethods()}
            value={refundPaymentData?.refundPaymentMethod ?? ''}
            onChange={handleRefundPaymentChange}
          />
          {paymentMethodError && !refundPaymentData?.refundPaymentMethod ? (
            <CustomMessage
              status="error"
              message={
                <FormattedMessage id="store/return-app.return-payment-methods.input-payment-method.error" />
              }
            />
          ) : null}
        </>
      )}
      {refundPaymentData?.refundPaymentMethod === 'bank' ? (
        <div className={`${handles.paymentMethodContainer}`}>
          <div className="flex-ns flex-wrap flex-auto flex-column mt6 mw6">
            <Input
              name="accountHolderName"
              placeholder={formatMessage(messages.formAccountHolder)}
              onChange={handleBankDetailsChange}
              value={refundPaymentData.accountHolderName ?? ''}
            />
            {bankDetailsError && !refundPaymentData.accountHolderName ? (
              <CustomMessage
                status="error"
                message={
                  <FormattedMessage id="store/return-app.return-payment-methods.input-account-holder.error" />
                }
              />
            ) : null}
          </div>
          <div className="flex-ns flex-wrap flex-auto flex-column mt4 mw6">
            <Input
              name="iban"
              placeholder={formatMessage(messages.formIBAN)}
              onChange={handleBankDetailsChange}
              value={refundPaymentData.iban ?? ''}
            />
            {bankDetailsError && !refundPaymentData.iban ? (
              <CustomMessage
                status="error"
                message={
                  <FormattedMessage id="store/return-app.return-payment-methods.input-iban.error" />
                }
              />
            ) : null}
            {bankDetailsError &&
            refundPaymentData.iban &&
            !isValidIBANNumber(refundPaymentData.iban) ? (
              <CustomMessage
                status="error"
                message={
                  <FormattedMessage id="store/return-app.return-payment-methods.input-iban-invalid.error" />
                }
              />
            ) : null}
          </div>
        </div>
      ) : null}
    </div>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/RenderConditionDropdown.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { ChangeEvent } from 'react'
import React from 'react'
import { useIntl } from 'react-intl'
import type { ItemCondition } from 'vtex.return-app'
import { Dropdown } from 'vtex.styleguide'
import { useCssHandles } from 'vtex.css-handles'

import { defaultReturnConditionsMessages } from '../../../common/utils/defaultReturnConditionsMessages'

const CSS_HANDLES = ['conditionDropdwonContainer'] as const

interface Props {
  condition: string
  onConditionChange: (condition: ItemCondition) => void
  isExcluded: boolean
}

export const RenderConditionDropdown = ({
  condition,
  onConditionChange,
  isExcluded,
}: Props) => {
  const { formatMessage } = useIntl()
  const handles = useCssHandles(CSS_HANDLES)

  const handleConditionChange = (e: ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target

    onConditionChange(value as ItemCondition)
  }

  const conditionOptions = [
    {
      value: 'newWithBox',
      label: formatMessage(defaultReturnConditionsMessages.newWithBox),
    },
    {
      value: 'newWithoutBox',
      label: formatMessage(defaultReturnConditionsMessages.newWithoutBox),
    },
    {
      value: 'usedWithBox',
      label: formatMessage(defaultReturnConditionsMessages.usedWithBox),
    },
    {
      value: 'usedWithoutBox',
      label: formatMessage(defaultReturnConditionsMessages.usedWithoutBox),
    },
  ]

  return (
    <div className={handles.conditionDropdwonContainer}>
      <Dropdown
        disabled={isExcluded}
        label=""
        placeholder={formatMessage(
          defaultReturnConditionsMessages.selectCondition
        )}
        size="small"
        options={conditionOptions}
        value={condition}
        onChange={handleConditionChange}
      />
    </div>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/AddressDetails.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState } from 'react'
import type { ChangeEvent } from 'react'
import { useIntl, defineMessages, FormattedMessage } from 'react-intl'
import { Input, Tooltip, Toggle, IconInfo } from 'vtex.styleguide'
import type { AddressType, ShippingData } from 'vtex.return-app'
import { useCssHandles } from 'vtex.css-handles'

import { useReturnRequest } from '../../hooks/useReturnRequest'
import { useStoreSettings } from '../../hooks/useStoreSettings'
import { CustomMessage } from './layout/CustomMessage'
import { PickupPointSelector } from './PickupPointSelector'
import type { OrderDetailsState } from '../../provider/OrderToReturnReducer'
import { setInitialPickupAddress } from '../../utils/setInitialPickupAddress'

const messages = defineMessages({
  addressInput: {
    id: 'store/return-app.return-order-details.inputs.address-input',
  },
  cityInput: {
    id: 'store/return-app.return-order-details.inputs.city-input',
  },
  stateInput: {
    id: 'store/return-app.return-order-details.inputs.state-input',
  },
  zipInput: {
    id: 'store/return-app.return-order-details.inputs.zip-input',
  },
  countryInput: {
    id: 'store/return-app.return-order-details.inputs.country-input',
  },
})

interface Props {
  shippingData: ShippingData
}

const CSS_HANDLES = [
  'addressContainer',
  'addressHeaderWrapper',
  'pickupAddressTitle',
  'tooltipToggleWrapper',
  'addressInputContainer',
  'cityInputContainer',
  'stateInputContainer',
  'zipCodeInputContainer',
  'countryInputContainer',
] as const

export const AddressDetails = ({ shippingData }: Props) => {
  const { formatMessage } = useIntl()
  const { data: settings } = useStoreSettings()
  const handles = useCssHandles(CSS_HANDLES)

  const { geoCoordinates } = shippingData ?? {}

  const [customerAddress, setCustomerAddress] = useState<
    OrderDetailsState['pickupReturnData'] | null
  >(null)

  const {
    returnRequest,
    inputErrors,
    actions: { updateReturnRequest },
  } = useReturnRequest()

  const { pickupReturnData } = returnRequest

  const [pickupPointType, setPickupPointType] = useState<AddressType>(
    pickupReturnData.addressType ?? 'CUSTOMER_ADDRESS'
  )

  const handleSelectedToggleAddress = () => {
    const addressType =
      pickupPointType === 'CUSTOMER_ADDRESS'
        ? 'PICKUP_POINT'
        : 'CUSTOMER_ADDRESS'

    // When user toggles to select a pickup point, we save the current CUSTOMER_ADDRESS into state in case they come back.
    if (addressType === 'PICKUP_POINT') {
      setCustomerAddress(pickupReturnData)

      updateReturnRequest({
        type: 'resetAddress',
      })
    }

    // When toggling back to CUSTOMER_ADDRESS, we restore the previous entered address.
    if (addressType === 'CUSTOMER_ADDRESS') {
      updateReturnRequest({
        type: 'updatePickupReturnData',
        payload: customerAddress ?? setInitialPickupAddress(shippingData),
      })
    }

    setPickupPointType(addressType)
  }

  const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { name, value } = event.target

    updateReturnRequest({
      type: 'updatePickupReturnData',
      payload: {
        ...pickupReturnData,
        addressType: pickupPointType,
        [name]: value,
      },
    })
  }

  const addressError = inputErrors.some((error) => error === 'pickup-data')
  const isPickupPoint = pickupPointType === 'PICKUP_POINT'

  /**
   * Important note: If the address from order has type PICKUP_POINT, the fields will be empty in the initial render.
   * More explanation on setInitialPickupAddress util function
   */
  return (
    <div
      className={`${handles.addressContainer} flex-ns flex-wrap flex-auto flex-column pa4 mw6`}
    >
      <div
        className={`${handles.addressHeaderWrapper} flex items-center justify-between`}
      >
        <div>
          <Tooltip
            label={
              <FormattedMessage id="store/return-app.return-order-details.title.tooltip.pickup-address" />
            }
          >
            <p className={handles.pickupAddressTitle}>
              <FormattedMessage id="store/return-app.return-order-details.title.pickup-address" />
            </p>
          </Tooltip>
        </div>
        {!settings?.options?.enablePickupPoints || !geoCoordinates ? null : (
          <div className={`${handles.tooltipToggleWrapper} flex items-center`}>
            <Tooltip
              label={
                <FormattedMessage id="store/return-app.return-order-details.pickup-address.drop-off-points.tooltip" />
              }
              position="left"
            >
              <div className="flex items-center">
                <span className="yellow">
                  <IconInfo className=" ml5 o-50" />
                </span>
                <p className="ml2 mr3">
                  <FormattedMessage id="store/return-app.return-order-details.pickup-address.drop-off-points" />
                </p>
              </div>
            </Tooltip>
            <Toggle
              checked={isPickupPoint}
              onChange={handleSelectedToggleAddress}
            />
          </div>
        )}
      </div>
      {isPickupPoint && geoCoordinates ? (
        <PickupPointSelector geoCoordinates={geoCoordinates} />
      ) : null}

      <div className={`${handles.addressInputContainer} mb4`}>
        <Input
          name="address"
          required
          placeholder={formatMessage(messages.addressInput)}
          onChange={handleInputChange}
          value={pickupReturnData.address}
          readOnly={isPickupPoint}
        />
        {addressError && !pickupReturnData.address ? (
          <CustomMessage
            status="error"
            message={
              <FormattedMessage id="store/return-app.return-address-details.address-input.error" />
            }
          />
        ) : null}
      </div>
      <div className={`${handles.cityInputContainer} mb4`}>
        <Input
          name="city"
          required
          placeholder={formatMessage(messages.cityInput)}
          onChange={handleInputChange}
          value={pickupReturnData.city}
          readOnly={isPickupPoint}
        />
        {addressError && !pickupReturnData.city ? (
          <CustomMessage
            status="error"
            message={
              <FormattedMessage id="store/return-app.return-address-details.city-input.error" />
            }
          />
        ) : null}
      </div>
      <div className={`${handles.stateInputContainer} mb4`}>
        <Input
          name="state"
          requiered
          placeholder={formatMessage(messages.stateInput)}
          onChange={handleInputChange}
          value={pickupReturnData.state}
          readOnly={isPickupPoint}
        />
        {addressError && !pickupReturnData.state ? (
          <CustomMessage
            status="error"
            message={
              <FormattedMessage id="store/return-app.return-address-details.state-input.error" />
            }
          />
        ) : null}
      </div>
      <div className={`${handles.zipCodeInputContainer} mb4`}>
        <Input
          name="zipCode"
          required
          placeholder={formatMessage(messages.zipInput)}
          onChange={handleInputChange}
          value={pickupReturnData.zipCode}
          readOnly={isPickupPoint}
        />
        {addressError && !pickupReturnData.zipCode ? (
          <CustomMessage
            status="error"
            message={
              <FormattedMessage id="store/return-app.return-address-details.zip-input.error" />
            }
          />
        ) : null}
      </div>
      <div className={`${handles.countryInputContainer} mb4`}>
        <Input
          name="country"
          required
          placeholder={formatMessage(messages.countryInput)}
          onChange={handleInputChange}
          value={pickupReturnData.country}
          readOnly={isPickupPoint}
        />
        {addressError && !pickupReturnData.country ? (
          <CustomMessage
            status="error"
            message={
              <FormattedMessage id="store/return-app.return-address-details.country-input.error" />
            }
          />
        ) : null}
      </div>
    </div>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/ItemsList.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import type { IntlFormatters } from 'react-intl'
import { FormattedMessage, defineMessages, useIntl } from 'react-intl'
import { useCssHandles } from 'vtex.css-handles'
import { useRuntime } from 'vtex.render-runtime'

import { useReturnRequest } from '../../hooks/useReturnRequest'
import { useStoreSettings } from '../../hooks/useStoreSettings'
import { ItemsDetails } from './ItemsDetails'
import { CustomMessage } from './layout/CustomMessage'

interface Props {
  items: ItemToReturn[]
  creationDate?: string
}

const CSS_HANDLES = [
  'itemsListContainer',
  'itemsListTheadWrapper',
  'cardItemsWrapper',
] as const

const desktopOrder = [
  'product',
  'quantity',
  'available-to-return',
  'quantity-to-return',
  'reason',
  'condition',
]

export const messages = defineMessages({
  product: {
    id: 'store/return-app.return-order-details.table-header.product',
  },
  quantity: {
    id: 'store/return-app.return-order-details.table-header.quantity',
  },
  'available-to-return': {
    id: 'store/return-app.return-order-details.table-header.available-to-return',
  },
  'quantity-to-return': {
    id: 'store/return-app.return-order-details.table-header.quantity-to-return',
  },
  reason: {
    id: 'store/return-app.return-order-details.table-header.reason',
  },
  condition: {
    id: 'store/return-app.return-order-details.table-header.condition',
  },
})

const TableHeaderRenderer = (
  formatMessage: IntlFormatters['formatMessage'],
  addCondition: boolean
) => {
  return function Header(value: string) {
    if (!addCondition && value === 'condition') {
      return
    }

    return (
      <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s">
        {formatMessage(messages[value])}
      </th>
    )
  }
}

export const ItemsList = (props: Props) => {
  const { items, creationDate } = props

  const { data: storeSettings } = useStoreSettings()
  const { options } = storeSettings ?? {}
  const { enableSelectItemCondition } = options ?? {}

  const {
    hints: { phone },
  } = useRuntime()

  const { formatMessage } = useIntl()

  const handles = useCssHandles(CSS_HANDLES)
  const { inputErrors } = useReturnRequest()

  const noItemSelected = inputErrors.some(
    (error) => error === 'no-item-selected'
  )

  const TableHeader = TableHeaderRenderer(
    formatMessage,
    Boolean(enableSelectItemCondition)
  )

  if (phone) {
    return (
      <div
        className={`${handles.cardItemsWrapper} flex flex-column flex-wrap flex-auto`}
      >
        {items.map((item) => (
          <ItemsDetails
            key={item.id}
            itemToReturn={item}
            creationDate={creationDate}
          />
        ))}
      </div>
    )
  }

  return (
    <table
      className={`${handles.itemsListContainer} w-100`}
      style={{ borderCollapse: 'collapse' }}
    >
      <thead
        className={`${handles.itemsListContainer} w-100 ph4 truncate overflow-x-hidden c-muted-2 f6`}
      >
        <tr className="w-100 truncate overflow-x-hidden">
          {desktopOrder.map((header) => TableHeader(header))}
        </tr>
      </thead>
      <tbody className="v-mid return-itemsList-body">
        {items.map((item) => (
          <ItemsDetails
            key={item.id}
            itemToReturn={item}
            creationDate={creationDate}
          />
        ))}
      </tbody>
      {noItemSelected ? (
        <CustomMessage
          status="error"
          message={
            <FormattedMessage id="store/return-app.return-items-list.no-items-selected.error" />
          }
        />
      ) : null}
    </table>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/ConfirmPickupAddressDetails.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { FormattedMessage } from 'react-intl'
import type { PickupReturnDataInput } from 'vtex.return-app'
import { useCssHandles } from 'vtex.css-handles'
import { useRuntime } from 'vtex.render-runtime'

interface Props {
  pickupReturnData: PickupReturnDataInput
}

const CSS_HANDLES = [
  'confirmPickupContainer',
  'confirmPickupTitle',
  'confirmPickupText',
] as const

export const ConfirmPickupAddressDetails = ({ pickupReturnData }: Props) => {
  const handles = useCssHandles(CSS_HANDLES)
  const {
    hints: { phone },
  } = useRuntime()

  return (
    <div
      className={`${handles.confirmPickupContainer} ${
        phone ? 'w-100' : 'w-40'
      }`}
    >
      <h2 className={`${handles.confirmPickupTitle} mt0 mb6`}>
        <FormattedMessage id="store/return-app.confirm-and-submit.pickup-address.title" />
      </h2>
      <p className={`${handles.confirmPickupText}  f6 gray`}>
        {pickupReturnData.address}
      </p>
      <p className={`${handles.confirmPickupText}  f6 gray`}>
        {pickupReturnData.city}
      </p>
      <p className={`${handles.confirmPickupText}  f6 gray`}>
        {pickupReturnData.state}
      </p>
      <p className={`${handles.confirmPickupText} f6 gray`}>
        {pickupReturnData.zipCode}
      </p>
      <p className={`${handles.confirmPickupText}  f6 gray`}>
        {pickupReturnData.country}
      </p>
    </div>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/TermsAndConditions.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

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

import { useStoreSettings } from '../../hooks/useStoreSettings'
import { useReturnRequest } from '../../hooks/useReturnRequest'
import { CustomMessage } from './layout/CustomMessage'

const CSS_HANDLES = [
  'termsAndConditionsContainer',
  'termsAndConditionsLink',
] as const

export const TermsAndConditions = () => {
  const {
    termsAndConditions,
    inputErrors,
    actions: { toogleTermsAndConditions },
  } = useReturnRequest()

  const { data } = useStoreSettings()
  const handles = useCssHandles(CSS_HANDLES)

  const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { checked } = event.target

    toogleTermsAndConditions(checked)
  }

  const hasntAcceptedTermsAndConditions = inputErrors.some(
    (error) => error === 'terms-and-conditions'
  )

  return (
    <div
      className={`${handles.termsAndConditionsContainer} flex-ns flex-wrap flex-auto flex-column pa4`}
    >
      <Checkbox
        checked={termsAndConditions}
        required
        id="agree"
        key="formAgreeCheckbox"
        label={
          <FormattedMessage
            id="store/return-app.return-order-details.terms-and-conditions.form-agree"
            values={{
              link: (
                <span>
                  <a
                    className={handles.termsAndConditionsContainer}
                    rel="noopener noreferrer"
                    target="_blank"
                    href={data?.termsUrl}
                  >
                    <FormattedMessage id="store/return-app.return-order-details.terms-and-conditions.link" />
                  </a>
                </span>
              ),
            }}
          />
        }
        name="agree"
        onChange={handleInputChange}
        value={termsAndConditions}
      />
      {hasntAcceptedTermsAndConditions ? (
        <CustomMessage
          status="error"
          message={
            <FormattedMessage id="store/return-app.return-terms-and-conditions.checkbox.error" />
          }
        />
      ) : null}
    </div>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/ConfirmAndSubmit.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { useState, useMemo } from 'react'
import { useMutation } from 'react-apollo'
import { FormattedMessage } from 'react-intl'
import { useRuntime } from 'vtex.render-runtime'
import type {
  MutationCreateReturnRequestArgs,
  ReturnRequestCreated,
} from 'vtex.return-app'
import { useCssHandles } from 'vtex.css-handles'
import { Card, Button, Alert } from 'vtex.styleguide'

import type { Page } from '../CreateReturnRequest'
import { useReturnRequest } from '../../hooks/useReturnRequest'
import CREATE_RETURN_REQUEST from '../graphql/createReturnRequest.gql'
import { ReturnInformationTable } from './ReturnInformationTable'
import { ConfirmContactDetails } from './ConfirmContactDetails'
import { ConfirmPickupAddressDetails } from './ConfirmPickupAddressDetails'
import { ConfirmPaymentMethods } from './ConfirmPaymentMethods'
import { ConfirmComment } from './ConfirmComment'
import { validateNewReturnRequestFields } from '../../utils/validateNewReturnRequestFields'
import { useStoreSettings } from '../../hooks/useStoreSettings'

interface Props {
  onPageChange: (page: Page) => void
  items: ItemToReturn[]
}

type SubmissionStatus = 'success' | 'error' | 'idle'

const CSS_HANDLES = [
  'submitDetailsContainer',
  'contactAddressWrapper',
  'paymentCommentWrapper',
  'confirmationActionsContainer',
  'backButtonWrapper',
  'submitButtonWrapper',
] as const

export const ConfirmAndSubmit = ({ onPageChange, items }: Props) => {
  const { returnRequest, termsAndConditions } = useReturnRequest()

  const [createReturnRequest, { loading: creatingReturnRequest }] = useMutation<
    { createReturnRequest: ReturnRequestCreated },
    MutationCreateReturnRequestArgs
  >(CREATE_RETURN_REQUEST)

  const {
    navigate,
    culture: { locale },
    hints: { phone },
  } = useRuntime()

  const { data: storeSettings } = useStoreSettings()
  const { options } = storeSettings ?? {}
  const { enableSelectItemCondition } = options ?? {}

  const [confirmationStatus, setConfirmationStatus] =
    useState<SubmissionStatus>('idle')

  const handles = useCssHandles(CSS_HANDLES)

  const returnRequestValidated = useMemo(() => {
    const { validatedFields } = validateNewReturnRequestFields(returnRequest, {
      termsAndConditionsAccepted: termsAndConditions,
      locale,
      considerItemCondition: Boolean(enableSelectItemCondition),
    })

    return validatedFields
  }, [termsAndConditions, returnRequest, locale, enableSelectItemCondition])

  const handleCreateReturnRequest = async () => {
    if (creatingReturnRequest || !returnRequestValidated) return

    try {
      const { errors } = await createReturnRequest({
        variables: {
          returnRequest: { ...returnRequestValidated },
        },
      })

      if (errors) {
        // TODO: handle validation errors coming from the server
        throw new Error('Error creating return request')
      }

      setConfirmationStatus('success')
    } catch (error) {
      console.error({ error })
      setConfirmationStatus('error')
    }
  }

  const handleAlertRedirect = () => {
    setConfirmationStatus('idle')
    navigate({
      to: `#/my-returns`,
      replace: true,
    })
  }

  const handlePageChange = () => {
    setConfirmationStatus('idle')
    onPageChange('form-details')
  }

  return (
    <>
      {!returnRequestValidated ? null : (
        <>
          <ReturnInformationTable
            items={items}
            selectedItems={returnRequestValidated.items}
          />
          <div className="mv8">
            <Card>
              <div
                className={`${handles.confirmationActionsContainer} flex flex-wrap`}
              >
                <section
                  className={`${
                    handles.contactAddressWrapper
                  } w-100 flex flex-wrap justify-between ${
                    phone ? 'flex-column' : ''
                  }`}
                >
                  <ConfirmContactDetails
                    contactDetails={returnRequestValidated.customerProfileData}
                  />
                  <ConfirmPickupAddressDetails
                    pickupReturnData={returnRequestValidated.pickupReturnData}
                  />
                </section>
                <section
                  className={`${
                    handles.paymentCommentWrapper
                  } w-100 flex mt5 justify-between ${
                    phone ? 'flex-column' : ''
                  }`}
                >
                  <ConfirmPaymentMethods
                    refundPaymentData={returnRequestValidated.refundPaymentData}
                  />
                  <ConfirmComment
                    userComment={returnRequestValidated.userComment}
                  />
                </section>
              </div>
            </Card>
          </div>
          <section
            className={`${handles.confirmationActionsContainer} flex justify-center`}
          >
            {confirmationStatus !== 'success' ? null : (
              <Alert
                type={confirmationStatus}
                action={{
                  label: (
                    <FormattedMessage id="store/return-app.confirm-and-submit.alert.label" />
                  ),
                  onClick: () => handleAlertRedirect(),
                }}
              >
                <FormattedMessage id="store/return-app.confirm-and-submit.alert.success" />
              </Alert>
            )}
            {confirmationStatus !== 'error' ? null : (
              <Alert
                type={confirmationStatus}
                action={{
                  label: (
                    <FormattedMessage id="store/return-app.confirm-and-submit.alert.error.label" />
                  ),
                  onClick: () => handleCreateReturnRequest(),
                }}
              >
                <FormattedMessage id="store/return-app.confirm-and-submit.alert.error" />
              </Alert>
            )}
            {confirmationStatus !== 'idle' ? null : (
              <div
                className={`flex ${
                  phone ? 'w-100 flex-column' : 'justify-center'
                }`}
              >
                <div
                  className={`${handles.backButtonWrapper} ${
                    phone ? 'mb5' : 'mr3'
                  }`}
                >
                  <Button
                    block={phone}
                    size={phone ? 'normal' : 'small'}
                    variation="secondary"
                    onClick={() => handlePageChange()}
                  >
                    <FormattedMessage id="store/return-app.confirm-and-submit.button.back" />
                  </Button>
                </div>
                <div
                  className={`${handles.submitButtonWrapper} ${
                    phone ? '' : 'mr3'
                  }`}
                >
                  <Button
                    block={phone}
                    size={phone ? 'normal' : 'small'}
                    onClick={handleCreateReturnRequest}
                    isLoading={creatingReturnRequest}
                  >
                    <FormattedMessage id="store/return-app.confirm-and-submit.button.submit" />
                  </Button>
                </div>
              </div>
            )}
          </section>
        </>
      )}
    </>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/RenderReasonDropdown.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { ChangeEvent } from 'react'
import React from 'react'
import { useIntl } from 'react-intl'
import { useRuntime } from 'vtex.render-runtime'
import { Dropdown, Textarea } from 'vtex.styleguide'
import { useCssHandles } from 'vtex.css-handles'

import { getReasonOptions } from '../../../common/constants/returnsRequest'
import { useStoreSettings } from '../../hooks/useStoreSettings'
import { defaultReturnReasonsMessages } from '../../utils/defaultReturnReasonsMessages'
import { generateCustomReasonOptions } from '../../utils/generateCustomReasonOptions'

const CSS_HANDLES = ['otherReasonOptionContainer'] as const

interface Props {
  reason: string
  otherReason: string
  onReasonChange: (reason: string, otherReason?: string) => void
  isExcluded: boolean
  creationDate?: string
}

export const RenderReasonDropdown = (props: Props) => {
  const { reason, otherReason, onReasonChange, isExcluded, creationDate } =
    props

  const { formatMessage } = useIntl()
  const handles = useCssHandles(CSS_HANDLES)

  const { data: settings } = useStoreSettings()
  const {
    culture: { locale },
  } = useRuntime()

  const customReturnReasons = settings?.customReturnReasons

  const handleReasonChange = (e: ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target

    onReasonChange(value)
  }

  const handleOtherReasonChange = (e: ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target

    onReasonChange('otherReason', value)
  }

  let reasonOptions: Array<{ value: string; label: string }>

  if (customReturnReasons && customReturnReasons.length > 0 && creationDate) {
    reasonOptions = generateCustomReasonOptions(
      customReturnReasons,
      locale,
      creationDate
    )
  } else {
    reasonOptions = getReasonOptions(formatMessage)
  }

  if (settings?.options?.enableOtherOptionSelection) {
    reasonOptions.push({
      value: 'otherReason',
      label: formatMessage(defaultReturnReasonsMessages.reasonOtherReason),
    })
  }

  return (
    <>
      <Dropdown
        disabled={isExcluded}
        placeholder={formatMessage(
          defaultReturnReasonsMessages.reasonSelectReason
        )}
        size="small"
        options={reasonOptions}
        value={reason}
        onChange={handleReasonChange}
      />
      {reason === 'otherReason' ? (
        <div className={`${handles.otherReasonOptionContainer} mv3`}>
          <Textarea
            resize="none"
            value={otherReason}
            onChange={handleOtherReasonChange}
          />
        </div>
      ) : 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 return-app/react/store/createReturnRequest/components/ReturnDetails.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { FormattedDate, FormattedMessage } from 'react-intl'
import type { RouteComponentProps } from 'react-router'
import type { ShippingData } from 'vtex.return-app'
import { useCssHandles } from 'vtex.css-handles'
import { Divider, Button } from 'vtex.styleguide'
import { useRuntime } from 'vtex.render-runtime'

import { ContactDetails } from './ContactDetails'
import { AddressDetails } from './AddressDetails'
import { UserCommentDetails } from './UserCommentDetails'
import { useReturnRequest } from '../../hooks/useReturnRequest'
import { ItemsList } from './ItemsList'
import { PaymentMethods } from './PaymentMethods'
import { TermsAndConditions } from './TermsAndConditions'
import type { Page } from '../CreateReturnRequest'

const CSS_HANDLES = [
  'returnDetailsContainer',
  'orderIdDetailsWrapper',
  'creationDateDetailsWrapper',
  'highlightedFormMessage',
] as const

interface Props {
  onPageChange: (page: Page) => void
  items: ItemToReturn[]
  creationDate: string
  canRefundCard: boolean
  shippingData: ShippingData
  showHighlightedMessage: boolean
}

export const ReturnDetails = (
  props: RouteComponentProps<{ orderId: string }> & Props
) => {
  const {
    match: {
      params: { orderId },
    },
    onPageChange,
    items,
    creationDate,
    canRefundCard,
    shippingData,
    showHighlightedMessage,
  } = props

  const handles = useCssHandles(CSS_HANDLES)
  const {
    actions: { areFieldsValid },
  } = useReturnRequest()

  const {
    hints: { phone },
  } = useRuntime()

  const handleFieldsValidation = () => {
    if (areFieldsValid()) {
      onPageChange('submit-form')
      typeof window !== 'undefined' && window.scrollTo(0, 0)
    }
  }

  return (
    <>
      <div className={`${handles.returnDetailsContainer} mb5`}>
        <div className="w-100 mt4">
          <div className="f4 mb5 fw5">
            <FormattedMessage id="store/return-app.return-order-details.section-products" />
          </div>
        </div>
        <div className="w-100 flex flex-row-ns ba br3 b--muted-4 flex-column">
          <div
            className={`${handles.orderIdDetailsWrapper} flex flex-column pa4 b--muted-4 flex-auto bb bb-0-ns br-ns`}
          >
            <div>
              <div className="c-muted-2 f6">
                <FormattedMessage id="store/return-app.return-order-details.page-header.order-id" />
              </div>
              <div className="w-100 mt2">
                <div className="f4 fw5 c-on-base">{orderId}</div>
              </div>
            </div>
          </div>
          <div
            className={`${handles.creationDateDetailsWrapper} flex flex-column pa4 b--muted-4 flex-auto bb bb-0-ns br-ns`}
          >
            <div>
              <div className="c-muted-2 f6">
                <FormattedMessage id="store/return-app.return-order-details.page-header.creation-date" />
              </div>
              <div className="w-100 mt2">
                <div className="f4 fw5 c-on-base">
                  <FormattedDate
                    value={creationDate}
                    day="2-digit"
                    month="2-digit"
                    year="numeric"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div className="t-body lh-copy c-muted-1 mb3 ml3 w-two-thirds-ns w-100">
        <FormattedMessage id="store/return-app.return-order-details.page-header.subtitle" />
      </div>
      <div className={!phone ? 'overflow-scroll' : ''}>
        <ItemsList items={items} creationDate={creationDate} />
      </div>
      <div className="mb8">
        <Divider orientation="horizontal" />
      </div>
      <div className="w-100">
        <div className="f4 fw5">
          <FormattedMessage id="store/return-app.return-order-details.section-details" />
        </div>
      </div>
      {showHighlightedMessage ? (
        <div className={`${handles.highlightedFormMessage} w-100 mt4`}>
          <FormattedMessage id="store/return-app.return-order-details.section-details-highlighted-message" />
        </div>
      ) : null}
      <div className="flex-ns flex-wrap flex-row">
        <ContactDetails />
        <AddressDetails shippingData={shippingData} />
        <UserCommentDetails />
      </div>
      <div className="mv8">
        <Divider orientation="horizontal" />
      </div>
      <div className="w-100">
        <div className="f4 fw5">
          <FormattedMessage id="store/return-app.return-order-details.section-payment" />
        </div>
      </div>
      <PaymentMethods canRefundCard={canRefundCard} />
      <TermsAndConditions />
      <div className="flex justify-center mt6">
        <Button onClick={handleFieldsValidation} block={phone}>
          <FormattedMessage id="store/return-app.return-order-details.button.next" />
        </Button>
      </div>
    </>
  )
}

```


[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 return-app/react/store/createReturnRequest/graphql/getOrdersAvailableToReturn.gql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
query ordersAvailableToReturn($page: Int!) {
  ordersAvailableToReturn(page: $page) @context(provider: "vtex.return-app") {
    list {
      orderId
      creationDate
      invoicedItems {
        id
        productId
        quantity
        imageUrl
      }
      processedItems {
        itemIndex
        quantity
      }
      excludedItems {
        itemIndex
      }
    }
    paging {
      total
      pages
      currentPage
      perPage
    }
  }
}

```


[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 return-app/react/store/createReturnRequest/graphql/createReturnRequest.gql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation CreateReturn($returnRequest: ReturnRequestInput!) {
  createReturnRequest(returnRequest: $returnRequest)
    @context(provider: "vtex.return-app") {
    returnRequestId
  }
}

```


[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 return-app/react/store/createReturnRequest/graphql/nearestPickupPoints.gql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
query nearestPickupPoints($lat: String!, $long: String!) {
  nearestPickupPoints(lat: $lat, long: $long)
    @context(provider: "vtex.return-app") {
    items {
      pickupPoint {
        friendlyName
        address {
          addressId
          addressType
          postalCode
          city
          state
          country
          street
          number
        }
      }
    }
  }
}

```


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

[User] Show me the implementation of return-app/react/store/createReturnRequest/graphql/getOrderToReturnSummary.gql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
query orderToReturnSummary($orderId: ID!) {
  orderToReturnSummary(orderId: $orderId)
    @context(provider: "vtex.return-app") {
    orderId
    creationDate
    invoicedItems {
      id
      productId
      quantity
      name
      localizedName
      imageUrl
      orderItemIndex
    }
    processedItems {
      itemIndex
      quantity
    }
    excludedItems {
      itemIndex
    }
    clientProfileData {
      name
      email
      phoneNumber
    }
    shippingData {
      addressId
      address
      city
      state
      country
      zipCode
      addressType
      geoCoordinates
    }
    paymentData {
      canRefundCard
    }
  }
}

```


[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 return-app/react/store/createReturnRequest/graphql/getGeoCoordinates.gql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
query getGeoCoordinates($orderId: ID!) {
  orderToReturnSummary(orderId: $orderId)
    @context(provider: "vtex.return-app") {
    shippingData {
      geoCoordinates
    }
  }
}

```


[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 return-app/react/store/createReturnRequest/components/layout/CustomMessage.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { ReactElement } from 'react'
import React from 'react'
import { IconWarning } from 'vtex.styleguide'

interface Props {
  status: string
  message: ReactElement
}

export const CustomMessage = ({ status, message }: Props) => {
  return (
    <section className="flex items-center mt2">
      <div
        className={`flex items-center ${
          status === 'error' ? 'bg-washed-red' : 'bg-washed-yellow'
        } br2-s`}
      >
        <span
          className={`${
            status === 'error' ? 'c-danger' : ' c-warning'
          } flex items-center ml3`}
        >
          <IconWarning size={14} />
        </span>
        <p className="t-small ma2">{message}</p>
      </div>
    </section>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/loaders/OrderDetailsLoader.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import type { FC } from 'react'
import { useIntl } from 'react-intl'
import { SkeletonPiece } from 'vtex.my-account-commons'
import { Alert } from 'vtex.styleguide'
import type { ApolloError } from 'apollo-client'

import { parseReturnRequestError } from '../../../utils/parseReturnRequestError'

interface Props {
  data: {
    loading: boolean
    error?: ApolloError
  }
}

export const OrderDetailsLoader: FC<Props> = ({ data, children }) => {
  const { formatMessage } = useIntl()
  const { loading, error } = data

  return (
    <>
      {!loading && !error ? (
        children
      ) : error ? (
        <Alert type="error">
          {formatMessage(parseReturnRequestError(error))}
        </Alert>
      ) : (
        <>
          <div className="mb5 w-100">
            <div className="w-100 flex flex-row-ns ba br3 b--muted-4 flex-column">
              <div className="flex flex-column pa4 b--muted-4 flex-auto bb bb-0-ns br-ns">
                <div>
                  <div className="c-muted-2 f6">
                    <SkeletonPiece width="40" size="3" />
                  </div>
                  <div className="w-100 mt2">
                    <div className="f4 fw5 c-on-base">
                      <SkeletonPiece width="70" size="3" />
                    </div>
                  </div>
                </div>
              </div>
              <div className="flex flex-column pa4 b--muted-4 flex-auto bb bb-0-ns br-ns">
                <div>
                  <div className="c-muted-2 f6">
                    <SkeletonPiece width="40" size="3" />
                  </div>
                  <div className="w-100 mt2">
                    <div className="f4 fw5 c-on-base">
                      <SkeletonPiece width="70" size="3" />
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          {/* OrderId and creationDate end */}
          <table className="w-100">
            <thead className="w-100 ph4 truncate overflow-x-hidden c-muted-2 f6">
              <tr className="w-100 truncate overflow-x-hidden">
                <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s">
                  <SkeletonPiece width="30" size="2" />
                </th>
                <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                  <SkeletonPiece width="30" size="2" />
                </th>
                <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                  <SkeletonPiece width="30" size="2" />
                </th>
                <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                  <SkeletonPiece width="30" size="2" />
                </th>
                <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                  <SkeletonPiece width="30" size="2" />
                </th>
                <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                  <SkeletonPiece width="30" size="2" />
                </th>
              </tr>
            </thead>
            <tbody className="v-mid">
              <tr>
                <td>
                  <section className="ml3">
                    <p className="t-body fw5 m2">
                      <SkeletonPiece width="30" size="2" />
                    </p>
                    <div className="flex">
                      <SkeletonPiece width="10" size="5" />
                    </div>
                  </section>
                </td>
                <td>
                  <SkeletonPiece width="70" size="3" />
                </td>
                <td>
                  <SkeletonPiece width="70" size="3" />
                </td>
                <td>
                  <SkeletonPiece width="70" size="3" />
                </td>
                <td>
                  <SkeletonPiece width="70" size="3" />
                </td>
                <td>
                  <SkeletonPiece width="70" size="3" />
                </td>
              </tr>
            </tbody>
          </table>
          {/* TableEnd */}
          <div className="flex-ns flex-wrap flex-row mt5">
            {/* contactDetails */}
            <div className="flex-ns flex-wrap flex-auto flex-column pa4">
              <p>
                <SkeletonPiece width="30" size="3" />
              </p>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
            </div>
            {/* AddressDetails */}
            <div className="flex-ns flex-wrap flex-auto flex-column pa4">
              <p>
                <SkeletonPiece width="30" size="3" />
              </p>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
            </div>
            {/* UserCommentDetails */}
            <div className="mt4 ph4">
              <p>
                <SkeletonPiece width="30" size="3" />
              </p>
              <div>
                <SkeletonPiece width="50" size="8" />
              </div>
            </div>
          </div>
          <div className="flex-ns flex-wrap flex-auto flex-column pa4 mb6">
            <p>
              <SkeletonPiece width="70" size="3" />
            </p>
            <p>
              <SkeletonPiece width="70" size="3" />
            </p>
          </div>
          <div className="flex-ns flex-wrap flex-auto flex-column pa4">
            <SkeletonPiece width="70" size="3" />
          </div>
          <div className="flex-ns flex-wrap flex-auto flex-column pa4">
            <SkeletonPiece width="20" size="4" />
          </div>
        </>
      )}
    </>
  )
}

```


[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 return-app/react/store/createReturnRequest/components/loaders/OrderListStructureLoader.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import type { FunctionComponent } from 'react'
import { SkeletonPiece } from 'vtex.my-account-commons'

export const OrderListStructureLoader: FunctionComponent = () => {
  const rowsLength = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

  return (
    <table className="w-100">
      <thead className="w-100 ph4 truncate overflow-x-hidden c-muted-2 f6">
        <tr className="w-100 truncate overflow-x-hidden">
          <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s">
            <SkeletonPiece width="30" size="3" />
          </th>
          <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
            <SkeletonPiece width="40" size="3" />
          </th>
          <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
            <SkeletonPiece width="40" size="3" />
          </th>
          <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
            <SkeletonPiece width="30" size="3" />
          </th>
        </tr>
      </thead>
      <tbody className="v-mid">
        {rowsLength.map((num) => {
          return (
            <tr key={num}>
              <td className="pa3">
                <SkeletonPiece width="70" size="3" />
              </td>
              <td className="pa3">
                <SkeletonPiece width="40" size="3" />
              </td>
              <td className="pa3">
                <SkeletonPiece width="30" size="3" />
              </td>
              <td className="pa3">
                <SkeletonPiece width="50" size="3" />
              </td>
            </tr>
          )
        })}
      </tbody>
    </table>
  )
}

```


[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 return-app/react/store/ReturnRequest/loaders/StoreReturnDetailsLoader.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FC } from 'react'
import React from 'react'
import type { ApolloError } from 'apollo-client'
import { Alert } from 'vtex.styleguide'
import { useIntl } from 'react-intl'
import { SkeletonPiece } from 'vtex.my-account-commons'

import { parseReturnRequestError } from '../../utils/parseReturnRequestError'

interface Props {
  data: {
    loading: boolean
    error?: ApolloError
  }
}

export const StoreReturnDetailsLoader: FC<Props> = ({ data, children }) => {
  const { loading, error } = data
  const { formatMessage } = useIntl()

  return (
    <>
      {!loading && !error ? (
        children
      ) : error ? (
        <Alert type="error">
          {formatMessage(parseReturnRequestError(error))}
        </Alert>
      ) : (
        <>
          {/* Current Status */}
          <div className="mv4">
            <div className="mb4">
              <SkeletonPiece width="34" size="3" />
            </div>
            <div>
              <div>
                <SkeletonPiece width="20" size="3" />
              </div>
            </div>
          </div>
          {/* End of Current Status */}
          {/* Order Link */}
          <div>
            <SkeletonPiece width="25" size="3" />
          </div>
          {/* End of Order Link */}
          {/* Items List */}
          <section className="mt6">
            <table className="w-100 bb b--muted-4">
              <thead className="w-100 ph4 truncate overflow-x-hidden c-muted-2 f6">
                <tr className="w-100 truncate overflow-x-hidden">
                  <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s w3">
                    <SkeletonPiece width="80" size="2" />
                  </th>
                  <th
                    className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc"
                    style={{ width: '500px' }}
                  >
                    <SkeletonPiece width="30" size="2" />
                  </th>
                  <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                    <SkeletonPiece width="30" size="2" />
                  </th>
                  <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                    <SkeletonPiece width="30" size="2" />
                  </th>
                  <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                    <SkeletonPiece width="30" size="2" />
                  </th>
                  <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                    <SkeletonPiece width="30" size="2" />
                  </th>
                  <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                    <SkeletonPiece width="30" size="2" />
                  </th>
                </tr>
              </thead>
              <tbody className="v-mid">
                <tr>
                  <td>
                    <SkeletonPiece width="80" size="5" />
                  </td>
                  <td>
                    <span className="mh2">
                      <SkeletonPiece width="70" size="3" />
                    </span>
                    <span className="mh2">
                      <SkeletonPiece width="70" size="3" />
                    </span>
                    <span className="mh2">
                      <SkeletonPiece width="70" size="3" />
                    </span>
                    <span className="mh2">
                      <SkeletonPiece width="70" size="3" />
                    </span>
                  </td>
                  <td>
                    <SkeletonPiece width="70" size="3" />
                  </td>
                  <td>
                    <SkeletonPiece width="70" size="3" />
                  </td>
                  <td>
                    <SkeletonPiece width="70" size="3" />
                  </td>
                  <td>
                    <SkeletonPiece width="70" size="3" />
                  </td>
                  <td>
                    <SkeletonPiece width="70" size="3" />
                  </td>
                </tr>
              </tbody>
            </table>
          </section>
          {/* End of Items List */}
          {/* Order Return Values */}
          <section className="mv4">
            <div className="mb5 w-100">
              <h3>
                <SkeletonPiece width="40" size="3" />
              </h3>
              <div className="w-100 flex flex-row-ns ba br3 b--muted-4 flex-column">
                <div className="flex flex-column pa4 b--muted-4 flex-auto bb bb-0-ns br-ns">
                  <div>
                    <div className="c-muted-2 f6">
                      <SkeletonPiece width="40" size="3" />
                    </div>
                    <div className="w-100 mt2">
                      <div className="f4 fw5 c-on-base">
                        <SkeletonPiece width="70" size="3" />
                      </div>
                    </div>
                  </div>
                </div>
                <div className="flex flex-column pa4 b--muted-4 flex-auto bb bb-0-ns br-ns">
                  <div>
                    <div className="c-muted-2 f6">
                      <SkeletonPiece width="40" size="3" />
                    </div>
                    <div className="w-100 mt2">
                      <div className="f4 fw5 c-on-base">
                        <SkeletonPiece width="70" size="3" />
                      </div>
                    </div>
                  </div>
                </div>
                <div className="flex flex-column pa4 b--muted-4 flex-auto bb bb-0-ns br-ns">
                  <div>
                    <div className="c-muted-2 f6">
                      <SkeletonPiece width="40" size="3" />
                    </div>
                    <div className="w-100 mt2">
                      <div className="f4 fw5 c-on-base">
                        <SkeletonPiece width="70" size="3" />
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>
          {/* End of Return Value */}
          <div className="flex-ns flex-row">
            {/* Contact Details */}
            <section className="w-100">
              <div className="flex-ns flex-wrap flex-auto flex-column pa4">
                <p>
                  <SkeletonPiece width="30" size="3" />
                </p>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
              </div>
            </section>
            {/* End of Contact Details */}
            {/* Pickup Address */}
            <section className="w-100">
              <div className="flex-ns flex-wrap flex-auto flex-column pa4">
                <p>
                  <SkeletonPiece width="30" size="3" />
                </p>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
                <div className="mb4">
                  <SkeletonPiece width="70" size="3" />
                </div>
              </div>
            </section>
            {/* End of Pickup Address */}
          </div>
          {/* Refund Method */}
          <section className="w-50">
            <div className="flex-ns flex-wrap flex-auto flex-column pa4">
              <p>
                <SkeletonPiece width="30" size="3" />
              </p>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
              <div className="mb4">
                <SkeletonPiece width="70" size="3" />
              </div>
            </div>
          </section>
          {/* End of Refund Method */}
          {/* Status TimeLine */}
          <section className="w-50">
            <div className="flex-ns flex-wrap flex-auto flex-column pa4">
              <div className="mb6">
                <SkeletonPiece width="30" size="3" />
              </div>
              <div className="mb6">
                <SkeletonPiece width="70" size="5" />
              </div>
              <div className="mb6">
                <SkeletonPiece width="70" size="5" />
              </div>
              <div className="mb6">
                <SkeletonPiece width="70" size="5" />
              </div>
              <div className="mb6">
                <SkeletonPiece width="70" size="5" />
              </div>
              <div className="mb6">
                <SkeletonPiece width="70" size="5" />
              </div>
              <div className="mb6">
                <SkeletonPiece width="70" size="5" />
              </div>
            </div>
          </section>
          {/* End of Status TimeLine */}
          {/* Status History */}
          <section>
            <div className="flex-ns flex-wrap flex-auto flex-column pa4">
              <div className="mb6">
                <SkeletonPiece width="30" size="3" />
              </div>
              <table className="w-100 bb b--muted-4">
                <thead className="w-100 ph4 truncate overflow-x-hidden c-muted-2 f6">
                  <tr className="w-100 truncate overflow-x-hidden">
                    <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s">
                      <SkeletonPiece width="30" size="3" />
                    </th>
                    <th className="v-mid pv0 tl bb b--muted-4 normal bg-base bt ph3 z1 pv3-s tc">
                      <SkeletonPiece width="30" size="3" />
                    </th>
                  </tr>
                </thead>
                <tbody className="v-mid">
                  <tr>
                    <td>
                      <SkeletonPiece width="70" size="3" />
                    </td>
                    <td>
                      <SkeletonPiece width="70" size="3" />
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </section>
          {/* End of Status History */}
        </>
      )}
    </>
  )
}

```


[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 render-guide/pages/interfaces.json from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "guide": {
    "around": ["layout"]
  },
  "guide.home": {
    "component": "Home"
  },
  "guide.topic": {
    "component": "Topic"
  },
  "guide.topic-details": {
    "component": "Topic"
  },
  "layout": {
    "component": "PageLayout"
  }
}

```


[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 render-guide/pages/routes.json from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "guide.home": {
    "path": "/guide"
  },
  "guide.topic": {
    "path": "/guide/:topic"
  },
  "guide.topic-details": {
    "path": "/guide/:topic/:id"
  }
}

```


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

[User] Show me the implementation of render-guide/react/code-block.global.css from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```css
@import url('~highlight.js/styles/atom-one-dark.css')

```


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

[User] Show me the implementation of render-guide/react/Home.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment, FunctionComponent } from 'react'
import { Helmet } from 'vtex.render-runtime'

import MarkdownBlock from './components/MarkdownBlock'

const Home: FunctionComponent = () => (
  <Fragment>
    <Helmet>
      <title>VTEX IO Web Framework Guide</title>
    </Helmet>
    <MarkdownBlock source="home/main" />
  </Fragment>
)

export default Home

```


[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 render-guide/react/PageLayout.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

import Sidebar from './components/Sidebar'

// This component generates the base layout for this app.
const PageLayout: FunctionComponent = ({ children }) => (
  <div className="vh-100 flex flex-row">
    <Sidebar />
    <div className="w-100 overflow-y-scroll">
      <div className="mw8 pv8 ph9 center">{children}</div>
    </div>
  </div>
)

export default PageLayout

```


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

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "apollo-client": "^2.4.7",
    "graphql": "^14.0.2",
    "highlight.js": "^9.13.1",
    "react": "^16.6.3",
    "react-apollo": "^2.3.1",
    "react-dom": "^16.0.0",
    "react-markdown": "^4.0.4"
  },
  "devDependencies": {
    "@types/highlight.js": "^9.12.3",
    "@types/jest": "^24.0.11",
    "@types/lodash.isequal": "^4.5.5",
    "@types/node": "^10.12.17",
    "@types/react": "^16.7.17",
    "@vtex/test-tools": "^0.1.4",
    "prettier": "^1.16.4",
    "tslint": "^5.12.0",
    "tslint-config-vtex": "^2.1.0",
    "typescript": "^3.4.2"
  },
  "scripts": {
    "lint": "tsc --noEmit && tslint -c tslint.json './**/*.ts'",
    "test": "vtex-test-tools 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 render-guide/react/Topic.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Fragment, FunctionComponent } from 'react'
import { Helmet } from 'vtex.render-runtime'

import ErrorPage from './components/ErrorPage'
import topics from './components/topics'

interface Props {
  params: {
    id?: string;
    topic: string;
  }
}

const Topic: FunctionComponent<Props> = ({ params }) => {
  const topic = topics.find(entry => entry.slug === params.topic)

  return topic ? (
    <Fragment>
      <Helmet>
        <title>{topic.name}</title>
      </Helmet>
      <topic.Component id={params.id} />
    </Fragment>
  ) : (
    <ErrorPage />
  )
}

export default Topic

```


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

[Assistant]
Here's the implementation:

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

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

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

  export const ExtensionPoint: ReactElement
  export const Helmet: ReactElement
  export const Link: ReactElement
  export const NoSSR: ReactElement
  export const RenderContextConsumer: ReactElement
  export const canUseDOM: boolean
  export const withRuntimeContext: <TOriginalProps extends {}>(
    Component: ComponentType<TOriginalProps & RenderContextProps>
  ) => ComponentType<TOriginalProps>

  export const buildCacheLocator = (app: string, type: string, cacheId: string) => string

  interface RenderComponent<P = {}, S = {}> extends Component<P, S> {
    getCustomMessages?: (locale: string) => any
    schema: ComponentSchema
    getSchema?: (a: any, b: any?) => ComponentSchema
    uiSchema: UISchema
  }

  export interface ComponentsRegistry {
    [component: string]: RenderComponent<any, any>
  }

  export interface Window extends Window {
    __RENDER_7_COMPONENTS__: ComponentsRegistry
  }

  let global: Window
}

```


[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 render-guide/react/typings/custom.d.ts from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

export interface Book {
  authors: string[]
  cacheId?: string
  id: string
  name: string
}

export interface BookInput {
  authors: Book['authors']
  name: Book['name']
}

export interface CachedBookList {
  books: Array<Partial<Book>>
}

export interface CachedTotal {
  total: number
}

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

export interface Topic {
  Component: ReactElement
  name: string
  slug: string
}

```


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

[User] Show me the implementation of render-guide/react/typings/graphql.d.ts from the render-guide 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 render-guide/react/typings/vtex.styleguide.d.ts from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

  export const Alert: ReactElement
  export const Checkbox: ReactElement
  export const Badge: ReactElement
  export const Box: ReactElement
  export const Button: ReactElement
  export const Card: ReactElement
  export const Dropdown: ReactElement
  export const EmptyState: ReactElement
  export const IconArrowBack: ReactElement
  export const IconEdit: ReactElement
  export const Input: ReactElement
  export const Modal: ReactElement
  export const PageHeader: ReactElement
  export const Pagination: ReactElement
  export const Radio: ReactElement
  export const Spinner: ReactElement
  export const Tab: ReactElement
  export const Table: ReactElement
  export const Tabs: ReactElement
  export const Toggle: ReactElement
  export const Layout: ReactElement
  export const PageBlock: ReactElement
}

```


[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 render-guide/react/utils/array.ts from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const isValidIndex = <T>(array: T[], index: number) => Array.isArray(array) && index > -1

export const parseArray = (serialized: string | void) => (serialized ? serialized.split(',') : [])

export const serializeArray = (array: string[] | void) =>
  Array.isArray(array) ? array.join(',') : ''

```


[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 render-guide/react/components/SyncQueryData.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { Query } from 'react-apollo'

interface Props {
  children: (queryResult: any) => JSX.Element
  notifyOnNetworkStatusChange?: boolean
  prop: string
  query: any
  variables?: any
}

// This is a helper component that makes the query and waits untill
// all of the data is loaded to render the children. While the data
// is not loaded yet, a Spinner is shown.
const SyncQueryData: FunctionComponent<Props> = ({
  children,
  notifyOnNetworkStatusChange,
  prop,
  query,
  variables,
}: Props) => (
  <Query
    notifyOnNetworkStatusChange={notifyOnNetworkStatusChange}
    query={query}
    variables={variables}
  >
    {({ data, fetchMore, loading }) =>
      children && data && data[prop] !== undefined
        ? children({ data, fetchMore, loading })
        : null
    }
  </Query>
)

export default SyncQueryData

```


[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 render-guide/react/components/ErrorPage.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

const ErrorPage: FunctionComponent = () => <h1>404</h1>

export default ErrorPage

```


[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 render-guide/react/components/ComingSoon.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { EmptyState } from 'vtex.styleguide'

interface Props {
  title: string
}

// A simple empty state with a "coming soon" message.
const ComingSoon: FunctionComponent<Props> = ({ title }) => (
  <EmptyState title={title}>Coming soon...</EmptyState>
)

export default ComingSoon

```


[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 render-guide/react/components/ErrorPage.test.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

import ErrorPage from './ErrorPage'

test('should render ErrorPage component', () => {
  const { getByText } = render(<ErrorPage />)

  const element = getByText(/404/)

  expect(element).toBeDefined()
})

```


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

[User] Show me the implementation of render-guide/react/components/Header.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

const Header: FunctionComponent = () => <h1 className="pl5">Render Guide</h1>

export default Header

```


[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 render-guide/react/components/Input.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
// This component renders an input with preview capabilities.
// If no value is given, a spinner is shown. If a value is
// available, but it's in loading state, the input will be
// initialized, but disabled

import React, { FunctionComponent } from 'react'
import { Input as StyleguideInput, Spinner } from 'vtex.styleguide'

interface Props {
  autoFocus?: boolean
  loading?: boolean
  label: string
  value?: string
  onChange?: (e: any) => void
  disabled?: boolean
}

const Input: FunctionComponent<Props> = ({
  autoFocus,
  loading,
  label,
  value,
  onChange,
  disabled,
}) =>
  value !== undefined ? (
    <StyleguideInput
      autoFocus={autoFocus}
      disabled={disabled || loading}
      label={label}
      value={value}
      onChange={onChange}
    />
  ) : (
    <Spinner />
  )

export default Input

```


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

[User] Show me the implementation of render-guide/react/graphql/editBook.graphql from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation EditBook ($book: BookInput!, $id: ID!)  {
  editBook(book: $book, id: $id,) {
    authors
    cacheId
    id
    name
  }
}

```


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

[User] Show me the implementation of render-guide/react/graphql/newBook.graphql from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation NewElement ($book: BookInput!) {
  newBook(book: $book) {
    authors
    cacheId
    id
    name
  }
}

```


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

[User] Show me the implementation of render-guide/react/graphql/markdown.graphql from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```graphql
query GetMarkdown ($id: ID!) {
  source(id: $id)
}

```


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

[User] Show me the implementation of render-guide/react/graphql/book.graphql from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Book($id: ID!)  {
  book(id: $id) {
    authors
    cacheId
    id
    name
  }
}

```


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

[User] Show me the implementation of render-guide/react/graphql/books.graphql from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Books($from: Int = 0, $to: Int = 5) {
  books(from: $from, to: $to) {
    authors
    cacheId
    id
    name
  }
}

```


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

[User] Show me the implementation of render-guide/react/graphql/delete.graphql from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation DeleteElement($id: String) {
  delete(id: $id)
}

```


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

[User] Show me the implementation of render-guide/react/components/Sidebar/index.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

import topics from '../topics'

import SidebarItem from './Item'

const Sidebar: FunctionComponent = () => (
  <nav className="pv8 br b--light-gray">
    <ul className="pl0 list">
      <SidebarItem name="VTEX IO Web Framework Guide" />
      {topics.map(topic => (
        <SidebarItem key={topic.slug} name={topic.name} slug={topic.slug} />
      ))}
    </ul>
  </nav>
)

export default Sidebar

```


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

[User] Show me the implementation of render-guide/react/components/Sidebar/Item.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { RenderContextProps, withRuntimeContext } from 'vtex.render-runtime'

import { Topic } from '../../typings/custom'

interface Props extends RenderContextProps {
  name: Topic['name']
  slug?: Topic['slug']
}

const Item: FunctionComponent<Props> = ({ name, runtime, slug }) => {
  const isHome = !slug

  return (
    <li
      className={`mv6 ph8 f4 pointer ${isHome ? 'b' : ''}`}
      onClick={() => {
        runtime.navigate({
          page: isHome ? 'guide.home' : 'guide.topic',
          ...(slug && { params: { topic: slug } }),
        })
      }}
    >
      {name}
    </li>
  )
}

export default withRuntimeContext(Item)

```


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

[User] Show me the implementation of render-guide/react/components/Pagination/index.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

import booksQuery from '../../graphql/books.graphql'
import { Book } from '../../typings/custom'
import DetailsEditor from '../DetailsEditor'
import SyncQueryData from '../SyncQueryData'

import PaginatedList from './PaginatedList'

interface Props {
  hasDelete?: boolean
  id?: string
  newPage?: string
  type: 'dynamic' | 'static'
}

const Pagination: FunctionComponent<Props> = ({
  hasDelete,
  id,
  newPage,
  type,
}) => {
  const topicPage = `${type}-pagination`

  return (
    <SyncQueryData prop="books" query={booksQuery}>
      {({ data: { books }, loading }) =>
        id ? (
          <DetailsEditor
            book={books.find((book: Book) => book.id === id)}
            hasDelete={hasDelete}
            isLoading={loading}
            topicPage={topicPage}
          />
        ) : (
          <PaginatedList newPage={newPage} topicPage={topicPage} />
        )
      }
    </SyncQueryData>
  )
}

export default Pagination

```


[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 render-guide/react/components/Pagination/TableWrapper.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
// This component is just a wrapper for Styleguide's table
import React, { FunctionComponent } from 'react'
import { RenderContextProps, withRuntimeContext } from 'vtex.render-runtime'
import { Table } from 'vtex.styleguide'

import { Book } from '../../typings/custom'

import { tableSchema } from './consts'
import { Row } from './typings'

interface CustomProps {
  books: Book[]
  elementsPerPage: number
  from: number
  loading: boolean
  newPage: string
  next: () => void
  previous: () => void
  to: number
  topicPage: string
  total: number
}

type Props = CustomProps & RenderContextProps

const TableWrapper: FunctionComponent<Props> = ({
  books,
  elementsPerPage,
  from,
  loading,
  newPage,
  next,
  previous,
  runtime,
  to,
  topicPage,
  total,
}) => (
  <Table
    density="low"
    emptyStateLabel="Nothing to show"
    fixFirstColumn
    fullWidth
    items={books}
    loading={loading}
    onRowClick={({ rowData: { id } }: Row) => {
      runtime.navigate({
        page: 'guide.topic-details',
        params: {
          id,
          topic: topicPage,
        },
      })
    }}
    pagination={{
      currentItemFrom: from,
      currentItemTo: to,
      onNextClick: next,
      onPrevClick: previous,
      onRowsChange: (e: Event) => {
        console.log(e)
      },
      rowsOptions: [elementsPerPage],
      textOf: 'of',
      textShowRows: 'Show rows',
      totalItems: total,
    }}
    schema={tableSchema}
    toolbar={
      newPage
        ? {
            newLine: {
              handleCallback: () =>
                runtime.navigate({
                  page: newPage,
                  params: { id: 'new', topic: 'dynamic-pagination' },
                }),
              label: 'New',
            },
          }
        : undefined
    }
  />
)

export default withRuntimeContext(TableWrapper)

```


[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 render-guide/react/components/Pagination/utils.ts from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { Book } from '../../typings/custom'

export const updateQuery = (
  previous: { books: Book[] },
  { fetchMoreResult }: { fetchMoreResult: { books: Book[] } }
) => ({
  ...previous,
  books:
    fetchMoreResult && Array.isArray(fetchMoreResult.books)
      ? [
          ...previous.books,
          ...fetchMoreResult.books.filter(
            book => !previous.books.find(previousBook => previousBook.id === book.id)
          ),
        ]
      : previous.books,
})

```


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

[Assistant]
Here's the implementation:

```typescript
import { Book } from '../../../../../typings/custom'

export interface Row {
  rowData: {
    id: Book['id']
    name: Book['name']
  }
}

```


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

[User] Show me the implementation of render-guide/react/components/Pagination/consts.ts from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```typescript
export const tableSchema = {
  properties: {
    id: {
      title: 'ID',
      type: 'string',
    },
    name: {
      title: 'Name',
      type: 'string',
    },
  },
}

```


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

[User] Show me the implementation of render-guide/react/components/Pagination/PaginationController.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

import { Book } from '../../typings/custom'

import TableWrapper from './TableWrapper'
import { updateQuery } from './utils'

interface Props {
  books: Book[]
  fetchMore: (options: any) => Promise<any>
  loading?: boolean
  newPage?: string
  topicPage: string
  total: number
}

interface State {
  currentPage: number
  elementsPerPage: number
  from: number
  to: number
}

class PaginationController extends Component<Props, State> {
  constructor(props: Props) {
    super(props)

    this.state = {
      currentPage: 0,
      elementsPerPage: 5,
      from: 0,
      to: 5,
    }
  }

  public render = () => {
    const { books, loading, newPage, topicPage, total } = this.props

    const from = this.state.currentPage * this.state.elementsPerPage

    const to = Math.min(
      (this.state.currentPage + 1) * this.state.elementsPerPage,
      total
    )

    const totalPages = Math.ceil(total / this.state.elementsPerPage)

    const nextPage = (this.state.currentPage + 1) % totalPages

    const previousPage =
      totalPages - 1 - ((totalPages - this.state.currentPage) % totalPages)

    return (
      <TableWrapper
        books={books.slice(from, to)}
        currentPage={this.state.currentPage}
        elementsPerPage={this.state.elementsPerPage}
        from={from + 1}
        id="tableWrapper"
        loading={loading}
        newPage={newPage}
        next={this.getPageChangeHandler(nextPage)}
        previous={this.getPageChangeHandler(previousPage)}
        to={to}
        topicPage={topicPage}
        total={total}
      />
    )
  }

  private getPageChangeHandler = (newPage: number) => async () => {
    const { books, fetchMore, total } = this.props

    const from = newPage * this.state.elementsPerPage

    const to = Math.min((newPage + 1) * this.state.elementsPerPage, total)

    if (books.slice(from, to).length !== to - from) {
      await fetchMore({
        updateQuery,
        variables: { from, to },
      })
    }

    this.setState({
      currentPage: newPage,
      from,
      to,
    })
  }
}

export default PaginationController

```


[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 render-guide/react/components/Pagination/PaginatedList.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
// This component is the base for pagination to work. It starts
// by quering the total number of elements, then queries for
// some of the elements. It then renders the pagination
// controller that will take care of fetching more whenever
// it thinks it's necessary. To understand more about fetchMore,
// please refer to the Apollo Docs!

import React, { FunctionComponent } from 'react'
import { Query } from 'react-apollo'

import listBooks from '../../graphql/books.graphql'
import totalElements from '../../graphql/total.graphql'
import SyncQueryData from '../SyncQueryData'

import PaginationController from './PaginationController'

interface Props {
  // Link to the page of adding new entry in the database
  newPage?: string
  topicPage: string
}

const PaginatedList: FunctionComponent<Props> = ({ newPage, topicPage }) => (
  <SyncQueryData prop="total" query={totalElements}>
    {({ data: { total } }) => (
      <Query query={listBooks} notifyOnNetworkStatusChange>
        {({ data: { books }, fetchMore, loading }) => (
          <PaginationController
            books={books}
            fetchMore={fetchMore}
            loading={loading}
            newPage={newPage}
            topicPage={topicPage}
            total={total}
          />
        )}
      </Query>
    )}
  </SyncQueryData>
)

export default PaginatedList

```


[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 render-guide/react/components/MarkdownBlock/index.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { Query } from 'react-apollo'
import Markdown from 'react-markdown'
import { Spinner } from 'vtex.styleguide'

import markdownQuery from '../../graphql/markdown.graphql'
import ErrorPage from '../ErrorPage'

import BlockQuote from './BlockQuote'
import CodeBlock from './CodeBlock'

interface Props {
  source: string
}

// This component renders a markdown block synchronously.
const MarkdownBlock: FunctionComponent<Props> = ({ source }) => (
  <Query query={markdownQuery} variables={{ id: source }}>
    {({ data: { source: markdownSource }, loading }) =>
      loading ? (
        <Spinner />
      ) : markdownSource ? (
        <div className="lh-copy">
          <Markdown
            renderers={{ blockquote: BlockQuote, code: CodeBlock }}
            source={markdownSource}
          />
        </div>
      ) : (
        <ErrorPage />
      )
    }
  </Query>
)

export default MarkdownBlock

```


[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 render-guide/react/components/MarkdownBlock/BlockQuote.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

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

const BlockQuote: FunctionComponent = ({ children }) => (
  <blockquote>
    <p>{children}</p>
  </blockquote>
)

export default BlockQuote

```


[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 render-guide/react/components/MarkdownBlock/CodeBlock.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import highlightJs from 'highlight.js'
import React, { createRef, PureComponent } from 'react'

// import '../code-block.global.css'

interface Props {
  value: string
}

class CodeBlock extends PureComponent<Props> {
  private codeBlock = createRef<HTMLElement>()

  constructor(props: Props) {
    super(props)
  }

  public componentDidMount() {
    this.highlightCode()
  }

  public componentDidUpdate() {
    this.highlightCode()
  }

  public render() {
    return (
      <pre>
        <code className="br2" ref={this.codeBlock}>
          {this.props.value}
        </code>
      </pre>
    )
  }

  private highlightCode = () => {
    if (this.codeBlock.current) {
      highlightJs.highlightBlock(this.codeBlock.current)
    }
  }
}

export default CodeBlock

```


[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 render-guide/react/components/DetailsEditor/DeleteButton.tsx from the render-guide VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { MutationFn } from 'react-apollo'
import { RenderContextProps, withRuntimeContext } from 'vtex.render-runtime'
import { Button } from 'vtex.styleguide'

interface CustomProps {
  id: string
  isDisabled: boolean
  isLoading: boolean
  mutation: MutationFn<any>
}

type Props = CustomProps & RenderContextProps

class DeleteButton extends Component<Props> {
  public render() {
    return (
      <Button
        isDisabled={this.props.isDisabled}
        isLoading={this.props.isLoading}
        onClick={this.handleDelete}
        variation="danger"
      >
        Delete
      </Button>
    )
  }

  private handleDelete = async (e: React.MouseEvent<HTMLButtonElement>) => {
    e.stopPropagation()

    const { id, mutation, runtime } = this.props

    try {
      await mutation({
        variables: { id },
      })

      runtime.navigate({
        page: 'guide.topic',
        params: { topic: 'dynamic-pagination' },
      })
    } catch (err) {
      console.log(err)
    }
  }
}

export default withRuntimeContext(DeleteButton)

```