diff --git a/packages/tradershub/src/constants/constants.tsx b/packages/tradershub/src/constants/constants.tsx index febb6f8eac7d..e4c3cd1c9ff7 100644 --- a/packages/tradershub/src/constants/constants.tsx +++ b/packages/tradershub/src/constants/constants.tsx @@ -112,6 +112,11 @@ export const IconToCurrencyMapper: IconToCurrencyMapperType = { }, }; +export const CurrencyTypes = { + CRYPTO: 'CRYPTO', + FIAT: 'FIAT', +} as const; + export const Regulation = { EU: 'EU', NonEU: 'Non-EU', @@ -121,3 +126,11 @@ export const BrokerCodes = { CR: 'CR', MF: 'MF', } as const; + +export const CurrenciesListOrder: { + CRYPTO: string[]; + FIAT: string[]; +} = { + FIAT: ['USD', 'EUR', 'GBP', 'AUD'], + CRYPTO: ['TUSDT', 'BTC', 'ETH', 'LTC', 'UST', 'eUSDT', 'BUSD', 'DAI', 'EURS', 'IDK', 'PAX', 'TUSD', 'USDC', 'USDK'], +}; diff --git a/packages/tradershub/src/helpers/currencies.ts b/packages/tradershub/src/helpers/currencies.ts new file mode 100644 index 000000000000..ebd30fe34360 --- /dev/null +++ b/packages/tradershub/src/helpers/currencies.ts @@ -0,0 +1,22 @@ +import { CurrenciesListOrder } from '@/constants'; +import { TCurrencyConfig } from '@/hooks/useCurrencies'; + +/** + * Reorder currencies list based on the type and the defined order as `CurrenciesListOrder`. + * @param {TCurrencyConfig[]} list - The list of currencies. + * @param {keyof typeof CurrenciesListOrder} type - The type of the order. + * @returns {TCurrencyConfig[]} The reordered list of currencies. + */ +export const reorderCurrencies = (list: TCurrencyConfig[], type: keyof typeof CurrenciesListOrder) => { + const newOrder = CurrenciesListOrder[type]; + + return list.sort((a, b) => { + if (newOrder.indexOf(a.id) < newOrder.indexOf(b.id)) { + return -1; + } + if (newOrder.indexOf(a.id) > newOrder.indexOf(b.id)) { + return 1; + } + return 0; + }); +}; diff --git a/packages/tradershub/src/helpers/currencyConfig.tsx b/packages/tradershub/src/helpers/currencyConfig.tsx deleted file mode 100644 index 6432876e9e4a..000000000000 --- a/packages/tradershub/src/helpers/currencyConfig.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import { - CurrencyBtcIcon, - CurrencyEthIcon, - CurrencyEurIcon, - CurrencyGbpIcon, - CurrencyLtcIcon, - CurrencyUsdcIcon, - CurrencyUsdIcon, - CurrencyUsdtIcon, -} from '@deriv/quill-icons'; - -export const CURRENCY_TYPES = { - CRYPTO: 'CRYPTO', - FIAT: 'FIAT', -} as const; - -export function getCurrencyConfig(type: keyof typeof CURRENCY_TYPES) { - if (type === CURRENCY_TYPES.FIAT) - return [ - { - icon: () => , - id: 'USD', - title: 'US Dollar', - }, - { - icon: () => , - id: 'EUR', - title: 'Euro', - }, - { - icon: () => , - id: 'GBP', - title: 'Pound Sterling', - }, - ]; - - return [ - { - icon: () => , - id: 'USDT', - info: true, - title: 'Tether', - }, - { - icon: () => , - id: 'BTC', - title: 'Bitcoin', - }, - { - icon: () => , - id: 'ETH', - title: 'Ethereum', - }, - { - icon: () => , - id: 'LTC', - title: 'Litecoin', - }, - { - icon: () => , - id: 'eUSDT', - info: true, - title: 'Tether ERC20', - }, - { - icon: () => , - id: 'USDC', - title: 'USD Coin', - }, - ]; -} diff --git a/packages/tradershub/src/helpers/index.ts b/packages/tradershub/src/helpers/index.ts index 3d9edcf6f40d..45b0f352a29a 100644 --- a/packages/tradershub/src/helpers/index.ts +++ b/packages/tradershub/src/helpers/index.ts @@ -1,4 +1,4 @@ -export * from './currencyConfig'; +export * from './currencies'; export * from './formikHelpers'; export * from './signupModalHelpers'; export * from './urls'; diff --git a/packages/tradershub/src/hooks/index.ts b/packages/tradershub/src/hooks/index.ts index 2ea4ebadfba4..b251a7a07d34 100644 --- a/packages/tradershub/src/hooks/index.ts +++ b/packages/tradershub/src/hooks/index.ts @@ -1,4 +1,5 @@ export { default as useCFDAssets } from './useCFDAssets'; +export { default as useCurrencies } from './useCurrencies'; export { default as useMT5AccountHandler } from './useMT5AccountHandler'; export { default as useNewCRRealAccount } from './useNewCRRealAccount'; export { default as usePlatformAssets } from './usePlatformAssets'; diff --git a/packages/tradershub/src/hooks/useCurrencies.ts b/packages/tradershub/src/hooks/useCurrencies.ts new file mode 100644 index 000000000000..5d9aee4d407d --- /dev/null +++ b/packages/tradershub/src/hooks/useCurrencies.ts @@ -0,0 +1,48 @@ +import { useMemo } from 'react'; +import { reorderCurrencies } from '@/helpers'; +import { useQuery } from '@deriv/api'; + +type TWebsiteStatus = NonNullable>['data']>['website_status']; +export type TCurrencyConfig = NonNullable['currencies_config'][string] & { + id: string; +}; + +export type TCurrencies = { + CRYPTO: TCurrencyConfig[]; + FIAT: TCurrencyConfig[]; +}; + +/** A custom hook to get the currency config information from `website_status` endpoint and in predefined order */ +const useCurrencies = () => { + const { data, ...rest } = useQuery('website_status'); + + const currencyConfig = useMemo(() => { + if (!data?.website_status?.currencies_config) return; + const currencies: TCurrencies = { + FIAT: [], + CRYPTO: [], + }; + + // map the currencies to their respective types (FIAT or CRYPTO) with their id + Object.entries(data?.website_status?.currencies_config).forEach(([key, value]) => { + if (value.type === 'fiat') { + currencies.FIAT.push({ ...value, id: key }); + } else { + currencies.CRYPTO.push({ ...value, id: key }); + } + }); + + // reorder the currencies based on the predefined order + return { + FIAT: reorderCurrencies(currencies.FIAT, 'FIAT'), + CRYPTO: reorderCurrencies(currencies.CRYPTO, 'CRYPTO'), + }; + }, [data?.website_status?.currencies_config]); + + return { + data: currencyConfig, + ...rest, + }; +}; + +export default useCurrencies; diff --git a/packages/tradershub/src/screens/CurrencySelector/Currencies.tsx b/packages/tradershub/src/screens/CurrencySelector/Currencies.tsx index 25b8e4b2bab5..8a263415f808 100644 --- a/packages/tradershub/src/screens/CurrencySelector/Currencies.tsx +++ b/packages/tradershub/src/screens/CurrencySelector/Currencies.tsx @@ -1,37 +1,38 @@ -import React, { useMemo } from 'react'; +import React from 'react'; import { twMerge } from 'tailwind-merge'; +import { CurrencyTypes } from '@/constants'; +import { TCurrencyConfig } from '@/hooks/useCurrencies'; import { InlineMessage, Text } from '@deriv-com/ui'; -import { CURRENCY_TYPES, getCurrencyConfig } from '../../helpers/currencyConfig'; import CurrencyCard from './CurrencyCard'; type TCurrencies = { - type: keyof typeof CURRENCY_TYPES; + list: TCurrencyConfig[]; + type: keyof typeof CurrencyTypes; }; /** * @name Currencies * @description The Currencies component is used to display the currencies in the currency selector screen. * @param {string} type - The type of the currency. + * @param {TCurrencyConfig[]} list - The list of the currency. * @returns {React.ReactNode} * @example - * @example + * @example */ -const Currencies = ({ type }: TCurrencies) => { - const currencies = useMemo(() => getCurrencyConfig(type), [type]); - +const Currencies = ({ type, list: currencies = [] }: TCurrencies) => { return (
- {type === CURRENCY_TYPES.CRYPTO ? 'Cryptocurrencies' : 'Fiat Currencies'} + {type === CurrencyTypes.CRYPTO ? 'Cryptocurrencies' : 'Fiat Currencies'} - {type === CURRENCY_TYPES.FIAT && ( + {type === CurrencyTypes.FIAT && ( Please note that you can only have 1 fiat account. )}
- {currencies.map(currency => ( - + {currencies?.map(currency => ( + ))}
diff --git a/packages/tradershub/src/screens/CurrencySelector/CurrencyCard.tsx b/packages/tradershub/src/screens/CurrencySelector/CurrencyCard.tsx index b62f64102752..d2b824bbc641 100644 --- a/packages/tradershub/src/screens/CurrencySelector/CurrencyCard.tsx +++ b/packages/tradershub/src/screens/CurrencySelector/CurrencyCard.tsx @@ -1,24 +1,22 @@ import React from 'react'; import { useFormikContext } from 'formik'; import { twMerge } from 'tailwind-merge'; +import { IconComponent } from '@/components'; import { StandaloneCircleInfoRegularIcon as CircleInfoIcon } from '@deriv/quill-icons'; import { Text } from '@deriv-com/ui'; -import { getCurrencyConfig } from '../../helpers/currencyConfig'; -type TCurrencyCard = ReturnType[number]; +type TCurrencyCard = { id: string; info?: boolean; title: string }; -// write docs for the component /** * @name CurrencyCard * @description The CurrencyCard component is used to display the currency card in the currency selector screen. - * @param {React.ReactNode} icon - The icon of the currency. * @param {string} id - The id of the currency. - * @param {boolean} info - The info of the currency. + * @param {boolean} info - The flag to display an info for a specific currency. * @param {string} title - The title of the currency. * @returns {React.ReactNode} - * @example + * @example */ -const CurrencyCard = ({ icon: Icon, id, info, title }: TCurrencyCard) => { +const CurrencyCard = ({ id, info, title }: TCurrencyCard) => { const { setFieldValue, values } = useFormikContext<{ currency: string }>(); const isSelected = values.currency === id; return ( @@ -34,7 +32,7 @@ const CurrencyCard = ({ icon: Icon, id, info, title }: TCurrencyCard) => { onClick={() => setFieldValue('currency', isSelected ? '' : id)} type='button' > - + {info && }
diff --git a/packages/tradershub/src/screens/CurrencySelector/CurrencySelector.tsx b/packages/tradershub/src/screens/CurrencySelector/CurrencySelector.tsx index d41e19d7cccc..88164fe273c3 100644 --- a/packages/tradershub/src/screens/CurrencySelector/CurrencySelector.tsx +++ b/packages/tradershub/src/screens/CurrencySelector/CurrencySelector.tsx @@ -1,9 +1,10 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import { Form, Formik, FormikValues } from 'formik'; +import { CurrencyTypes } from '@/constants'; import { WizardScreenActions, WizardScreenWrapper } from '@/flows'; -import { CURRENCY_TYPES } from '@/helpers'; +import useCurrencies from '@/hooks/useCurrencies'; import { ACTION_TYPES, useRealAccountCreationContext } from '@/providers'; -import { Divider } from '@deriv-com/ui'; +import { Divider, Loader } from '@deriv-com/ui'; import Currencies from './Currencies'; /** @@ -13,11 +14,13 @@ import Currencies from './Currencies'; */ const CurrencySelector = () => { const { dispatch, helpers, state } = useRealAccountCreationContext(); + const { data: currencies, isLoading } = useCurrencies(); const handleSubmit = (values: FormikValues) => { dispatch({ payload: { currency: values.currency }, type: ACTION_TYPES.SET_CURRENCY }); helpers.goToNextStep(); }; + return ( { > {({ values }) => (
-
- - - +
+ {/** temporarily setting a loader here until a proper design, needs to be here for center alignment */} + {isLoading && } + + {/** currencies as a type guard for typescript */} + {currencies && ( + + + + + + )}