diff --git a/src/components/FilterSortContainer/index.module.scss b/src/components/FilterSortContainer/index.module.scss index 2b1fca07e..73f20a777 100644 --- a/src/components/FilterSortContainer/index.module.scss +++ b/src/components/FilterSortContainer/index.module.scss @@ -1,10 +1,11 @@ .filterSortContainerOnMobile { display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; justify-content: space-between; gap: 20px; ul { + max-width: 100%; display: flex; flex-wrap: wrap; margin: 0; @@ -12,6 +13,7 @@ li { width: 50%; list-style-type: none; + text-wrap: nowrap; &:nth-child(odd) { text-align: left; diff --git a/src/components/MultiFilterButton/index.tsx b/src/components/MultiFilterButton/index.tsx index 4401e820a..fff8cc9e7 100644 --- a/src/components/MultiFilterButton/index.tsx +++ b/src/components/MultiFilterButton/index.tsx @@ -1,6 +1,7 @@ import { Link, useLocation } from 'react-router-dom' import { Popover } from 'antd' import { useTranslation } from 'react-i18next' +import { useEffect, useMemo, useState } from 'react' import { ReactComponent as FilterIcon } from '../../assets/filter_icon.svg' import { ReactComponent as SelectedIcon } from '../../assets/selected-icon.svg' import { ReactComponent as NotSelectedIcon } from '../../assets/not-selected-icon.svg' @@ -17,81 +18,103 @@ export function MultiFilterButton({ filterList: { key: string; value: string; to: string; title: string | JSX.Element }[] isMobile?: boolean }) { - const { t } = useTranslation() + const [selected, setSelected] = useState('') + const { t, i18n } = useTranslation() const params = useSearchParams(filterName) const filter = params[filterName] - const types = filter?.split(',').filter(t => !!t) ?? [] + + const types = useMemo(() => filter?.split(',').filter(t => !!t) ?? [], [filter]) + + useEffect(() => { + const filterMap = new Map(filterList.map(f => [f.key, f.value])) + setSelected( + types + .map(item => filterMap.get(item)) + .filter(item => item) + .join(','), + ) + }, [filter, filterList, types]) const isAllSelected = types.length === filterList.length const isNoneSelected = types.length === 0 - const search = new URLSearchParams(useLocation().search) + const location = useLocation() + const search = new URLSearchParams(location.search) search.delete(filterName) search.delete('page') return ( - -
-

{t('components.multi_filter_button.select')}

- { - const newSearch = new URLSearchParams(search) - if (isNoneSelected) { - newSearch.append(filterName, filterList.map(f => f.value).join(',')) - } +
+ {!!selected && ( +
+ {selected} + +{types.length} +
+ )} + +
+

{t('components.multi_filter_button.select')}

+ { + const newSearch = new URLSearchParams(search) + if (isNoneSelected) { + newSearch.append(filterName, filterList.map(f => f.key).join(',')) + } - return `${filterList[0].to}?${newSearch.toString()}` - }} - > - {types.length > 0 ? ( - <>{isAllSelected ? : } - ) : ( - - )} - -
- {filterList.map(f => ( - { - const subTypes = new Set(types) - if (subTypes.has(f.value)) { - subTypes.delete(f.value) - } else { - subTypes.add(f.value) - } + return `/${i18n.language}${filterList[0].to}?${newSearch.toString()}` + }} + > + {types.length > 0 ? ( + <>{isAllSelected ? : } + ) : ( + + )} + +
+ {filterList.map(f => ( + { + const subTypes = new Set(types) + if (subTypes.has(f.key)) { + subTypes.delete(f.key) + } else { + subTypes.add(f.key) + } - const newSearch = new URLSearchParams(search) - if (subTypes.size === 0) { - newSearch.delete(filterName) - } else { - newSearch.append(filterName, Array.from(subTypes).join(',')) - } - return `${f.to}?${newSearch.toString()}` - }} - data-is-active={types.includes(f.value)} - > - {f.title} - {types.includes(f.value) ? : } - - ))} + const newSearch = new URLSearchParams(search) + if (subTypes.size === 0) { + newSearch.delete(filterName) + } else { + newSearch.append(filterName, Array.from(subTypes).join(',')) + } + return `/${i18n.language}${f.to}?${newSearch.toString()}` + }} + data-is-active={types.includes(f.key)} + > + {f.title} + {types.includes(f.key) ? : } + + ))} +
+ } + > +
+
- } - > - -
+ + ) } diff --git a/src/components/MultiFilterButton/styles.module.scss b/src/components/MultiFilterButton/styles.module.scss index 464517d06..8d36d8cc8 100644 --- a/src/components/MultiFilterButton/styles.module.scss +++ b/src/components/MultiFilterButton/styles.module.scss @@ -3,9 +3,11 @@ border: none; outline: none; background: none; - display: inline-flex; - vertical-align: text-top; + gap: 4px; cursor: pointer; + width: 70%; + display: flex; + align-items: center; } .antPopover { @@ -31,6 +33,33 @@ } } +.selected { + border-radius: 48px; + border: 1px solid var(--primary-dimmed-color); + background: var(--secondary-color); + display: flex; + padding: 4px 8px; + align-items: center; + align-content: flex-start; + gap: 4px; + flex-wrap: nowrap; + margin-left: 4px; + color: var(--primary-color); + font-size: 12px; + font-style: normal; + font-weight: 500; + line-height: normal; + align-self: center; + max-width: 85%; + + .selectedItems { + max-width: 95%; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +} + .filterItems { display: flex; flex-direction: column; diff --git a/src/pages/NftCollections/List.tsx b/src/pages/NftCollections/List.tsx index ea6de1bf4..a93e6540f 100644 --- a/src/pages/NftCollections/List.tsx +++ b/src/pages/NftCollections/List.tsx @@ -2,6 +2,7 @@ import { scriptToHash } from '@nervosnetwork/ckb-sdk-utils' import { Popover, Tooltip } from 'antd' import classNames from 'classnames' import { Trans, useTranslation } from 'react-i18next' +import { TFunction } from 'i18next' import { Link } from '../../components/Link' import SortButton from '../../components/SortButton' import { handleNftImgError, patchMibaoImg } from '../../utils/util' @@ -46,56 +47,57 @@ function useFilterList(): Record<'title' | 'value', string>[] { ] } -const filterList = [ - { - key: 'invalid', - value: 'invalid', - title: , - to: '/nft-collections', - }, - { - key: 'suspicious', - value: 'suspicious', - title: , - to: '/nft-collections', - }, - { - key: 'out-of-length-range', - value: 'out-of-length-range', - title: , - to: '/nft-collections', - }, - { - key: 'rgb++', - value: 'rgb++', - title: , - to: '/nft-collections', - }, - { - key: 'duplicate', - value: 'duplicate', - title: , - to: '/nft-collections', - }, - { - key: 'layer-1-asset', - value: 'layer-1-asset', - title: , - to: '/nft-collections', - }, - { - key: 'layer-2-asset', - value: 'layer-2-asset', - title: , - to: '/nft-collections', - }, - { - key: 'supply-limited', - value: 'supply-limited', - title: , - to: '/nft-collections', - }, -].filter(f => whiteList.includes(f.key)) +const getFilterList = (t: TFunction) => + [ + { + key: 'invalid', + value: t('xudt.tags.invalid'), + title: , + to: '/nft-collections', + }, + { + key: 'suspicious', + value: t('xudt.tags.suspicious'), + title: , + to: '/nft-collections', + }, + { + key: 'out-of-length-range', + value: t('xudt.tags.out-of-length-range'), + title: , + to: '/nft-collections', + }, + { + key: 'rgb++', + value: t('xudt.tags.rgb++'), + title: , + to: '/nft-collections', + }, + { + key: 'duplicate', + value: t('xudt.tags.duplicate'), + title: , + to: '/nft-collections', + }, + { + key: 'layer-1-asset', + value: t('xudt.tags.layer-1-asset'), + title: , + to: '/nft-collections', + }, + { + key: 'layer-2-asset', + value: t('xudt.tags.layer-2-asset'), + title: , + to: '/nft-collections', + }, + { + key: 'supply-limited', + value: t('xudt.tags.supply-limited'), + title: , + to: '/nft-collections', + }, + ].filter(f => whiteList.includes(f.key)) export const isTxFilterType = (s?: string): boolean => { return s ? ['all', 'm_nft', 'nrc721', 'cota', 'spore'].includes(s) : false @@ -141,7 +143,7 @@ const Tags = () => { return (
{t('xudt.title.tags')} - +
) } @@ -367,9 +369,9 @@ export const ListOnMobile: React.FC<{ isLoading: boolean; list: NFTCollection[] -
+
{t('xudt.title.tags')} - +
diff --git a/src/pages/NftCollections/styles.module.scss b/src/pages/NftCollections/styles.module.scss index 57b26afa7..10da348d2 100644 --- a/src/pages/NftCollections/styles.module.scss +++ b/src/pages/NftCollections/styles.module.scss @@ -67,8 +67,10 @@ } .colTags { + max-width: 100%; + width: 100%; display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; align-items: center; } diff --git a/src/pages/Xudts/index.tsx b/src/pages/Xudts/index.tsx index e11af710c..eb09a7ec6 100644 --- a/src/pages/Xudts/index.tsx +++ b/src/pages/Xudts/index.tsx @@ -5,6 +5,7 @@ import { FC, ReactNode, useState } from 'react' import { ColumnGroupType, ColumnType } from 'antd/lib/table' import dayjs from 'dayjs' import classNames from 'classnames' +import { TFunction } from 'i18next' import type { XUDT } from '../../models/Xudt' import { Link } from '../../components/Link' import Content from '../../components/Content' @@ -29,7 +30,7 @@ import { scripts } from '../ScriptList' type SortField = 'transactions' | 'addresses_count' | 'created_time' | 'mint_status' -const filterList = [ +const getfilterList = (t: TFunction) => [ // TODO: maybe removed in the future, hold on // { // key: 'out-of-length-range', @@ -39,19 +40,19 @@ const filterList = [ // }, { key: 'layer-1-asset', - value: 'layer-1-asset', + value: t('xudt.tags.layer-1-asset'), title: , to: '/xudts', }, { key: 'layer-2-asset', - value: 'layer-2-asset', + value: t('xudt.tags.layer-2-asset'), title: , to: '/xudts', }, { key: 'supply-limited', - value: 'supply-limited', + value: t('xudt.tags.supply-limited'), title: , to: '/xudts', }, @@ -134,20 +135,20 @@ export function TokensCard({ - {t('xudt.transactions')} - + {t('xudt.title.tags')} + - {t('xudt.unique_addresses')} - + {t('xudt.transactions')} + {t('xudt.created_time')} - {t('xudt.title.tags')} - + {t('xudt.unique_addresses')} + @@ -222,7 +223,7 @@ const TokenTable: FC<{ title: ( <> {t('xudt.title.tags')} - + ), className: styles.colTags, @@ -247,7 +248,7 @@ const TokenTable: FC<{ { title: ( <> - {t('xudt.unique_addresses')} + {t('xudt.unique_addresses')} ), diff --git a/src/pages/Xudts/styles.module.scss b/src/pages/Xudts/styles.module.scss index 124df684d..f4fefd39b 100644 --- a/src/pages/Xudts/styles.module.scss +++ b/src/pages/Xudts/styles.module.scss @@ -77,6 +77,8 @@ dt { display: flex; align-items: center; color: var(--primary-color); + font-size: 15px; + font-weight: 500; &:hover { color: var(--primary-color); @@ -236,6 +238,9 @@ dt { } .colTags { + display: flex; + align-items: center; + .tags { flex-wrap: wrap; display: flex; @@ -316,7 +321,13 @@ dt { } .colAddressCount { + display: flex; min-width: 170px; + flex-wrap: nowrap; + + span { + white-space: nowrap; + } } .colCreatedTime {