The `CountriesAndRatesCard` component enables users to select whether a discount will apply to all countries or to specific countries. The user can also provide an upper bound for shipping rates so that a discount can be limited only to shipping situations that are financially viable for the user. ## Properties |Name|Type|Description|Required| |---|---|---|---| |countrySelectionType|`Field`|Whether a discount applies to all countries or to specific countries.|Yes| |selectedCountries|`Field`|The specific country codes that a discount applies to.|Yes| |excludeShippingRates|`Field`|Whether the discount only applies when shipping rates are under a certain amount.|Yes| |maximumShippingPrice|`Field`|The maximum shipping rate where the discount applies.|Yes| |countrySelector|`React.ReactNode`|The widget the enables users to select countries.|Yes| |currencyCode|`CurrencyCode`|The currency code used for the maxiumum shipping price input.|Yes| ## Example code ```jsx?title:'MyApp.jsx' import React, { useState } from "react"; import { CountriesAndRatesCard, CountrySelectionType, } from "@shopify/discount-app-components"; export default function MyApp() { const [countrySelectionType, setCountrySelectionType] = useState( CountrySelectionType.AllCountries ); const [excludeShippingRates, setExcludeShippingRates] = useState(false); const [maximumShippingPrice, setMaximumShippingPrice] = useState(0); const [countries, setCountries] = useState([]); return ( } currencyCode={CurrencyCode.Cad} /> ); } ``` ### CountrySelector The following code is an example of the `CountrySelector` component: ```jsx?title:'CountrySelector.jsx' import React, {useState} from 'react'; import {TextField, Icon, Button} from '@shopify/polaris'; import {SearchMinor} from '@shopify/polaris-icons'; import CountryPicker from './CountryPicker'; export default function CountrySelector({ selectedCountries, setSelectedCountries }) { const [isOpen, setIsOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); return (
{ setSearchQuery(nextSearchQuery); setIsOpen(true); }} value={searchQuery} autoComplete="off" prefix={} connectedRight={ } /> setIsOpen(false)} onSelect={(customers) => { setIsOpen(false); setSelectedCustomers(customers); }} />
); } ``` ### CountryPicker To load the list of countries where the app user can ship, we need to query the GraphQL API. In the following `CountryPicker` component, `./authenticatedGraphQL` is used to proxy the GraphQL request: ```jsx?title:'CountryPicker.jsx' import React, {useState} from 'React'; import { gql } from 'graphql-request'; import { useQuery } from 'react-query'; import { unstable_Picker as Picker } from '@shopify/app-bridge-react'; import { fetchGraphQL } from './authenticatedGraphQL'; // A request to proxy the GraphQL request import { useLocalizeCountry } from '@shopify/discount-app-components'; const SHOP_COUNTRIES_QUERY = gql` query GetShopCountries { shop { id countriesInShippingZones { countryCodes includeRestOfWorld } } } `; function CountryPicker({ isOpen, onCancel, onSelect, searchQuery, setSearchQuery, initialSelectedItems, }) { const [selectedItems, setSelectedItems] = useState(); const graphQLClient = useGraphQLClient(); const localizeCountry = useLocalizeCountry(); let countries = []; let countryCodes = []; useEffect(() => { setSelectedItems(initialSelectedItems); }, [initialSelectedItems]); // The request to fetch countries const { data, error, isLoading: dataIsLoading, } = useQuery(['GetCountries'], async () => fetchGraphQL(SHOP_COUNTRIES_QUERY)); // Map the API response to a list of countries if (!dataIsLoading && !error) { countryCodes = data.data.shop.countriesInShippingZones.countryCodes const includesRestOfWorld = data.data.shop.countriesInShippingZones.includesRestOfWorld; countries = countryCodes.map((node) => localizeCountry(countryCode)); } return ( ({id:item}))} maxSelectable={0} searchQuery={searchQuery} onCancel={onCancel} onSelect={({ selectedItems }) => { onSelect( selectedItems.map((item) => countryCodes.find((node) => node === item.id), ), ); }} onSearch={(options) => { setSearchQuery(options.searchQuery); }} emptySearchLabel={ { title: 'No Countries', description: 'There is no country for this search', withIllustration: true, } } loading={dataIsLoading} searchQueryPlaceholder="Search country" primaryActionLabel="Select" secondaryActionLabel="Cancel" title="Country Picker" /> ); } ```