Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
57b296bd
Commit
57b296bd
authored
Feb 27, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
desktop view and sorting
parent
0b4b78da
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
192 additions
and
5 deletions
+192
-5
contracts.ts
types/api/contracts.ts
+1
-1
VerifiedContracts.tsx
ui/pages/VerifiedContracts.tsx
+56
-4
VerifiedContractsTable.tsx
ui/verifiedContracts/VerifiedContractsTable.tsx
+52
-0
VerifiedContractsTableItem.tsx
ui/verifiedContracts/VerifiedContractsTableItem.tsx
+81
-0
utils.ts
ui/verifiedContracts/utils.ts
+2
-0
No files found.
types/api/contracts.ts
View file @
57b296bd
...
...
@@ -7,7 +7,7 @@ export interface VerifiedContract {
language
:
'
vyper
'
|
'
yul
'
|
'
solidity
'
;
has_constructor_args
:
boolean
;
optimization_enabled
:
boolean
;
tx_count
:
number
;
tx_count
:
number
|
null
;
verified_at
:
string
;
market_cap
:
string
|
null
;
}
...
...
ui/pages/VerifiedContracts.tsx
View file @
57b296bd
...
...
@@ -2,8 +2,9 @@ import { Box, Flex, Hide, Show, Text } from '@chakra-ui/react';
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
type
{
VerifiedContractsFilters
}
from
'
types/api/contracts
'
;
import
type
{
VerifiedContract
,
VerifiedContract
sFilters
}
from
'
types/api/contracts
'
;
import
compareBns
from
'
lib/bigint/compareBns
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
import
useQueryWithPages
from
'
lib/hooks/useQueryWithPages
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
...
...
@@ -16,12 +17,55 @@ import PageTitle from 'ui/shared/Page/PageTitle';
import
Pagination
from
'
ui/shared/Pagination
'
;
import
SkeletonList
from
'
ui/shared/skeletons/SkeletonList
'
;
import
SkeletonTable
from
'
ui/shared/skeletons/SkeletonTable
'
;
import
type
{
Sort
,
SortField
}
from
'
ui/verifiedContracts/utils
'
;
import
VerifiedContractsFilter
from
'
ui/verifiedContracts/VerifiedContractsFilter
'
;
import
VerifiedContractsTable
from
'
ui/verifiedContracts/VerifiedContractsTable
'
;
const
SORT_SEQUENCE
:
Record
<
SortField
,
Array
<
Sort
|
undefined
>>
=
{
balance
:
[
'
balance-desc
'
,
'
balance-asc
'
,
undefined
],
txs
:
[
'
txs-desc
'
,
'
txs-asc
'
,
undefined
],
};
const
getNextSortValue
=
(
field
:
SortField
)
=>
(
prevValue
:
Sort
|
undefined
)
=>
{
const
sequence
=
SORT_SEQUENCE
[
field
];
const
curIndex
=
sequence
.
findIndex
((
sort
)
=>
sort
===
prevValue
);
const
nextIndex
=
curIndex
+
1
>
sequence
.
length
-
1
?
0
:
curIndex
+
1
;
return
sequence
[
nextIndex
];
};
const
sortFn
=
(
sort
:
Sort
|
undefined
)
=>
(
a
:
VerifiedContract
,
b
:
VerifiedContract
)
=>
{
switch
(
sort
)
{
case
'
balance-desc
'
:
{
const
result
=
compareBns
(
b
.
coin_balance
,
a
.
coin_balance
);
return
a
.
coin_balance
===
b
.
coin_balance
?
0
:
result
;
}
case
'
balance-asc
'
:
{
const
result
=
compareBns
(
a
.
coin_balance
,
b
.
coin_balance
);
return
a
.
coin_balance
===
b
.
coin_balance
?
0
:
result
;
}
case
'
txs-desc
'
:
{
const
result
=
(
a
.
tx_count
||
0
)
>
(
b
.
tx_count
||
0
)
?
-
1
:
1
;
return
a
.
tx_count
===
b
.
tx_count
?
0
:
result
;
}
case
'
txs-asc
'
:
{
const
result
=
(
a
.
tx_count
||
0
)
>
(
b
.
tx_count
||
0
)
?
1
:
-
1
;
return
a
.
tx_count
===
b
.
tx_count
?
0
:
result
;
}
default
:
return
0
;
}
};
const
VerifiedContracts
=
()
=>
{
const
router
=
useRouter
();
const
[
searchTerm
,
setSearchTerm
]
=
React
.
useState
(
getQueryParamString
(
router
.
query
.
q
)
||
undefined
);
const
[
type
,
setType
]
=
React
.
useState
(
getQueryParamString
(
router
.
query
.
filter
)
as
VerifiedContractsFilters
[
'
filter
'
]
||
undefined
);
const
[
sort
,
setSort
]
=
React
.
useState
<
Sort
>
();
const
debouncedSearchTerm
=
useDebounce
(
searchTerm
||
''
,
300
);
const
{
isError
,
isLoading
,
data
,
isPaginationVisible
,
pagination
,
onFilterChange
}
=
useQueryWithPages
({
...
...
@@ -49,6 +93,12 @@ const VerifiedContracts = () => {
setType
(
undefined
);
},
[
debouncedSearchTerm
,
onFilterChange
]);
const
handleSortToggle
=
React
.
useCallback
((
field
:
SortField
)
=>
{
return
()
=>
{
setSort
(
getNextSortValue
(
field
));
};
},
[]);
const
typeFilter
=
<
VerifiedContractsFilter
onChange=
{
handleTypeChange
}
defaultValue=
{
type
}
isActive=
{
Boolean
(
type
)
}
/>;
const
filterInput
=
(
...
...
@@ -89,13 +139,13 @@ const VerifiedContracts = () => {
<
SkeletonList
/>
</
Show
>
<
Hide
below=
"lg"
ssr=
{
false
}
>
<
SkeletonTable
columns=
{
[
'
15%
'
,
'
15%
'
,
'
10%
'
,
'
20%
'
,
'
20%
'
,
'
20%
'
]
}
/>
<
SkeletonTable
columns=
{
[
'
50%
'
,
'
130px
'
,
'
130px
'
,
'
50%
'
,
'
80px
'
,
'
110px
'
,
'
120px
'
]
}
/>
</
Hide
>
</>
);
}
if
(
data
.
items
.
length
===
0
&&
!
searchTerm
)
{
if
(
data
.
items
.
length
===
0
&&
!
searchTerm
&&
!
type
)
{
return
<
Text
as=
"span"
>
There are no verified contracts
</
Text
>;
}
...
...
@@ -103,13 +153,15 @@ const VerifiedContracts = () => {
return
<
EmptySearchResult
text=
{
`Couldn${ apos }t find any contract that matches your query.`
}
/>;
}
const
sortedData
=
data
.
items
.
slice
().
sort
(
sortFn
(
sort
));
return
(
<>
<
Show
below=
"lg"
ssr=
{
false
}
>
{
'
<AddressIntTxsList data={ data.items } currentAddress={ hash }/>
'
}
</
Show
>
<
Hide
below=
"lg"
ssr=
{
false
}
>
{
'
<AddressIntTxsTable data={ data.items } currentAddress={ hash }/>
'
}
<
VerifiedContractsTable
data=
{
sortedData
}
sort=
{
sort
}
onSortToggle=
{
handleSortToggle
}
/>
</
Hide
>
</>
);
...
...
ui/verifiedContracts/VerifiedContractsTable.tsx
0 → 100644
View file @
57b296bd
import
{
Table
,
Tbody
,
Tr
,
Th
,
Link
,
Icon
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
VerifiedContract
}
from
'
types/api/contracts
'
;
import
appConfig
from
'
configs/app/config
'
;
import
arrowIcon
from
'
icons/arrows/east.svg
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
type
{
Sort
,
SortField
}
from
'
./utils
'
;
import
VerifiedContractsTableItem
from
'
./VerifiedContractsTableItem
'
;
interface
Props
{
data
:
Array
<
VerifiedContract
>
;
sort
:
Sort
|
undefined
;
onSortToggle
:
(
field
:
SortField
)
=>
()
=>
void
;
}
const
VerifiedContractsTable
=
({
data
,
sort
,
onSortToggle
}:
Props
)
=>
{
const
sortIconTransform
=
sort
?.
includes
(
'
asc
'
)
?
'
rotate(-90deg)
'
:
'
rotate(90deg)
'
;
return
(
<
Table
variant=
"simple"
size=
"sm"
>
<
Thead
top=
{
80
}
>
<
Tr
>
<
Th
width=
"50%"
>
Contract
</
Th
>
<
Th
width=
"130px"
isNumeric
>
<
Link
display=
"flex"
alignItems=
"center"
justifyContent=
"flex-end"
onClick=
{
onSortToggle
(
'
balance
'
)
}
columnGap=
{
1
}
>
{
sort
?.
includes
(
'
balance
'
)
&&
<
Icon
as=
{
arrowIcon
}
boxSize=
{
4
}
transform=
{
sortIconTransform
}
/>
}
Balance
{
appConfig
.
network
.
currency
.
symbol
}
</
Link
>
</
Th
>
<
Th
width=
"130px"
isNumeric
>
<
Link
display=
"flex"
alignItems=
"center"
justifyContent=
"flex-end"
onClick=
{
onSortToggle
(
'
txs
'
)
}
columnGap=
{
1
}
>
{
sort
?.
includes
(
'
txs
'
)
&&
<
Icon
as=
{
arrowIcon
}
boxSize=
{
4
}
transform=
{
sortIconTransform
}
/>
}
Txs
</
Link
>
</
Th
>
<
Th
width=
"50%"
>
Compiler/version
</
Th
>
<
Th
width=
"80px"
>
Settings
</
Th
>
<
Th
width=
"110px"
>
Verified
</
Th
>
<
Th
width=
"120px"
>
Market cap
</
Th
>
</
Tr
>
</
Thead
>
<
Tbody
>
{
data
.
map
((
item
)
=>
<
VerifiedContractsTableItem
key=
{
item
.
address
.
hash
}
data=
{
item
}
/>)
}
</
Tbody
>
</
Table
>
);
};
export
default
React
.
memo
(
VerifiedContractsTable
);
ui/verifiedContracts/VerifiedContractsTableItem.tsx
0 → 100644
View file @
57b296bd
import
{
Tr
,
Td
,
Icon
,
Box
,
Flex
,
chakra
,
Tooltip
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
import
type
{
VerifiedContract
}
from
'
types/api/contracts
'
;
import
appConfig
from
'
configs/app/config
'
;
import
iconCheck
from
'
icons/check.svg
'
;
import
iconCross
from
'
icons/cross.svg
'
;
import
iconSuccess
from
'
icons/status/success.svg
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
AddressIcon
from
'
ui/shared/address/AddressIcon
'
;
import
AddressLink
from
'
ui/shared/address/AddressLink
'
;
import
HashStringShorten
from
'
ui/shared/HashStringShorten
'
;
interface
Props
{
data
:
VerifiedContract
;
}
const
VerifiedContractsTableItem
=
({
data
}:
Props
)
=>
{
const
balance
=
data
.
coin_balance
&&
data
.
coin_balance
!==
'
0
'
?
BigNumber
(
data
.
coin_balance
).
div
(
10
**
appConfig
.
network
.
currency
.
decimals
).
toFormat
(
2
)
:
'
0
'
;
return
(
<
Tr
>
<
Td
>
<
Flex
columnGap=
{
2
}
>
<
AddressIcon
address=
{
data
.
address
}
/>
<
Flex
columnGap=
{
2
}
flexWrap=
"wrap"
lineHeight=
{
6
}
w=
"calc(100% - 32px)"
>
<
AddressLink
hash=
{
data
.
address
.
hash
}
type=
"address"
alias=
{
data
.
address
.
name
}
/>
<
Box
color=
"text_secondary"
>
<
HashStringShorten
hash=
{
data
.
address
.
hash
}
isTooltipDisabled
/>
</
Box
>
</
Flex
>
</
Flex
>
</
Td
>
<
Td
isNumeric
lineHeight=
{
6
}
>
{
balance
}
</
Td
>
<
Td
isNumeric
lineHeight=
{
6
}
>
{
data
.
tx_count
?
data
.
tx_count
.
toLocaleString
()
:
'
0
'
}
</
Td
>
<
Td
lineHeight=
{
6
}
>
<
Flex
flexWrap=
"wrap"
columnGap=
{
2
}
>
<
chakra
.
span
textTransform=
"capitalize"
>
{
data
.
language
}
</
chakra
.
span
>
<
chakra
.
span
color=
"text_secondary"
wordBreak=
"break-all"
>
{
data
.
compiler_version
}
</
chakra
.
span
>
</
Flex
>
</
Td
>
<
Td
>
<
Tooltip
label=
"Optimization"
>
<
span
>
{
data
.
optimization_enabled
?
<
Icon
as=
{
iconCheck
}
boxSize=
{
6
}
color=
"green.500"
cursor=
"pointer"
/>
:
<
Icon
as=
{
iconCross
}
boxSize=
{
6
}
color=
"red.600"
cursor=
"pointer"
/>
}
</
span
>
</
Tooltip
>
<
Tooltip
label=
"Constructor args"
>
<
chakra
.
span
ml=
{
3
}
>
{
data
.
has_constructor_args
?
<
Icon
as=
{
iconCheck
}
boxSize=
{
6
}
color=
"green.500"
cursor=
"pointer"
/>
:
<
Icon
as=
{
iconCross
}
boxSize=
{
6
}
color=
"red.600"
cursor=
"pointer"
/>
}
</
chakra
.
span
>
</
Tooltip
>
</
Td
>
<
Td
lineHeight=
{
6
}
>
<
Flex
alignItems=
"center"
columnGap=
{
2
}
>
<
Icon
as=
{
iconSuccess
}
boxSize=
{
4
}
color=
"green.500"
/>
<
chakra
.
span
color=
"text_secondary"
>
{
dayjs
(
data
.
verified_at
).
fromNow
()
}
</
chakra
.
span
>
</
Flex
>
</
Td
>
<
Td
lineHeight=
{
6
}
>
N/A
</
Td
>
</
Tr
>
);
};
export
default
React
.
memo
(
VerifiedContractsTableItem
);
ui/verifiedContracts/utils.ts
0 → 100644
View file @
57b296bd
export
type
Sort
=
'
balance-asc
'
|
'
balance-desc
'
|
'
txs-asc
'
|
'
txs-desc
'
;
export
type
SortField
=
'
balance
'
|
'
txs
'
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment