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
1ce2d44e
Commit
1ce2d44e
authored
Sep 29, 2022
by
tom
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'main' of github.com:blockscout/frontend into page-layout
parents
6c83a0b0
46ae538f
Changes
30
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
204 additions
and
221 deletions
+204
-221
cookies.ts
lib/cookies.ts
+1
-1
dayjs.ts
lib/date/dayjs.ts
+36
-1
getStaticPaths.ts
lib/next/account/getStaticPaths.ts
+1
-3
api_key.tsx
pages/[network_type]/[network_sub_type]/account/api_key.tsx
+1
-1
custom_abi.tsx
.../[network_type]/[network_sub_type]/account/custom_abi.tsx
+1
-1
public_tags_request.tsx
..._type]/[network_sub_type]/account/public_tags_request.tsx
+1
-1
tag_address.tsx
...[network_type]/[network_sub_type]/account/tag_address.tsx
+1
-1
tag_transaction.tsx
...work_type]/[network_sub_type]/account/tag_transaction.tsx
+1
-1
watchlist.tsx
...s/[network_type]/[network_sub_type]/account/watchlist.tsx
+1
-1
pending-transactions.tsx
...network_type]/[network_sub_type]/pending-transactions.tsx
+1
-1
txs.tsx
pages/[network_type]/[network_sub_type]/txs.tsx
+1
-1
FilterButton.tsx
ui/shared/FilterButton.tsx
+5
-6
Page.tsx
ui/shared/Page/Page.tsx
+24
-28
Pagination.tsx
ui/shared/Pagination.tsx
+14
-43
RoutedTabs.tsx
ui/shared/RoutedTabs/RoutedTabs.tsx
+2
-4
SortButton.tsx
ui/shared/SortButton.tsx
+5
-4
Utilization.tsx
ui/shared/Utilization.tsx
+7
-3
AddressLink.tsx
ui/shared/address/AddressLink.tsx
+8
-5
Header.tsx
ui/snippets/header/Header.tsx
+16
-23
NavFooter.tsx
ui/snippets/navigation/NavFooter.tsx
+11
-23
NavLink.tsx
ui/snippets/navigation/NavLink.tsx
+11
-11
NavigationDesktop.tsx
ui/snippets/navigation/NavigationDesktop.tsx
+23
-13
NetworkLogo.tsx
ui/snippets/networkMenu/NetworkLogo.tsx
+1
-1
NetworkMenu.tsx
ui/snippets/networkMenu/NetworkMenu.tsx
+2
-2
SearchBar.tsx
ui/snippets/searchBar/SearchBar.tsx
+4
-9
SearchBarDesktop.tsx
ui/snippets/searchBar/SearchBarDesktop.tsx
+3
-3
SearchBarMobile.tsx
ui/snippets/searchBar/SearchBarMobile.tsx
+2
-0
TxInternalsFilter.tsx
ui/tx/internals/TxInternalsFilter.tsx
+0
-3
TxsContent.tsx
ui/txs/TxsContent.tsx
+6
-10
TxsTableItem.tsx
ui/txs/TxsTableItem.tsx
+14
-17
No files found.
lib/cookies.ts
View file @
1ce2d44e
...
...
@@ -12,7 +12,7 @@ export enum NAMES {
export
function
get
(
name
?:
string
|
undefined
|
null
)
{
if
(
!
isBrowser
())
{
return
()
=>
{}
;
return
undefined
;
}
return
Cookies
.
get
(
name
);
}
...
...
lib/date/dayjs.ts
View file @
1ce2d44e
// eslint-disable-next-line no-restricted-imports
import
dayjs
from
'
dayjs
'
;
import
duration
from
'
dayjs/plugin/duration
'
;
import
localizedFormat
from
'
dayjs/plugin/localizedFormat
'
;
import
relativeTime
from
'
dayjs/plugin/relativeTime
'
;
import
updateLocale
from
'
dayjs/plugin/updateLocale
'
;
dayjs
.
locale
(
'
en
'
);
dayjs
.
extend
(
relativeTime
);
const
relativeTimeConfig
=
{
thresholds
:
[
{
l
:
'
s
'
,
r
:
1
},
{
l
:
'
ss
'
,
r
:
59
,
d
:
'
second
'
},
{
l
:
'
m
'
,
r
:
1
},
{
l
:
'
mm
'
,
r
:
59
,
d
:
'
minute
'
},
{
l
:
'
h
'
,
r
:
1
},
{
l
:
'
hh
'
,
r
:
23
,
d
:
'
hour
'
},
{
l
:
'
d
'
,
r
:
1
},
{
l
:
'
dd
'
,
r
:
29
,
d
:
'
day
'
},
{
l
:
'
M
'
,
r
:
1
},
{
l
:
'
MM
'
,
r
:
11
,
d
:
'
month
'
},
{
l
:
'
y
'
},
{
l
:
'
yy
'
,
d
:
'
year
'
},
],
};
dayjs
.
extend
(
relativeTime
,
relativeTimeConfig
);
dayjs
.
extend
(
updateLocale
);
dayjs
.
extend
(
localizedFormat
);
dayjs
.
extend
(
duration
);
dayjs
.
updateLocale
(
'
en
'
,
{
formats
:
{
LLLL
:
'
MMMM-DD-YYYY HH:mm:ss A Z UTC
'
,
},
relativeTime
:
{
s
:
'
a sec
'
,
ss
:
'
%d secs
'
,
future
:
'
in %s
'
,
past
:
'
%s ago
'
,
m
:
'
a min
'
,
mm
:
'
%d mins
'
,
h
:
'
an hour
'
,
hh
:
'
%d hours
'
,
d
:
'
a day
'
,
dd
:
'
%d days
'
,
M
:
'
a month
'
,
MM
:
'
%d months
'
,
y
:
'
a year
'
,
yy
:
'
%d years
'
,
},
});
export
default
dayjs
;
lib/next/account/getStaticPaths.ts
View file @
1ce2d44e
import
type
{
GetStaticPaths
}
from
'
next
'
;
import
getAvailablePaths
from
'
lib/networks/getAvailablePaths
'
;
export
const
getStaticPaths
:
GetStaticPaths
=
async
()
=>
{
return
{
paths
:
getAvailablePaths
(),
fallback
:
fals
e
};
return
{
paths
:
[],
fallback
:
tru
e
};
};
pages/[network_type]/[network_sub_type]/account/api_key.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
ApiKeysPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
><
title
>
{
title
}
</
title
></
Head
>
...
...
pages/[network_type]/[network_sub_type]/account/custom_abi.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
CustomAbiPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
><
title
>
{
title
}
</
title
></
Head
>
...
...
pages/[network_type]/[network_sub_type]/account/public_tags_request.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
PublicTagsPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
><
title
>
{
title
}
</
title
></
Head
>
...
...
pages/[network_type]/[network_sub_type]/account/tag_address.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
AddressTagsPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
><
title
>
{
title
}
</
title
></
Head
>
...
...
pages/[network_type]/[network_sub_type]/account/tag_transaction.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
TransactionTagsPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
><
title
>
{
title
}
</
title
></
Head
>
...
...
pages/[network_type]/[network_sub_type]/account/watchlist.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
WatchListPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
>
...
...
pages/[network_type]/[network_sub_type]/pending-transactions.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
AddressTagsPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
><
title
>
{
title
}
</
title
></
Head
>
...
...
pages/[network_type]/[network_sub_type]/txs.tsx
View file @
1ce2d44e
...
...
@@ -15,7 +15,7 @@ type Props = {
}
const
AddressTagsPage
:
NextPage
<
Props
>
=
({
pageParams
}:
Props
)
=>
{
const
title
=
getNetworkTitle
(
pageParams
);
const
title
=
getNetworkTitle
(
pageParams
||
{}
);
return
(
<>
<
Head
><
title
>
{
title
}
</
title
></
Head
>
...
...
ui/shared/FilterButton.tsx
View file @
1ce2d44e
import
{
Button
,
Circle
,
Icon
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
B
ox
,
B
utton
,
Circle
,
Icon
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
filterIcon
from
'
icons/filter.svg
'
;
const
FilterIcon
=
<
Icon
as=
{
filterIcon
}
boxSize=
{
5
}
/>;
const
FilterIcon
=
<
Icon
as=
{
filterIcon
}
boxSize=
{
5
}
mr=
{
{
base
:
0
,
lg
:
2
}
}
/>;
interface
Props
{
isActive
:
boolean
;
isCollapsed
?:
boolean
;
appliedFiltersNum
?:
number
;
onClick
:
()
=>
void
;
}
const
FilterButton
=
({
isActive
,
appliedFiltersNum
,
onClick
,
isCollapsed
}:
Props
,
ref
:
React
.
ForwardedRef
<
HTMLButtonElement
>
)
=>
{
const
FilterButton
=
({
isActive
,
appliedFiltersNum
,
onClick
}:
Props
,
ref
:
React
.
ForwardedRef
<
HTMLButtonElement
>
)
=>
{
const
badgeColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
const
badgeBgColor
=
useColorModeValue
(
'
blue.700
'
,
'
gray.50
'
);
return
(
<
Button
ref=
{
ref
}
leftIcon=
{
isCollapsed
?
undefined
:
FilterIcon
}
rightIcon=
{
appliedFiltersNum
?
<
Circle
bg=
{
badgeBgColor
}
size=
{
5
}
color=
{
badgeColor
}
>
{
appliedFiltersNum
}
</
Circle
>
:
undefined
}
size=
"sm"
fontWeight=
"500"
...
...
@@ -30,7 +28,8 @@ const FilterButton = ({ isActive, appliedFiltersNum, onClick, isCollapsed }: Pro
px=
{
1.5
}
flexShrink=
{
0
}
>
{
isCollapsed
?
FilterIcon
:
'
Filter
'
}
{
FilterIcon
}
<
Box
display=
{
{
base
:
'
none
'
,
lg
:
'
block
'
}
}
>
Filter
</
Box
>
</
Button
>
);
};
...
...
ui/shared/Page/Page.tsx
View file @
1ce2d44e
import
{
chakra
,
VStack
,
Grid
,
GridItem
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
VStack
,
Box
,
HStack
}
from
'
@chakra-ui/react
'
;
import
{
useQuery
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
PageContent
from
'
ui/shared/Page/PageContent
'
;
import
Header
from
'
ui/snippets/header/Header
'
;
import
NavigationDesktop
from
'
ui/snippets/navigation/NavigationDesktop
'
;
...
...
@@ -16,8 +14,7 @@ interface Props {
className
?:
string
;
}
const
Page
=
({
children
,
wrapChildren
=
true
,
className
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
Page
=
({
children
}:
Props
)
=>
{
const
router
=
useRouter
();
const
fetch
=
useFetch
();
...
...
@@ -35,31 +32,30 @@ const Page = ({ children, wrapChildren = true, className }: Props) => {
}
},
[
networkType
,
networkSubType
]);
const
renderedChildren
=
wrapChildren
?
(
<
PageContent
>
{
children
}
</
PageContent
>
)
:
children
;
if
(
isMobile
)
{
return
(
<
VStack
width=
"100%"
minH=
"100vh"
spacing=
{
0
}
className=
{
className
}
>
<
Header
/>
{
renderedChildren
}
</
VStack
>
);
}
return
(
<
Grid
templateColumns=
"auto 1fr"
templateRows=
"auto 1fr"
rowGap=
"52px"
className=
{
className
}
>
<
GridItem
rowSpan=
{
2
}
colSpan=
{
1
}
>
<
HStack
w=
"100%"
minH=
"100vh"
alignItems=
"stretch"
>
<
NavigationDesktop
/>
</
GridItem
>
<
GridItem
>
<
VStack
width=
"100%"
paddingX=
{
{
base
:
4
,
lg
:
8
}
}
paddingTop=
{
{
base
:
0
,
lg
:
9
}
}
paddingBottom=
{
10
}
spacing=
{
0
}
>
<
Header
/>
</
GridItem
>
<
GridItem
>
{
renderedChildren
}
</
GridItem
>
</
Grid
>
<
Box
as=
"main"
w=
"100%"
paddingTop=
{
{
base
:
'
138px
'
,
lg
:
'
52px
'
}
}
>
{
children
}
</
Box
>
</
VStack
>
</
HStack
>
);
};
...
...
ui/shared/Pagination.tsx
View file @
1ce2d44e
...
...
@@ -6,13 +6,11 @@ import arrowIcon from 'icons/arrows/east-mini.svg';
type
Props
=
{
currentPage
:
number
;
maxPage
?:
number
;
isMobile
?:
boolean
;
}
const
MAX_PAGE_DEFAULT
=
50
;
const
Pagination
=
({
currentPage
,
maxPage
,
isMobile
}:
Props
)
=>
{
const
Pagination
=
({
currentPage
,
maxPage
}:
Props
)
=>
{
const
pageNumber
=
(
<
Flex
alignItems=
"center"
>
<
Button
...
...
@@ -42,20 +40,21 @@ const Pagination = ({ currentPage, maxPage, isMobile }: Props) => {
</
Flex
>
);
if
(
isMobile
)
{
return
(
<
Flex
fontSize=
"sm"
width=
"100%"
justifyContent=
"space-between"
width=
{
{
base
:
'
100%
'
,
lg
:
'
auto
'
}
}
justifyContent=
{
{
base
:
'
space-between
'
,
lg
:
'
unset
'
}
}
alignItems=
"center"
>
<
Flex
alignItems=
"center"
justifyContent=
"space-between"
w=
{
{
base
:
'
100%
'
,
lg
:
'
auto
'
}
}
>
<
IconButton
variant=
"outline"
size=
"sm"
aria
-
label=
"Next page"
w=
"36px"
icon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
/>
}
mr=
{
8
}
/>
{
pageNumber
}
<
IconButton
...
...
@@ -64,42 +63,14 @@ const Pagination = ({ currentPage, maxPage, isMobile }: Props) => {
aria
-
label=
"Next page"
w=
"36px"
icon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
transform=
"rotate(180deg)"
/>
}
/>
</
Flex
>
);
}
return
(
<
Flex
fontSize=
"sm"
>
<
Flex
alignItems=
"center"
justifyContent=
"space-between"
>
<
Button
variant=
"outline"
size=
"sm"
aria
-
label=
"Next page"
leftIcon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
/>
}
mr=
{
8
}
pl=
{
1
}
>
Previous
</
Button
>
{
pageNumber
}
<
Button
variant=
"outline"
size=
"sm"
aria
-
label=
"Next page"
rightIcon=
{
<
Icon
as=
{
arrowIcon
}
w=
{
5
}
h=
{
5
}
transform=
"rotate(180deg)"
/>
}
ml=
{
8
}
pr=
{
1
}
>
Next
</
Button
>
/>
</
Flex
>
<
Flex
alignItems=
"center"
width=
"132px"
ml=
{
16
}
>
<
Flex
alignItems=
"center"
width=
"132px"
ml=
{
16
}
display=
{
{
base
:
'
none
'
,
lg
:
'
flex
'
}
}
>
Go to
<
Input
w=
"84px"
size=
"xs"
ml=
{
2
}
/>
</
Flex
>
</
Flex
>
);
};
...
...
ui/shared/RoutedTabs/RoutedTabs.tsx
View file @
1ce2d44e
...
...
@@ -33,7 +33,7 @@ const RoutedTabs = ({ tabs, defaultActiveTab }: Props) => {
const
defaultIndex
=
tabs
.
findIndex
(({
routeName
})
=>
routeName
===
defaultActiveTab
);
const
isMobile
=
useIsMobile
();
const
[
activeTab
,
setActiveTab
]
=
React
.
useState
<
number
>
(
defaultIndex
);
const
[
activeTab
]
=
React
.
useState
<
number
>
(
defaultIndex
);
const
{
tabsCut
,
tabsList
,
tabsRefs
,
listRef
}
=
useAdaptiveTabs
(
tabs
,
isMobile
);
const
router
=
useRouter
();
...
...
@@ -45,8 +45,6 @@ const RoutedTabs = ({ tabs, defaultActiveTab }: Props) => {
const
newUrl
=
link
(
nextTab
.
routeName
,
router
.
query
);
router
.
push
(
newUrl
,
undefined
,
{
shallow
:
true
});
}
setActiveTab
(
index
);
},
[
tabs
,
router
]);
return
(
...
...
@@ -57,7 +55,7 @@ const RoutedTabs = ({ tabs, defaultActiveTab }: Props) => {
whiteSpace=
"nowrap"
ref=
{
listRef
}
overflowY=
"hidden"
overflowX=
{
isMobile
?
'
auto
'
:
undefined
}
overflowX=
{
{
base
:
'
auto
'
,
lg
:
undefined
}
}
overscrollBehaviorX=
"contain"
css=
{
{
'
scroll-snap-type
'
:
'
x mandatory
'
,
...
...
ui/shared/SortButton.tsx
View file @
1ce2d44e
import
{
Icon
,
IconButton
}
from
'
@chakra-ui/react
'
;
import
{
Icon
,
IconButton
,
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
upDownArrow
from
'
icons/arrows/up-down.svg
'
;
...
...
@@ -6,9 +6,10 @@ import upDownArrow from 'icons/arrows/up-down.svg';
type
Props
=
{
handleSort
:
()
=>
void
;
isSortActive
:
boolean
;
className
?:
string
;
}
const
SortButton
=
({
handleSort
,
isSortActive
}:
Props
)
=>
{
const
SortButton
=
({
handleSort
,
isSortActive
,
className
}:
Props
)
=>
{
return
(
<
IconButton
icon=
{
<
Icon
as=
{
upDownArrow
}
boxSize=
{
5
}
/>
}
...
...
@@ -16,12 +17,12 @@ const SortButton = ({ handleSort, isSortActive }: Props) => {
size=
"sm"
variant=
"outline"
colorScheme=
"gray-dark"
ml=
{
2
}
minWidth=
"36px"
onClick=
{
handleSort
}
isActive=
{
isSortActive
}
className=
{
className
}
/>
);
};
export
default
SortButton
;
export
default
chakra
(
SortButton
)
;
ui/shared/Utilization.tsx
View file @
1ce2d44e
...
...
@@ -4,18 +4,22 @@ import React from 'react';
interface
Props
{
className
?:
string
;
value
:
number
;
colorScheme
?:
'
green
'
|
'
gray
'
;
}
const
WIDTH
=
50
;
const
Utilization
=
({
className
,
value
}:
Props
)
=>
{
const
Utilization
=
({
className
,
value
,
colorScheme
=
'
green
'
}:
Props
)
=>
{
const
valueString
=
(
value
*
100
).
toFixed
(
2
)
+
'
%
'
;
const
colorGrayScheme
=
useColorModeValue
(
'
gray.500
'
,
'
gray.500
'
);
const
color
=
colorScheme
===
'
gray
'
?
colorGrayScheme
:
'
green.500
'
;
return
(
<
Flex
className=
{
className
}
alignItems=
"center"
>
<
Box
bg=
{
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
)
}
w=
{
`${ WIDTH }px`
}
h=
"4px"
borderRadius=
"full"
overflow=
"hidden"
>
<
Box
bg=
"green.500"
w=
{
valueString
}
h=
"100%"
/>
<
Box
bg=
{
color
}
w=
{
valueString
}
h=
"100%"
/>
</
Box
>
<
Text
color=
"green.500"
ml=
"10px"
fontWeight=
"bold"
>
{
valueString
}
</
Text
>
<
Text
color=
{
color
}
ml=
"10px"
fontWeight=
"bold"
>
{
valueString
}
</
Text
>
</
Flex
>
);
};
...
...
ui/shared/address/AddressLink.tsx
View file @
1ce2d44e
...
...
@@ -6,23 +6,26 @@ import HashStringShorten from 'ui/shared/HashStringShorten';
import
HashStringShortenDynamic
from
'
ui/shared/HashStringShortenDynamic
'
;
interface
Props
{
type
?:
'
address
'
|
'
transaction
'
|
'
token
'
;
type
?:
'
address
'
|
'
transaction
'
|
'
token
'
|
'
block
'
;
alias
?:
string
;
className
?:
string
;
hash
:
string
;
truncation
?:
'
constant
'
|
'
dynamic
'
|
'
none
'
;
fontWeight
?:
string
;
id
?:
string
;
}
const
AddressLink
=
({
alias
,
type
,
className
,
truncation
=
'
dynamic
'
,
hash
,
fontWeight
}:
Props
)
=>
{
const
AddressLink
=
({
alias
,
type
,
className
,
truncation
=
'
dynamic
'
,
hash
,
id
,
fontWeight
}:
Props
)
=>
{
const
link
=
useLink
();
let
url
;
if
(
type
===
'
transaction
'
)
{
url
=
link
(
'
tx_index
'
,
{
id
:
hash
});
url
=
link
(
'
tx_index
'
,
{
id
:
id
||
hash
});
}
else
if
(
type
===
'
token
'
)
{
url
=
link
(
'
token_index
'
,
{
id
:
hash
});
url
=
link
(
'
token_index
'
,
{
id
:
id
||
hash
});
}
else
if
(
type
===
'
block
'
)
{
url
=
link
(
'
block
'
,
{
id
:
id
||
hash
});
}
else
{
url
=
link
(
'
address_index
'
,
{
id
:
hash
});
url
=
link
(
'
address_index
'
,
{
id
:
id
||
hash
});
}
const
content
=
(()
=>
{
...
...
ui/snippets/header/Header.tsx
View file @
1ce2d44e
import
{
HStack
,
Box
,
Flex
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
NetworkLogo
from
'
ui/snippets/networkMenu/NetworkLogo
'
;
import
ProfileMenuDesktop
from
'
ui/snippets/profileMenu/ProfileMenuDesktop
'
;
import
ProfileMenuMobile
from
'
ui/snippets/profileMenu/ProfileMenuMobile
'
;
...
...
@@ -11,12 +10,10 @@ import Burger from './Burger';
import
ColorModeToggler
from
'
./ColorModeToggler
'
;
const
Header
=
()
=>
{
const
isMobile
=
useIsMobile
();
const
bgColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
if
(
isMobile
)
{
return
(
<
Box
bgColor=
{
bgColor
}
>
<>
<
Box
bgColor=
{
bgColor
}
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
>
<
Flex
as=
"header"
position=
"fixed"
...
...
@@ -36,23 +33,19 @@ const Header = () => {
</
Flex
>
<
SearchBar
/>
</
Box
>
);
}
return
(
<
HStack
as=
"header"
width=
"100%"
alignItems=
"center"
justifyContent=
"center"
paddingX=
{
12
}
paddingTop=
{
9
}
gap=
{
12
}
display=
{
{
base
:
'
none
'
,
lg
:
'
flex
'
}
}
>
<
SearchBar
/>
<
ColorModeToggler
/>
<
ProfileMenuDesktop
/>
</
HStack
>
</>
);
};
...
...
ui/snippets/navigation/NavFooter.tsx
View file @
1ce2d44e
import
{
VStack
,
Text
,
Stack
,
Icon
,
Link
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
VStack
,
Text
,
Stack
,
Icon
,
Link
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
ghIcon
from
'
icons/social/git.svg
'
;
import
statsIcon
from
'
icons/social/stats.svg
'
;
import
tgIcon
from
'
icons/social/telega.svg
'
;
import
twIcon
from
'
icons/social/tweet.svg
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
getDefaultTransitionProps
from
'
theme/utils/getDefaultTransitionProps
'
;
const
SOCIAL_LINKS
=
[
...
...
@@ -24,22 +23,13 @@ interface Props {
}
const
NavFooter
=
({
isCollapsed
,
hasAccount
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
width
=
(()
=>
{
if
(
isMobile
)
{
return
'
100%
'
;
}
return
isCollapsed
?
'
20px
'
:
'
180px
'
;
})();
const
isExpanded
=
isCollapsed
===
false
;
const
marginTop
=
(()
=>
{
if
(
!
hasAccount
)
{
return
'
auto
'
;
}
return
isMobile
?
6
:
20
;
return
{
base
:
6
,
lg
:
20
}
;
})();
return
(
...
...
@@ -48,8 +38,8 @@ const NavFooter = ({ isCollapsed, hasAccount }: Props) => {
spacing=
{
8
}
borderTop=
"1px solid"
borderColor=
{
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
)
}
width=
{
width
}
paddingTop=
{
isMobile
?
6
:
8
}
width=
{
{
base
:
'
100%
'
,
lg
:
isExpanded
?
'
180px
'
:
'
20px
'
,
xl
:
isCollapsed
?
'
20px
'
:
'
180px
'
}
}
paddingTop=
{
{
base
:
6
,
lg
:
8
}
}
marginTop=
{
marginTop
}
alignItems=
"flex-start"
alignSelf=
"center"
...
...
@@ -57,7 +47,7 @@ const NavFooter = ({ isCollapsed, hasAccount }: Props) => {
fontSize=
"xs"
{
...
getDefaultTransitionProps
({
transitionProperty
:
'
width
'
})
}
>
<
Stack
direction=
{
isCollapsed
?
'
column
'
:
'
row
'
}
>
<
Stack
direction=
{
{
base
:
'
row
'
,
lg
:
isExpanded
?
'
row
'
:
'
column
'
,
xl
:
isCollapsed
?
'
column
'
:
'
row
'
}
}
>
{
SOCIAL_LINKS
.
map
(
sl
=>
{
return
(
<
Link
href=
{
sl
.
link
}
key=
{
sl
.
link
}
variant=
"secondary"
w=
{
5
}
h=
{
5
}
aria
-
label=
{
sl
.
label
}
>
...
...
@@ -66,14 +56,12 @@ const NavFooter = ({ isCollapsed, hasAccount }: Props) => {
);
})
}
</
Stack
>
{
!
isCollapsed
&&
(
<>
<
Text
variant=
"secondary"
>
<
Box
display=
{
{
base
:
'
block
'
,
lg
:
isExpanded
?
'
block
'
:
'
none
'
,
xl
:
isCollapsed
?
'
none
'
:
'
block
'
}
}
>
<
Text
variant=
"secondary"
mb=
{
8
}
>
Blockscout is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Ethereum Networks.
</
Text
>
<
Text
variant=
"secondary"
>
Version:
<
Link
href=
{
VERSION_URL
}
target=
"_blank"
>
{
BLOCKSCOUT_VERSION
}
</
Link
></
Text
>
</>
)
}
</
Box
>
</
VStack
>
);
};
...
...
ui/snippets/navigation/NavLink.tsx
View file @
1ce2d44e
...
...
@@ -2,7 +2,6 @@ import { Link, Icon, Text, HStack, Tooltip, Box } from '@chakra-ui/react';
import
NextLink
from
'
next/link
'
;
import
React
from
'
react
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
getDefaultTransitionProps
from
'
theme/utils/getDefaultTransitionProps
'
;
import
useColors
from
'
./useColors
'
;
...
...
@@ -18,21 +17,15 @@ interface Props {
const
NavLink
=
({
text
,
url
,
icon
,
isCollapsed
,
isActive
,
px
}:
Props
)
=>
{
const
colors
=
useColors
();
const
isMobile
=
useIsMobile
();
const
width
=
(()
=>
{
if
(
isMobile
)
{
return
'
100%
'
;
}
return
isCollapsed
?
'
60px
'
:
'
180px
'
;
})();
const
isExpanded
=
isCollapsed
===
false
;
return
(
<
Box
as=
"li"
listStyleType=
"none"
w=
"100%"
>
<
NextLink
href=
{
url
}
passHref
>
<
Link
w=
{
width
}
px=
{
px
||
(
isCollapsed
?
'
15px
'
:
3
)
}
w=
{
{
base
:
'
100%
'
,
lg
:
isExpanded
?
'
180px
'
:
'
60px
'
,
xl
:
isCollapsed
?
'
60px
'
:
'
180px
'
}
}
px=
{
px
||
{
base
:
3
,
lg
:
isExpanded
?
3
:
'
15px
'
,
xl
:
isCollapsed
?
'
15px
'
:
3
}
}
py=
{
2.5
}
display=
"flex"
color=
{
isActive
?
colors
.
text
.
active
:
colors
.
text
.
default
}
...
...
@@ -53,7 +46,14 @@ const NavLink = ({ text, url, icon, isCollapsed, isActive, px }: Props) => {
>
<
HStack
spacing=
{
3
}
>
<
Icon
as=
{
icon
}
boxSize=
"30px"
/>
{
!
isCollapsed
&&
<
Text
variant=
"inherit"
fontSize=
"sm"
lineHeight=
"20px"
>
{
text
}
</
Text
>
}
<
Text
variant=
"inherit"
fontSize=
"sm"
lineHeight=
"20px"
display=
{
{
base
:
'
block
'
,
lg
:
isExpanded
?
'
block
'
:
'
none
'
,
xl
:
isCollapsed
?
'
none
'
:
'
block
'
}
}
>
{
text
}
</
Text
>
</
HStack
>
</
Tooltip
>
</
Link
>
...
...
ui/snippets/navigation/NavigationDesktop.tsx
View file @
1ce2d44e
import
{
Flex
,
Box
,
VStack
,
Icon
,
useColorModeValue
,
useBreakpointValue
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Box
,
VStack
,
Icon
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
chevronIcon
from
'
icons/arrows/east-mini.svg
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
useNavItems
from
'
lib/hooks/useNavItems
'
;
import
useNetwork
from
'
lib/hooks/useNetwork
'
;
import
isBrowser
from
'
lib/isBrowser
'
;
import
getDefaultTransitionProps
from
'
theme/utils/getDefaultTransitionProps
'
;
import
NetworkLogo
from
'
ui/snippets/networkMenu/NetworkLogo
'
;
import
NetworkMenu
from
'
ui/snippets/networkMenu/NetworkMenu
'
;
...
...
@@ -15,18 +16,24 @@ import NavLink from './NavLink';
const
NavigationDesktop
=
()
=>
{
const
{
mainNavItems
,
accountNavItems
}
=
useNavItems
();
const
selectedNetwork
=
useNetwork
();
const
isLargeScreen
=
useBreakpointValue
({
base
:
false
,
xl
:
true
});
const
navBarCollapsedCookie
=
cookies
.
get
(
cookies
.
NAMES
.
NAV_BAR_COLLAPSED
);
const
isAuth
=
Boolean
(
cookies
.
get
(
cookies
.
NAMES
.
API_TOKEN
));
const
hasAccount
=
selectedNetwork
?.
isAccountSupported
&&
isAuth
;
const
[
isCollapsed
,
setCollapsedState
]
=
React
.
useState
(
navBarCollapsedCookie
===
'
true
'
);
const
isInBrowser
=
isBrowser
();
const
[
hasAccount
,
setHasAccount
]
=
React
.
useState
(
false
);
const
[
isCollapsed
,
setCollapsedState
]
=
React
.
useState
<
boolean
|
undefined
>
();
React
.
useEffect
(()
=>
{
if
(
!
navBarCollapsedCookie
)
{
setCollapsedState
(
!
isLargeScreen
);
const
navBarCollapsedCookie
=
cookies
.
get
(
cookies
.
NAMES
.
NAV_BAR_COLLAPSED
);
const
isAuth
=
Boolean
(
cookies
.
get
(
cookies
.
NAMES
.
API_TOKEN
));
if
(
isInBrowser
)
{
if
(
navBarCollapsedCookie
===
'
true
'
)
{
setCollapsedState
(
true
);
}
},
[
isLargeScreen
,
navBarCollapsedCookie
]);
if
(
navBarCollapsedCookie
===
'
false
'
)
{
setCollapsedState
(
false
);
}
setHasAccount
(
Boolean
(
selectedNetwork
?.
isAccountSupported
&&
isAuth
&&
isInBrowser
));
}
},
[
isInBrowser
,
selectedNetwork
?.
isAccountSupported
]);
const
handleTogglerClick
=
React
.
useCallback
(()
=>
{
setCollapsedState
((
flag
)
=>
!
flag
);
...
...
@@ -40,16 +47,19 @@ const NavigationDesktop = () => {
borderColor
:
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
),
};
const
isExpanded
=
isCollapsed
===
false
;
return
(
<
Flex
display=
{
{
base
:
'
none
'
,
lg
:
'
flex
'
}
}
position=
"relative"
flexDirection=
"column"
alignItems=
"flex-start"
borderRight=
"1px solid"
borderColor=
{
containerBorderColor
}
px=
{
isCollapsed
?
4
:
6
}
px=
{
{
lg
:
isExpanded
?
6
:
4
,
xl
:
isCollapsed
?
4
:
6
}
}
py=
{
12
}
width=
{
isCollapsed
?
'
92px
'
:
'
229px
'
}
width=
{
{
lg
:
isExpanded
?
'
229px
'
:
'
92px
'
,
xl
:
isCollapsed
?
'
92px
'
:
'
229px
'
}
}
{
...
getDefaultTransitionProps
({
transitionProperty
:
'
width
,
padding
'
})
}
>
<
Box
...
...
@@ -86,12 +96,12 @@ const NavigationDesktop = () => {
_hover=
{
{
color
:
'
blue.400
'
}
}
borderRadius=
"base"
{
...
chevronIconStyles
}
transform=
{
isCollapsed
?
'
rotate(180deg)
'
:
'
rotate(0)
'
}
transform=
{
{
lg
:
isExpanded
?
'
rotate(0)
'
:
'
rotate(180deg)
'
,
xl
:
isCollapsed
?
'
rotate(180deg)
'
:
'
rotate(0)
'
}
}
{
...
getDefaultTransitionProps
({
transitionProperty
:
'
transform
,
left
'
})
}
transformOrigin=
"center"
position=
"absolute"
top=
"104px"
left=
{
isCollapsed
?
'
80px
'
:
'
216px
'
}
left=
{
{
lg
:
isExpanded
?
'
216px
'
:
'
80px
'
,
xl
:
isCollapsed
?
'
80px
'
:
'
216px
'
}
}
cursor=
"pointer"
onClick=
{
handleTogglerClick
}
/>
...
...
ui/snippets/networkMenu/NetworkLogo.tsx
View file @
1ce2d44e
...
...
@@ -57,7 +57,7 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => {
<
NextLink
href=
{
href
}
passHref
>
<
Box
as=
"a"
width=
{
isCollapsed
?
'
0
'
:
'
113px
'
}
width=
{
{
base
:
'
113px
'
,
lg
:
isCollapsed
===
false
?
'
113px
'
:
0
,
xl
:
isCollapsed
?
'
0
'
:
'
113px
'
}
}
display=
"inline-flex"
overflow=
"hidden"
onClick=
{
onClick
}
...
...
ui/snippets/networkMenu/NetworkMenu.tsx
View file @
1ce2d44e
...
...
@@ -4,7 +4,7 @@ import React from 'react';
import
NetworkMenuButton
from
'
./NetworkMenuButton
'
;
import
NetworkMenuContentDesktop
from
'
./NetworkMenuContentDesktop
'
;
interface
Props
{
isCollapsed
:
boolean
;
isCollapsed
?
:
boolean
;
}
const
NetworkMenu
=
({
isCollapsed
}:
Props
)
=>
{
...
...
@@ -13,7 +13,7 @@ const NetworkMenu = ({ isCollapsed }: Props) => {
{
({
isOpen
})
=>
(
<>
<
PopoverTrigger
>
<
Box
marginLeft=
{
isCollapsed
?
'
0px
'
:
'
7px
'
}
>
<
Box
marginLeft=
{
{
base
:
'
7px
'
,
lg
:
isCollapsed
===
false
?
'
7px
'
:
'
0px
'
,
xl
:
isCollapsed
?
'
0px
'
:
'
7px
'
}
}
>
<
NetworkMenuButton
isActive=
{
isOpen
}
/>
</
Box
>
</
PopoverTrigger
>
...
...
ui/snippets/searchBar/SearchBar.tsx
View file @
1ce2d44e
import
type
{
ChangeEvent
,
FormEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useLink
from
'
lib/link/useLink
'
;
import
SearchBarDesktop
from
'
./SearchBarDesktop
'
;
...
...
@@ -10,7 +9,6 @@ import SearchBarMobile from './SearchBarMobile';
const
SearchBar
=
()
=>
{
const
[
value
,
setValue
]
=
React
.
useState
(
''
);
const
link
=
useLink
();
const
isMobile
=
useIsMobile
();
const
handleChange
=
React
.
useCallback
((
event
:
ChangeEvent
<
HTMLInputElement
>
)
=>
{
setValue
(
event
.
target
.
value
);
...
...
@@ -22,14 +20,11 @@ const SearchBar = () => {
window
.
location
.
assign
(
url
);
},
[
link
,
value
]);
if
(
isMobile
)
{
return
(
<
SearchBarMobile
onChange=
{
handleChange
}
onSubmit=
{
handleSubmit
}
/>
);
}
return
(
<>
<
SearchBarDesktop
onChange=
{
handleChange
}
onSubmit=
{
handleSubmit
}
/>
<
SearchBarMobile
onChange=
{
handleChange
}
onSubmit=
{
handleSubmit
}
/>
</>
);
};
...
...
ui/snippets/searchBar/SearchBarDesktop.tsx
View file @
1ce2d44e
import
{
InputGroup
,
Input
,
InputLeftAddon
,
InputLeftElement
,
Icon
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
InputGroup
,
Input
,
InputLeftAddon
,
InputLeftElement
,
Icon
,
chakra
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
ChangeEvent
,
FormEvent
}
from
'
react
'
;
...
...
@@ -11,7 +11,7 @@ interface Props {
const
SearchBarDesktop
=
({
onChange
,
onSubmit
}:
Props
)
=>
{
return
(
<
form
noValidate
onSubmit=
{
onSubmit
}
>
<
chakra
.
form
noValidate
onSubmit=
{
onSubmit
}
display=
{
{
base
:
'
none
'
,
lg
:
'
block
'
}
}
w=
"100%"
>
<
InputGroup
>
<
InputLeftAddon
w=
"111px"
>
All filters
</
InputLeftAddon
>
<
InputLeftElement
w=
{
6
}
ml=
"132px"
mr=
{
2.5
}
>
...
...
@@ -25,7 +25,7 @@ const SearchBarDesktop = ({ onChange, onSubmit }: Props) => {
borderColor=
{
useColorModeValue
(
'
blackAlpha.100
'
,
'
whiteAlpha.200
'
)
}
/>
</
InputGroup
>
</
form
>
</
chakra
.
form
>
);
};
...
...
ui/snippets/searchBar/SearchBarMobile.tsx
View file @
1ce2d44e
...
...
@@ -61,6 +61,8 @@ const SearchBarMobile = ({ onChange, onSubmit }: Props) => {
transform=
{
isVisible
?
'
translateY(0)
'
:
'
translateY(-100%)
'
}
transitionProperty=
"transform"
transitionDuration=
"slow"
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
w=
"100%"
>
<
InputGroup
size=
"sm"
>
<
InputLeftElement
>
...
...
ui/tx/internals/TxInternalsFilter.tsx
View file @
1ce2d44e
...
...
@@ -3,7 +3,6 @@ import React from 'react';
import
type
{
TxInternalsType
}
from
'
types/api/tx
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
FilterButton
from
'
ui/shared/FilterButton
'
;
import
{
TX_INTERNALS_ITEMS
}
from
'
ui/tx/internals/utils
'
;
...
...
@@ -15,14 +14,12 @@ interface Props {
const
TxInternalsFilter
=
({
onFilterChange
,
defaultFilters
,
appliedFiltersNum
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
PopoverTrigger
>
<
FilterButton
isActive=
{
isOpen
||
Number
(
appliedFiltersNum
)
>
0
}
isCollapsed=
{
isMobile
}
onClick=
{
onToggle
}
appliedFiltersNum=
{
appliedFiltersNum
}
/>
...
...
ui/txs/TxsContent.tsx
View file @
1ce2d44e
import
{
Box
,
HStack
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
HStack
,
Show
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
,
useEffect
,
useState
}
from
'
react
'
;
import
type
{
Sort
}
from
'
types/client/txs-sort
'
;
import
{
txs
}
from
'
data/txs
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
FilterButton
from
'
ui/shared/FilterButton
'
;
import
FilterInput
from
'
ui/shared/FilterInput
'
;
import
Pagination
from
'
ui/shared/Pagination
'
;
...
...
@@ -18,8 +17,6 @@ type Props = {
}
const
TxsContent
=
({
isPending
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
[
sorting
,
setSorting
]
=
useState
<
Sort
>
();
const
[
sortedTxs
,
setSortedTxs
]
=
useState
(
txs
);
...
...
@@ -75,7 +72,6 @@ const TxsContent = ({ isPending }: Props) => {
{
/* TODO */
}
<
FilterButton
isActive=
{
false
}
isCollapsed=
{
isMobile
}
// eslint-disable-next-line react/jsx-no-bind
onClick=
{
()
=>
{}
}
appliedFiltersNum=
{
0
}
...
...
@@ -84,6 +80,7 @@ const TxsContent = ({ isPending }: Props) => {
// eslint-disable-next-line react/jsx-no-bind
handleSort=
{
()
=>
{}
}
isSortActive=
{
Boolean
(
sorting
)
}
display=
{
{
base
:
'
block
'
,
lg
:
'
none
'
}
}
/>
<
FilterInput
// eslint-disable-next-line react/jsx-no-bind
...
...
@@ -93,11 +90,10 @@ const TxsContent = ({ isPending }: Props) => {
placeholder=
"Search by addresses, hash, method..."
/>
</
HStack
>
{
isMobile
?
sortedTxs
.
map
(
tx
=>
<
TxsListItem
tx=
{
tx
}
key=
{
tx
.
hash
}
/>)
:
<
TxsTable
txs=
{
sortedTxs
}
sort=
{
sort
}
sorting=
{
sorting
}
/>
}
<
Show
below=
"lg"
>
{
sortedTxs
.
map
(
tx
=>
<
TxsListItem
tx=
{
tx
}
key=
{
tx
.
hash
}
/>)
}
</
Show
>
<
Show
above=
"lg"
><
TxsTable
txs=
{
sortedTxs
}
sort=
{
sort
}
sorting=
{
sorting
}
/></
Show
>
<
Box
mx=
{
{
base
:
0
,
lg
:
6
}
}
my=
{
{
base
:
6
,
lg
:
3
}
}
>
<
Pagination
currentPage=
{
1
}
isMobile=
{
isMobile
}
/>
<
Pagination
currentPage=
{
1
}
/>
</
Box
>
</>
);
...
...
ui/txs/TxsTableItem.tsx
View file @
1ce2d44e
...
...
@@ -13,8 +13,8 @@ import {
PopoverContent
,
PopoverBody
,
Portal
,
useBreakpointValue
,
useColorModeValue
,
Show
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
...
...
@@ -37,8 +37,6 @@ import TxType from './TxType';
const
TxsTableItem
=
({
tx
}:
{
tx
:
ArrayElement
<
typeof
txs
>
})
=>
{
const
link
=
useLink
();
const
isLargeScreen
=
useBreakpointValue
({
base
:
false
,
xl
:
true
});
const
addressFrom
=
(
<
Address
>
<
Tooltip
label=
{
tx
.
address_from
.
type
}
>
...
...
@@ -108,8 +106,7 @@ const TxsTableItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
<
Td
>
<
Link
href=
{
link
(
'
block
'
,
{
id
:
tx
.
block_num
.
toString
()
})
}
>
{
tx
.
block_num
}
</
Link
>
</
Td
>
{
isLargeScreen
?
(
<>
<
Show
above=
"xl"
>
<
Td
>
{
addressFrom
}
</
Td
>
...
...
@@ -119,8 +116,8 @@ const TxsTableItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
<
Td
>
{
addressTo
}
</
Td
>
</
>
)
:
(
</
Show
>
<
Show
below=
"xl"
>
<
Td
colSpan=
{
3
}
>
<
Box
>
{
addressFrom
}
...
...
@@ -135,7 +132,7 @@ const TxsTableItem = ({ tx }: {tx: ArrayElement<typeof txs>}) => {
{
addressTo
}
</
Box
>
</
Td
>
)
}
</
Show
>
<
Td
isNumeric
>
{
tx
.
amount
.
value
.
toFixed
(
8
)
}
</
Td
>
...
...
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