@dynamic-labs/sdk-react-core
Version:
A React SDK for implementing wallet web3 authentication and authorization to your website.
82 lines (79 loc) • 5.69 kB
JavaScript
'use client'
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { useState, useMemo, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { StorageService } from '@dynamic-labs/utils';
import { ErrorContainer } from '../../components/ErrorContainer/ErrorContainer.js';
import { Search } from '../../components/Search/Search.js';
import { Skeleton } from '../../components/Skeleton/Skeleton.js';
import { useErrorContext } from '../../context/ErrorContext/ErrorContext.js';
import { DefaultFooter } from '../../layout/DynamicAuthLayout/DefaultFooter/DefaultFooter.js';
import { useEffectOnce } from '../../utils/hooks/useEffectOnce/useEffectOnce.js';
import { classNames } from '../../utils/functions/classNames/classNames.js';
import { EXCHANGE_PICKER_SEARCH_KEY } from '../../utils/constants/localStorage.js';
import { useProjectSettings } from '../../store/state/projectSettings/projectSettings.js';
import { isProviderExchange, convertProviderToExchangeKeyEnum } from '../../widgets/DynamicWidget/helpers/convertExchangeKeyAndProviderEnum.js';
import { SearchNotFoundMessage } from '../WalletList/SearchNotFoundMessage/SearchNotFoundMessage.js';
import { ReactComponent as SvgNoWalletFound } from '../../assets/no-wallet-found.js';
import { ExchangeListItem } from './ExchangeListItem/ExchangeListItem.js';
const ExchangeList = ({ onSelectExchange, showDefaultFooter, scrollContainerClassName, }) => {
var _a;
/**
* Clear search key on unmount
*/
useEffectOnce(() => () => StorageService === null || StorageService === void 0 ? void 0 : StorageService.setItem(EXCHANGE_PICKER_SEARCH_KEY, ''));
const { error } = useErrorContext();
const [footerBorderIsVisible, setFooterBorderIsVisible] = useState(true);
const { t } = useTranslation();
const projectSettings = useProjectSettings();
const [filterValue, setFilterValue] = useState((_a = StorageService.getItem(EXCHANGE_PICKER_SEARCH_KEY)) !== null && _a !== void 0 ? _a : '');
const exchangeNames = useMemo(() => {
if (!(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers))
return [];
const names = projectSettings.providers.flatMap(({ provider, enabledAt }) => {
if (!enabledAt)
return [];
if (isProviderExchange(provider)) {
return [provider];
}
else {
return [];
}
});
return [...new Set(names)];
}, [projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers]);
const filteredExchangeNames = useMemo(() => {
const term = filterValue.trim().toLowerCase();
if (!term)
return exchangeNames;
return exchangeNames.filter((provider) => convertProviderToExchangeKeyEnum(provider).toLowerCase().includes(term));
}, [exchangeNames, filterValue]);
const exchangeListScrollRef = useRef(null);
/* istanbul ignore next */
const handleScroll = () => {
const element = exchangeListScrollRef.current;
if (!element) {
return;
}
if ((element === null || element === void 0 ? void 0 : element.scrollTop) > (element === null || element === void 0 ? void 0 : element.clientHeight) * 1.25) {
setFooterBorderIsVisible(false);
}
else {
setFooterBorderIsVisible(true);
}
};
const handleFilterValueChange = (value) => {
StorageService.setItem(EXCHANGE_PICKER_SEARCH_KEY, value);
setFilterValue(value);
};
const searchContainer = !projectSettings ? (jsx(Skeleton, { className: 'exchange-list__search-skeleton' })) : (jsx("div", { className: classNames('exchange-list__search-container', {
'exchange-list__search-container--scroll': !error,
}), children: jsx(Search, { copykey: 'dyn_exchange_list.search.label', label: t('dyn_exchange_list.search.label'), value: filterValue, onChange: ({ target: { value } }) => handleFilterValueChange(value), onClickClear: () => handleFilterValueChange('') }) }));
return (jsxs(Fragment, { children: [searchContainer, Boolean(error) && (jsx(ErrorContainer, { className: 'exchange-list__error-container', withIcon: false, children: error })), jsx("div", { className: classNames('exchange-list__scroll-container', scrollContainerClassName, {
'exchange-list__scroll-container--error': Boolean(error),
'exchange-list__scroll-container--fixed-height': false,
}), "data-testid": 'exchange-list-scroll-container', ref: exchangeListScrollRef, onScroll: handleScroll, children: !projectSettings ? (jsx(Skeleton, { count: 10, className: 'exchange-list__tile-skeleton' })) : (
// eslint-disable-next-line react/jsx-no-useless-fragment
jsxs(Fragment, { children: [exchangeNames.length === 0 && (jsx(ErrorContainer, { copykey: 'dyn_exchange_list.no_exchange', children: t('dyn_exchange_list.no_exchanges') })), exchangeNames.length && filteredExchangeNames.length === 0 ? (jsx(SearchNotFoundMessage, { title: t('dyn_exchange_list.search.not_found.title'), subtitle: t('dyn_exchange_list.search.not_found.description'), image: jsx(SvgNoWalletFound, {}) })) : (filteredExchangeNames.map((exchange, index) => (jsx(ExchangeListItem, { exchange: convertProviderToExchangeKeyEnum(exchange), onResetSearchValue: () => handleFilterValueChange(''), onSelectExchange: onSelectExchange }, `${exchange}_${index}`))))] })) }), showDefaultFooter && (jsx(DefaultFooter, { hideBorder: !footerBorderIsVisible }))] }));
};
export { ExchangeList };