Skip to content

Commit

Permalink
feat(xudt-tag): add xudt tag column in xudt page (#378)
Browse files Browse the repository at this point in the history
  • Loading branch information
Daryl-L authored Jul 12, 2024
1 parent 706d639 commit 57edf66
Show file tree
Hide file tree
Showing 13 changed files with 457 additions and 166 deletions.
3 changes: 3 additions & 0 deletions src/assets/not-selected-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/assets/partial-selected-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/selected-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions src/components/MultiFilterButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Link, useLocation } from 'react-router-dom'
import { Popover } from 'antd'
import { useTranslation } from 'react-i18next'
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'
import { ReactComponent as PartialSelectedIcon } from '../../assets/partial-selected-icon.svg'
import { useSearchParams } from '../../hooks'
import styles from './styles.module.scss'

export function MultiFilterButton({
filterList,
isMobile,
filterName,
}: {
filterName: string
filterList: { key: string; value: string; to: string; title: string | JSX.Element }[]
isMobile?: boolean
}) {
const { t } = useTranslation()
const params = useSearchParams(filterName)
const filter = params[filterName]
let types = filterList.map(f => f.value)
if (filter !== undefined) {
types = filter.split(',').filter(t => !!t)
}

const isAllSelected = types.length === filterList.length
const isNoneSelected = types.length === 0
const search = new URLSearchParams(useLocation().search)
search.delete(filterName)
search.delete('page')

return (
<Popover
className={styles.container}
placement="bottomRight"
trigger={isMobile ? 'click' : 'hover'}
overlayClassName={styles.antPopover}
content={
<div className={styles.filterItems}>
<div className={styles.selectTitle}>
<h2>{t('components.multi_filter_button.select')}</h2>
<Link
key="all"
to={() => {
const newSearch = new URLSearchParams(search)
if (isNoneSelected) {
newSearch.append(filterName, filterList.map(f => f.value).join(','))
}

if (isAllSelected) {
newSearch.append(filterName, '')
}

return `${filterList[0].to}?${newSearch.toString()}`
}}
>
{types.length > 0 ? (
<>{isAllSelected ? <SelectedIcon /> : <PartialSelectedIcon />}</>
) : (
<NotSelectedIcon />
)}
</Link>
</div>
{filterList.map(f => (
<Link
key={f.key}
to={() => {
const subTypes = new Set(types)
if (subTypes.has(f.value)) {
subTypes.delete(f.value)
} else {
subTypes.add(f.value)
}

const newSearch = new URLSearchParams(search)
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) ? <SelectedIcon /> : <NotSelectedIcon />}
</Link>
))}
</div>
}
>
<FilterIcon
className={styles.filter}
// if the filter is the empty string, display highlight
// if the filter is the string list, display highlight
// if the filter is undefined, not display highlight
data-changed={filter !== undefined}
/>
</Popover>
)
}

MultiFilterButton.displayName = 'MultiFilterButton'

export default MultiFilterButton
79 changes: 79 additions & 0 deletions src/components/MultiFilterButton/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.container {
appearance: none;
border: none;
outline: none;
background: none;
display: inline-flex;
vertical-align: text-top;
margin-left: 8px;
cursor: pointer;
}

.antPopover {
:global {
/* stylelint-disable-next-line selector-class-pattern */
.ant-popover-inner {
border-radius: 8px;
box-shadow: 0 2px 10px 0 #eee;
}

/* stylelint-disable-next-line selector-class-pattern */
.ant-popover-inner-content {
padding: 14px 24px 14px 16px;
}
}
}

.filter {
margin-left: 8px;
color: #999;

&[data-changed='true'] {
color: var(--primary-color);
}
}

.filterItems {
display: flex;
flex-direction: column;
width: 200px;

.selectTitle {
color: var(--primary-color);

h2 {
color: #333;
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: normal;
}

display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border-radius: 8px;

a {
padding: 0;
}
}

a {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border-radius: 8px;

svg {
color: var(--primary-color);
}

&:hover {
background: var(--primary-hover-bg-color);
cursor: pointer;
}
}
}
2 changes: 1 addition & 1 deletion src/components/XUDTTag/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const XUDTTag = ({ tagName }: { tagName: string }) => {
const { push } = useHistory()

let tag = tagName
let content = t(`xudt.${tag}`)
let content = t(`xudt.tags.${tag}`)
if (tag.startsWith('verified-on-')) {
// FIXME: should be i18n
content = content.replace('Platform', tag.replace('verified-on-', ''))
Expand Down
44 changes: 13 additions & 31 deletions src/components/XUDTTag/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,25 @@
&[data-type='supply-limited'] {
border-color: #fcdeb0;
background: #fdf5d7;

span {
color: #caac0f;
}
color: #caac0f;
}

&[data-type='out-of-length-range'] {
border-color: #b0cbfc;
background: #d7e5fd;

span {
color: #346dff;
}
color: #346dff;
}

&[data-type='invalid'] {
border-color: #ccc;
background: #f0f0f0;

span {
color: #666;
}
color: #666;
}

&[data-type='duplicate'] {
border-color: #ffdba6;
background: #fffcf2;

span {
color: #ffa800;
}
color: #ffa800;
}

&[data-type='layer-1-asset'] {
Expand All @@ -63,37 +51,31 @@
&[data-type='verified-on-platform'] {
border-color: #99e6ca;
background: #d7fdf2;
color: #00bb8e;
}

span {
color: #00bb8e;
}
&[data-type='unnamed'] {
border: 1px solid #e5e5e5;
background: #fafafa;
color: #999;
}

&[data-type='supply-unlimited'] {
border-color: #b0e1fc;
background: #d2f7ff;

span {
color: #00a7cc;
}
color: #00a7cc;
}

&[data-type='rgbpp-compatible'] {
border: none;
background: linear-gradient(90deg, #ffd176 0.23%, #ffdb81 6.7%, #84ffcb 99.82%);

span {
color: #333;
}
color: #333;
}

&[data-type='suspicious'] {
background: #ffe8e8;
border-color: #ff9c9c;

span {
color: #fa504f;
}
color: #fa504f;
}

span {
Expand Down
32 changes: 22 additions & 10 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@
"handling-reorg": "Reorg detected at {{time}} so CKB Explorer is checking data thoroughly. It may take half an hour, please visit later",
"migration-notice": "Service of CKB explorer will have a migration on {{time}}, and the server might be unavailable temporarily"
},
"components": {
"multi_filter_button": {
"select": "Select"
}
},
"navbar": {
"wallet": "Wallet",
"charts": "Charts",
Expand Down Expand Up @@ -208,6 +213,7 @@
"estimated_epoch_time": "Estimated Epoch Time",
"transactions_per_minute": "Transactions per Minute",
"transactions_last_24hrs": "Transactions in Last 24hrs",
"tags": "Tags",
"nervos_dao": "Nervos DAO",
"mainnet": "Lina Mainnet",
"testnet": "Testnet"
Expand Down Expand Up @@ -759,6 +765,9 @@
"repeat_inscription_symbol": "This inscription is a duplicate with an earlier release of the same symbol."
},
"xudt": {
"title": {
"tags": "Tags"
},
"holder_allocation": "Holder Allocation",
"holder_allocation_description": "There are {{ckb}} CKB Holder and {{btc}} BTC holder of the current asset.",
"lock_hash": "Lock Hash",
Expand All @@ -779,16 +788,19 @@
"address_count": "Address Count",
"created_time": "Created Time",
"tokens_empty": "There are no xUDTs at this time.",
"invalid": "Invalid",
"suspicious": "Suspicious",
"out-of-length-range": "Out Of Length Range",
"duplicate": "Duplicate",
"layer-1-asset": "Layer 1 Asset",
"layer-2-asset": "Layer 2 Asset",
"verified-on": "Verified On Platform",
"supply-limited": "Supply Limited",
"supply-unlimited": "Supply Unlimited",
"rgbpp-compatible": "RGB++ Compatible",
"tags": {
"invalid": "Invalid",
"suspicious": "Suspicious",
"out-of-length-range": "Out Of Length Range",
"duplicate": "Duplicate",
"layer-1-asset": "Layer 1 Asset",
"layer-2-asset": "Layer 2 Asset",
"verified-on": "Verified On Platform",
"supply-limited": "Supply Limited",
"supply-unlimited": "Supply Unlimited",
"rgbpp-compatible": "RGB++ Compatible",
"unnamed": "Unnamed"
},
"category": "Category"
},
"nft": {
Expand Down
Loading

0 comments on commit 57edf66

Please sign in to comment.