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
ce6b0349
Commit
ce6b0349
authored
Dec 27, 2022
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
markup changes
parent
3a2979aa
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
323 additions
and
187 deletions
+323
-187
SearchResults.tsx
ui/pages/SearchResults.tsx
+55
-65
SearchResultListItem.tsx
ui/searchResults/SearchResultListItem.tsx
+102
-0
SearchResultTableItem.tsx
ui/searchResults/SearchResultTableItem.tsx
+22
-19
ContentLoader.tsx
ui/shared/ContentLoader.tsx
+5
-2
SearchBar.tsx
ui/snippets/searchBar/SearchBar.tsx
+1
-1
SearchBarSuggest.tsx
ui/snippets/searchBar/SearchBarSuggest.tsx
+11
-33
SearchBarSuggestItem.tsx
ui/snippets/searchBar/SearchBarSuggestItem.tsx
+84
-24
useSearchQuery.tsx
ui/snippets/searchBar/useSearchQuery.tsx
+43
-43
No files found.
ui/pages/SearchResults.tsx
View file @
ce6b0349
import
{
Box
,
chakra
,
Table
,
Tbody
,
Tr
,
Th
,
Skeleton
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
chakra
,
Table
,
Tbody
,
Tr
,
Th
,
Skeleton
,
Show
,
Hide
}
from
'
@chakra-ui/react
'
;
import
type
{
FormEvent
}
from
'
react
'
;
import
type
{
FormEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
link
from
'
lib/link/link
'
;
import
link
from
'
lib/link/link
'
;
import
SearchResultListItem
from
'
ui/searchResults/SearchResultListItem
'
;
import
SearchResultTableItem
from
'
ui/searchResults/SearchResultTableItem
'
;
import
SearchResultTableItem
from
'
ui/searchResults/SearchResultTableItem
'
;
import
ActionBar
from
'
ui/shared/ActionBar
'
;
import
ActionBar
from
'
ui/shared/ActionBar
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
Page
from
'
ui/shared/Page/Page
'
;
import
Page
from
'
ui/shared/Page/Page
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
Pagination
from
'
ui/shared/Pagination
'
;
import
Pagination
from
'
ui/shared/Pagination
'
;
import
SkeletonList
from
'
ui/shared/skeletons/SkeletonList
'
;
import
SkeletonTable
from
'
ui/shared/skeletons/SkeletonTable
'
;
import
SkeletonTable
from
'
ui/shared/skeletons/SkeletonTable
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
Header
from
'
ui/snippets/header/Header
'
;
import
Header
from
'
ui/snippets/header/Header
'
;
import
SearchBarInput
from
'
ui/snippets/searchBar/SearchBarInput
'
;
import
SearchBarInput
from
'
ui/snippets/searchBar/SearchBarInput
'
;
import
useSearchQuery
from
'
ui/snippets/searchBar/useSearchQuery
'
;
import
useSearchQuery
from
'
ui/snippets/searchBar/useSearchQuery
'
;
// const data = {
// items: [
// {
// address: '0x377c5F2B300B25a534d4639177873b7fEAA56d4B',
// address_url: '/address/0x377c5F2B300B25a534d4639177873b7fEAA56d4B',
// name: 'Toms NFT',
// symbol: 'TNT',
// token_url: '/token/0x377c5F2B300B25a534d4639177873b7fEAA56d4B',
// type: 'token' as const,
// },
// {
// address: '0xC35Cc7223B0175245E9964f2E3119c261E8e21F9',
// address_url: '/address/0xC35Cc7223B0175245E9964f2E3119c261E8e21F9',
// name: 'TomToken',
// symbol: 'pdE1B',
// token_url: '/token/0xC35Cc7223B0175245E9964f2E3119c261E8e21F9',
// type: 'token' as const,
// },
// {
// block_hash: '0x1af31d7535dded06bab9a88eb40ee2f8d0529a60ab3b8a7be2ba69b008cacbd1',
// block_number: 8198536,
// type: 'block' as const,
// url: '/block/0x1af31d7535dded06bab9a88eb40ee2f8d0529a60ab3b8a7be2ba69b008cacbd1',
// },
// {
// address: '0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a',
// name: null,
// type: 'address' as const,
// url: '/address/0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a',
// },
// {
// address: '0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a',
// name: 'TomToken',
// type: 'contract' as const,
// url: '/address/0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a',
// },
// {
// tx_hash: '0x349d4025d03c6faec117ee10ac0bce7c7a805dd2cbff7a9f101304d9a8a525dd',
// type: 'transaction' as const,
// url: '/tx/0x349d4025d03c6faec117ee10ac0bce7c7a805dd2cbff7a9f101304d9a8a525dd',
// },
// ],
// next_page_params: null,
// };
const
SearchResultsPageContent
=
()
=>
{
const
SearchResultsPageContent
=
()
=>
{
const
{
query
,
searchTerm
,
handleSearchTermChange
}
=
useSearchQuery
(
true
);
const
{
query
,
searchTerm
,
handleSearchTermChange
}
=
useSearchQuery
(
true
);
const
{
data
,
isError
,
isLoading
,
pagination
,
isPaginationVisible
}
=
query
;
const
{
data
,
isError
,
isLoading
,
pagination
,
isPaginationVisible
}
=
query
;
const
isMobile
=
useIsMobile
();
const
handleSubmit
=
React
.
useCallback
((
event
:
FormEvent
<
HTMLFormElement
>
)
=>
{
const
handleSubmit
=
React
.
useCallback
((
event
:
FormEvent
<
HTMLFormElement
>
)
=>
{
event
.
preventDefault
();
event
.
preventDefault
();
...
@@ -81,7 +40,12 @@ const SearchResultsPageContent = () => {
...
@@ -81,7 +40,12 @@ const SearchResultsPageContent = () => {
return
(
return
(
<
Box
>
<
Box
>
<
Skeleton
h=
{
6
}
w=
"280px"
borderRadius=
"full"
mb=
{
6
}
/>
<
Skeleton
h=
{
6
}
w=
"280px"
borderRadius=
"full"
mb=
{
6
}
/>
<
SkeletonTable
columns=
{
[
'
33%
'
,
'
34%
'
,
'
33%
'
]
}
/>
<
Show
below=
"lg"
ssr=
{
false
}
>
<
SkeletonList
/>
</
Show
>
<
Hide
below=
"lg"
ssr=
{
false
}
>
<
SkeletonTable
columns=
{
[
'
33%
'
,
'
34%
'
,
'
33%
'
]
}
/>
</
Hide
>
</
Box
>
</
Box
>
);
);
}
}
...
@@ -96,27 +60,53 @@ const SearchResultsPageContent = () => {
...
@@ -96,27 +60,53 @@ const SearchResultsPageContent = () => {
</
Box
>
</
Box
>
);
);
const
bar
=
(()
=>
{
if
(
!
isPaginationVisible
)
{
return
text
;
}
if
(
isMobile
)
{
return
(
<>
{
text
}
<
ActionBar
>
<
Pagination
{
...
pagination
}
ml=
"auto"
/>
</
ActionBar
>
</>
);
}
return
(
<
ActionBar
mt=
{
-
6
}
>
{
text
}
<
Pagination
{
...
pagination
}
/>
</
ActionBar
>
);
})();
return
(
return
(
<>
<>
{
isPaginationVisible
?
(
{
bar
}
<
ActionBar
mt=
{
-
6
}
>
{
text
}
<
Pagination
{
...
pagination
}
/>
</
ActionBar
>
)
:
text
}
{
data
.
items
.
length
>
0
&&
(
{
data
.
items
.
length
>
0
&&
(
<
Table
variant=
"simple"
size=
"md"
fontWeight=
{
500
}
>
<>
<
Thead
top=
{
isPaginationVisible
?
80
:
0
}
>
<
Show
below=
"lg"
ssr=
{
false
}
>
<
Tr
>
{
data
.
items
.
map
((
item
,
index
)
=>
<
SearchResultListItem
key=
{
index
}
data=
{
item
}
/>)
}
<
Th
width=
"33%"
>
Search Result
</
Th
>
</
Show
>
<
Th
width=
"34%"
>
Hash/address
</
Th
>
<
Hide
below=
"lg"
ssr=
{
false
}
>
<
Th
width=
"33%"
>
Category
</
Th
>
<
Table
variant=
"simple"
size=
"md"
fontWeight=
{
500
}
>
</
Tr
>
<
Thead
top=
{
isPaginationVisible
?
80
:
0
}
>
</
Thead
>
<
Tr
>
<
Tbody
>
<
Th
width=
"50%"
>
Search Result
</
Th
>
{
data
.
items
.
map
((
item
,
index
)
=>
<
SearchResultTableItem
key=
{
index
}
data=
{
item
}
/>)
}
<
Th
width=
"50%"
/>
</
Tbody
>
<
Th
width=
"150px"
>
Category
</
Th
>
</
Table
>
</
Tr
>
</
Thead
>
<
Tbody
>
{
data
.
items
.
map
((
item
,
index
)
=>
<
SearchResultTableItem
key=
{
index
}
data=
{
item
}
/>)
}
</
Tbody
>
</
Table
>
</
Hide
>
</>
)
}
)
}
</>
</>
);
);
...
...
ui/searchResults/SearchResultListItem.tsx
0 → 100644
View file @
ce6b0349
import
{
Text
,
Link
,
Flex
,
Icon
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
SearchResultItem
}
from
'
types/api/search
'
;
import
blockIcon
from
'
icons/block.svg
'
;
import
txIcon
from
'
icons/transactions.svg
'
;
import
link
from
'
lib/link/link
'
;
import
Address
from
'
ui/shared/address/Address
'
;
import
AddressIcon
from
'
ui/shared/address/AddressIcon
'
;
import
AddressLink
from
'
ui/shared/address/AddressLink
'
;
import
HashStringShortenDynamic
from
'
ui/shared/HashStringShortenDynamic
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile
'
;
import
TokenLogo
from
'
ui/shared/TokenLogo
'
;
interface
Props
{
data
:
SearchResultItem
;
}
const
SearchResultListItem
=
({
data
}:
Props
)
=>
{
const
firstRow
=
(()
=>
{
switch
(
data
.
type
)
{
case
'
token
'
:
{
return
(
<
Flex
alignItems=
"center"
>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
/>
<
Link
ml=
{
2
}
href=
{
link
(
'
token_index
'
,
{
hash
:
data
.
address
})
}
fontWeight=
{
700
}
>
{
data
.
name
}{
data
.
symbol
?
` (${ data.symbol })`
:
''
}
</
Link
>
</
Flex
>
);
}
case
'
contract
'
:
case
'
address
'
:
{
return
(
<
Address
>
<
AddressIcon
hash=
{
data
.
address
}
/>
<
AddressLink
hash=
{
data
.
address
}
ml=
{
2
}
fontWeight=
{
700
}
/>
</
Address
>
);
}
case
'
block
'
:
{
return
(
<
Flex
alignItems=
"center"
>
<
Icon
as=
{
blockIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
<
Link
fontWeight=
{
700
}
href=
{
link
(
'
block
'
,
{
id
:
String
(
data
.
block_number
)
})
}
>
{
data
.
block_number
}
</
Link
>
</
Flex
>
);
}
case
'
transaction
'
:
{
return
(
<
Flex
alignItems=
"center"
overflow=
"hidden"
>
<
Icon
as=
{
txIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
<
Address
>
<
AddressLink
hash=
{
data
.
tx_hash
}
type=
"transaction"
fontWeight=
{
700
}
/>
</
Address
>
</
Flex
>
);
}
}
})();
const
secondRow
=
(()
=>
{
switch
(
data
.
type
)
{
case
'
token
'
:
{
return
(
<
HashStringShortenDynamic
hash=
{
data
.
address
}
/>
);
}
case
'
block
'
:
{
return
(
<
HashStringShortenDynamic
hash=
{
data
.
block_hash
}
/>
);
}
case
'
contract
'
:
case
'
address
'
:
{
return
data
.
name
?
<
Text
>
{
data
.
name
}
</
Text
>
:
null
;
}
default
:
return
null
;
}
})();
return
(
<
ListItemMobile
py=
{
3
}
fontSize=
"sm"
rowGap=
{
2
}
>
<
Flex
justifyContent=
"space-between"
w=
"100%"
overflow=
"hidden"
>
{
firstRow
}
<
Text
variant=
"secondary"
ml=
{
8
}
textTransform=
"capitalize"
>
{
data
.
type
}
</
Text
>
</
Flex
>
{
secondRow
}
</
ListItemMobile
>
);
};
export
default
SearchResultListItem
;
ui/searchResults/SearchResultTableItem.tsx
View file @
ce6b0349
import
{
Tr
,
Td
,
Text
,
Link
,
Flex
,
Icon
}
from
'
@chakra-ui/react
'
;
import
{
Tr
,
Td
,
Text
,
Link
,
Flex
,
Icon
,
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SearchResultItem
}
from
'
types/api/search
'
;
import
type
{
SearchResultItem
}
from
'
types/api/search
'
;
...
@@ -26,16 +26,17 @@ const SearchResultTableItem = ({ data }: Props) => {
...
@@ -26,16 +26,17 @@ const SearchResultTableItem = ({ data }: Props) => {
<
Td
fontSize=
"sm"
>
<
Td
fontSize=
"sm"
>
<
Flex
alignItems=
"center"
>
<
Flex
alignItems=
"center"
>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
/>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
/>
<
Text
fontWeight=
{
700
}
ml=
{
2
}
>
<
Link
ml=
{
2
}
href=
{
link
(
'
token_index
'
,
{
hash
:
data
.
address
})
}
fontWeight=
{
700
}
>
<
span
>
{
data
.
name
}
</
span
>
<
span
>
{
data
.
symbol
&&
<
span
>
(
{
data
.
symbol
}
)
</
span
>
}
{
data
.
name
}{
data
.
symbol
?
` (${ data.symbol })`
:
''
}
</
Text
>
</
span
>
</
Link
>
</
Flex
>
</
Flex
>
</
Td
>
</
Td
>
<
Td
fontSize=
"sm"
verticalAlign=
"middle"
>
<
Td
fontSize=
"sm"
verticalAlign=
"middle"
>
<
Address
>
<
Box
whiteSpace=
"nowrap"
overflow=
"hidden"
>
<
AddressLink
hash=
{
data
.
address
}
type=
"token"
/>
<
HashStringShortenDynamic
hash=
{
data
.
address
}
/>
</
Address
>
</
Box
>
</
Td
>
</
Td
>
</>
</>
);
);
...
@@ -49,13 +50,11 @@ const SearchResultTableItem = ({ data }: Props) => {
...
@@ -49,13 +50,11 @@ const SearchResultTableItem = ({ data }: Props) => {
<
Td
fontSize=
"sm"
>
<
Td
fontSize=
"sm"
>
<
Address
>
<
Address
>
<
AddressIcon
hash=
{
data
.
address
}
/>
<
AddressIcon
hash=
{
data
.
address
}
/>
<
Text
fontWeight=
{
700
}
ml=
{
2
}
>
{
data
.
name
}
</
Text
>
<
AddressLink
fontWeight=
{
700
}
ml=
{
2
}
hash=
{
data
.
address
}
/
>
</
Address
>
</
Address
>
</
Td
>
</
Td
>
<
Td
fontSize=
"sm"
verticalAlign=
"middle"
>
<
Td
fontSize=
"sm"
verticalAlign=
"middle"
>
<
Address
>
{
data
.
name
}
<
AddressLink
hash=
{
data
.
address
}
type=
"address"
/>
</
Address
>
</
Td
>
</
Td
>
</>
</>
);
);
...
@@ -65,7 +64,7 @@ const SearchResultTableItem = ({ data }: Props) => {
...
@@ -65,7 +64,7 @@ const SearchResultTableItem = ({ data }: Props) => {
<
Td
colSpan=
{
2
}
fontSize=
"sm"
>
<
Td
colSpan=
{
2
}
fontSize=
"sm"
>
<
Address
>
<
Address
>
<
AddressIcon
hash=
{
data
.
address
}
/>
<
AddressIcon
hash=
{
data
.
address
}
/>
<
AddressLink
hash=
{
data
.
address
}
ml=
{
2
}
type=
"address"
/>
<
AddressLink
hash=
{
data
.
address
}
ml=
{
2
}
type=
"address"
fontWeight=
{
700
}
/>
</
Address
>
</
Address
>
</
Td
>
</
Td
>
);
);
...
@@ -77,15 +76,15 @@ const SearchResultTableItem = ({ data }: Props) => {
...
@@ -77,15 +76,15 @@ const SearchResultTableItem = ({ data }: Props) => {
<
Td
fontSize=
"sm"
>
<
Td
fontSize=
"sm"
>
<
Flex
alignItems=
"center"
>
<
Flex
alignItems=
"center"
>
<
Icon
as=
{
blockIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
<
Icon
as=
{
blockIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
<
Text
fontWeight=
{
700
}
>
<
Link
fontWeight=
{
700
}
href=
{
link
(
'
block
'
,
{
id
:
String
(
data
.
block_number
)
})
}
>
{
data
.
block_number
}
{
data
.
block_number
}
</
Text
>
</
Link
>
</
Flex
>
</
Flex
>
</
Td
>
</
Td
>
<
Td
fontSize=
"sm"
verticalAlign=
"middle"
>
<
Td
fontSize=
"sm"
verticalAlign=
"middle"
>
<
Link
overflow=
"hidden"
whiteSpace=
"nowrap"
display=
"block"
href=
{
link
(
'
block
'
,
{
id
:
String
(
data
.
block_number
)
})
}
>
<
Box
overflow=
"hidden"
whiteSpace=
"nowrap"
>
<
HashStringShortenDynamic
hash=
{
data
.
block_hash
}
/>
<
HashStringShortenDynamic
hash=
{
data
.
block_hash
}
/>
</
Link
>
</
Box
>
</
Td
>
</
Td
>
</>
</>
);
);
...
@@ -97,7 +96,7 @@ const SearchResultTableItem = ({ data }: Props) => {
...
@@ -97,7 +96,7 @@ const SearchResultTableItem = ({ data }: Props) => {
<
Flex
alignItems=
"center"
>
<
Flex
alignItems=
"center"
>
<
Icon
as=
{
txIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
<
Icon
as=
{
txIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
<
Address
>
<
Address
>
<
AddressLink
hash=
{
data
.
tx_hash
}
type=
"transaction"
/>
<
AddressLink
hash=
{
data
.
tx_hash
}
type=
"transaction"
fontWeight=
{
700
}
/>
</
Address
>
</
Address
>
</
Flex
>
</
Flex
>
</
Td
>
</
Td
>
...
@@ -109,7 +108,11 @@ const SearchResultTableItem = ({ data }: Props) => {
...
@@ -109,7 +108,11 @@ const SearchResultTableItem = ({ data }: Props) => {
return
(
return
(
<
Tr
>
<
Tr
>
{
content
}
{
content
}
<
Td
fontSize=
"sm"
textTransform=
"capitalize"
verticalAlign=
"middle"
>
{
data
.
type
}
</
Td
>
<
Td
fontSize=
"sm"
textTransform=
"capitalize"
verticalAlign=
"middle"
>
<
Text
variant=
"secondary"
>
{
data
.
type
}
</
Text
>
</
Td
>
</
Tr
>
</
Tr
>
);
);
};
};
...
...
ui/shared/ContentLoader.tsx
View file @
ce6b0349
...
@@ -9,9 +9,10 @@ const runnerAnimation = keyframes`
...
@@ -9,9 +9,10 @@ const runnerAnimation = keyframes`
interface
Props
{
interface
Props
{
className
?:
string
;
className
?:
string
;
text
?:
string
;
}
}
const
ContentLoader
=
({
className
}:
Props
)
=>
{
const
ContentLoader
=
({
className
,
text
}:
Props
)
=>
{
return
(
return
(
<
Box
display=
"inline-block"
className=
{
className
}
>
<
Box
display=
"inline-block"
className=
{
className
}
>
<
Box
<
Box
...
@@ -30,7 +31,9 @@ const ContentLoader = ({ className }: Props) => {
...
@@ -30,7 +31,9 @@ const ContentLoader = ({ className }: Props) => {
borderRadius
:
'
full
'
,
borderRadius
:
'
full
'
,
}
}
}
}
/>
/>
<
Text
mt=
{
6
}
variant=
"secondary"
>
Loading data, please wait...
</
Text
>
<
Text
mt=
{
6
}
variant=
"secondary"
>
{
text
||
'
Loading data, please wait...
'
}
</
Text
>
</
Box
>
</
Box
>
);
);
};
};
...
...
ui/snippets/searchBar/SearchBar.tsx
View file @
ce6b0349
...
@@ -76,7 +76,7 @@ const SearchBar = ({ isHomepage, withShadow }: Props) => {
...
@@ -76,7 +76,7 @@ const SearchBar = ({ isHomepage, withShadow }: Props) => {
/>
/>
</
PopoverTrigger
>
</
PopoverTrigger
>
<
PopoverContent
w=
{
`${ menuWidth.current }px`
}
maxH=
{
{
base
:
'
300px
'
,
lg
:
'
500px
'
}
}
overflowY=
"scroll"
ref=
{
menuRef
}
>
<
PopoverContent
w=
{
`${ menuWidth.current }px`
}
maxH=
{
{
base
:
'
300px
'
,
lg
:
'
500px
'
}
}
overflowY=
"scroll"
ref=
{
menuRef
}
>
<
PopoverBody
display=
"flex"
flexDirection=
"column"
rowGap=
"6"
>
<
PopoverBody
py=
{
6
}
>
<
SearchBarSuggest
query=
{
query
}
/>
<
SearchBarSuggest
query=
{
query
}
/>
</
PopoverBody
>
</
PopoverBody
>
</
PopoverContent
>
</
PopoverContent
>
...
...
ui/snippets/searchBar/SearchBarSuggest.tsx
View file @
ce6b0349
import
{
Box
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Text
}
from
'
@chakra-ui/react
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
_groupBy
from
'
lodash/groupBy
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SearchResult
,
SearchResultType
}
from
'
types/api/search
'
;
import
type
{
SearchResult
}
from
'
types/api/search
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
import
SearchBarSuggestItem
from
'
./SearchBarSuggestItem
'
;
import
SearchBarSuggestItem
from
'
./SearchBarSuggestItem
'
;
...
@@ -13,25 +13,12 @@ interface Props {
...
@@ -13,25 +13,12 @@ interface Props {
query
:
UseQueryResult
<
SearchResult
>
;
query
:
UseQueryResult
<
SearchResult
>
;
}
}
interface
Group
{
type
:
SearchResultType
;
title
:
string
;
}
const
GROUPS
:
Array
<
Group
>
=
[
{
type
:
'
block
'
,
title
:
'
Blocks
'
},
{
type
:
'
token
'
,
title
:
'
Tokens
'
},
{
type
:
'
address
'
,
title
:
'
Address
'
},
{
type
:
'
transaction
'
,
title
:
'
Transactions
'
},
{
type
:
'
contract
'
,
title
:
'
Contracts
'
},
];
const
SearchBarSuggest
=
({
query
}:
Props
)
=>
{
const
SearchBarSuggest
=
({
query
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
groupedData
=
_groupBy
(
query
.
data
?.
items
||
[],
'
type
'
);
const
content
=
(()
=>
{
const
content
=
(()
=>
{
if
(
query
.
isLoading
)
{
if
(
query
.
isLoading
)
{
return
<
ContentLoader
text=
"We are searching, please wait... "
/>;
return
<
Box
>
loading...
</
Box
>;
return
<
Box
>
loading...
</
Box
>;
}
}
...
@@ -39,26 +26,17 @@ const SearchBarSuggest = ({ query }: Props) => {
...
@@ -39,26 +26,17 @@ const SearchBarSuggest = ({ query }: Props) => {
return
<
Box
>
Something went wrong. Try refreshing the page or come back later.
</
Box
>;
return
<
Box
>
Something went wrong. Try refreshing the page or come back later.
</
Box
>;
}
}
if
(
query
.
data
.
items
.
length
===
0
)
{
const
num
=
query
.
data
.
next_page_params
?
'
50+
'
:
query
.
data
.
items
.
length
;
return
<
Box
fontWeight=
{
500
}
>
Found
<
Text
fontWeight=
{
700
}
as=
"span"
>
0
</
Text
>
matching results
</
Box
>;
}
return
Object
.
entries
(
groupedData
).
map
(([
group
,
data
])
=>
{
return
(
const
groupName
=
GROUPS
.
find
(({
type
})
=>
type
===
group
)?.
title
;
<>
return
(
<
Box
fontWeight=
{
500
}
fontSize=
"sm"
>
Found
<
Text
fontWeight=
{
700
}
as=
"span"
>
{
num
}
</
Text
>
matching results
</
Box
>
<
Box
key=
{
group
}
>
{
query
.
data
.
items
.
map
((
item
,
index
)
=>
<
SearchBarSuggestItem
key=
{
index
}
data=
{
item
}
isMobile=
{
isMobile
}
/>)
}
<
Text
variant=
"secondary"
fontSize=
"sm"
fontWeight=
{
600
}
mb=
{
3
}
>
{
groupName
}
(
{
data
.
length
}
)
</
Text
>
</>
{
data
.
map
((
item
,
index
)
=>
<
SearchBarSuggestItem
key=
{
index
}
data=
{
item
}
isMobile=
{
isMobile
}
/>)
}
);
</
Box
>
);
});
})();
})();
return
(
return
content
;
<
Box
>
{
content
}
</
Box
>
);
};
};
export
default
SearchBarSuggest
;
export
default
SearchBarSuggest
;
ui/snippets/searchBar/SearchBarSuggestItem.tsx
View file @
ce6b0349
import
{
chakra
,
Text
,
Flex
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
Text
,
Flex
,
useColorModeValue
,
Icon
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SearchResultItem
}
from
'
types/api/search
'
;
import
type
{
SearchResultItem
}
from
'
types/api/search
'
;
import
blockIcon
from
'
icons/block.svg
'
;
import
txIcon
from
'
icons/transactions.svg
'
;
import
link
from
'
lib/link/link
'
;
import
link
from
'
lib/link/link
'
;
import
Address
from
'
ui/shared/address/Address
'
;
import
AddressIcon
from
'
ui/shared/address/AddressIcon
'
;
import
AddressIcon
from
'
ui/shared/address/AddressIcon
'
;
import
HashStringShorten
from
'
ui/shared/HashStringShorten
'
;
import
HashStringShorten
Dynamic
from
'
ui/shared/HashStringShortenDynamic
'
;
import
TokenLogo
from
'
ui/shared/TokenLogo
'
;
import
TokenLogo
from
'
ui/shared/TokenLogo
'
;
interface
Props
{
interface
Props
{
...
@@ -34,47 +35,98 @@ const SearchBarSuggestItem = ({ data, isMobile }: Props) => {
...
@@ -34,47 +35,98 @@ const SearchBarSuggestItem = ({ data, isMobile }: Props) => {
}
}
})();
})();
const
content
=
(()
=>
{
const
firstRow
=
(()
=>
{
switch
(
data
.
type
)
{
switch
(
data
.
type
)
{
case
'
token
'
:
{
case
'
token
'
:
{
return
(
return
(
<>
<>
<
Flex
>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
flexShrink=
{
0
}
/>
<
TokenLogo
boxSize=
{
6
}
hash=
{
data
.
address
}
name=
{
data
.
name
}
/>
<
Text
fontWeight=
{
700
}
ml=
{
2
}
w=
"200px"
overflow=
"hidden"
whiteSpace=
"nowrap"
textOverflow=
"ellipsis"
flexShrink=
{
0
}
>
<
Text
fontWeight=
{
700
}
ml=
{
2
}
>
<
span
>
{
data
.
name
}
</
span
>
<
span
>
{
data
.
name
}
</
span
>
{
data
.
symbol
&&
<
span
>
(
{
data
.
symbol
}
)
</
span
>
}
{
data
.
symbol
&&
<
span
>
(
{
data
.
symbol
}
)
</
span
>
}
</
Text
>
</
Flex
>
<
Text
variant=
"secondary"
mt=
{
2
}
overflow=
"hidden"
whiteSpace=
"nowrap"
>
{
isMobile
?
<
HashStringShorten
hash=
{
data
.
address
}
isTooltipDisabled
/>
:
data
.
address
}
</
Text
>
</
Text
>
{
!
isMobile
&&
(
<
Text
overflow=
"hidden"
whiteSpace=
"nowrap"
ml=
{
2
}
variant=
"secondary"
>
<
HashStringShortenDynamic
hash=
{
data
.
address
}
isTooltipDisabled
/>
</
Text
>
)
}
</>
</>
);
);
}
}
case
'
contract
'
:
case
'
contract
'
:
case
'
address
'
:
{
case
'
address
'
:
{
return
(
return
(
<
Address
>
<>
<
AddressIcon
hash=
{
data
.
address
}
/>
<
AddressIcon
hash=
{
data
.
address
}
mr=
{
2
}
/>
<
Text
fontWeight=
{
700
}
ml=
{
2
}
>
{
data
.
name
||
data
.
address
}
</
Text
>
<
chakra
.
span
overflow=
"hidden"
whiteSpace=
"nowrap"
fontWeight=
{
700
}
>
</
Address
>
<
HashStringShortenDynamic
hash=
{
data
.
address
}
isTooltipDisabled
/>
</
chakra
.
span
>
{
!
isMobile
&&
(
<
Text
variant=
"secondary"
ml=
{
2
}
>
{
data
.
name
}
</
Text
>
)
}
</>
);
);
}
}
case
'
block
'
:
{
case
'
block
'
:
{
return
(
return
(
<
Text
>
<>
{
data
.
block_number
}
<
Icon
as=
{
blockIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
</
Text
>
<
chakra
.
span
fontWeight=
{
700
}
>
{
data
.
block_number
}
</
chakra
.
span
>
{
!
isMobile
&&
(
<
Text
variant=
"secondary"
overflow=
"hidden"
whiteSpace=
"nowrap"
ml=
{
2
}
>
<
HashStringShortenDynamic
hash=
{
data
.
block_hash
}
isTooltipDisabled
/>
</
Text
>
)
}
</>
);
);
}
}
case
'
transaction
'
:
{
case
'
transaction
'
:
{
return
(
return
(
<
Text
>
<
>
{
data
.
tx_hash
}
<
Icon
as=
{
txIcon
}
boxSize=
{
6
}
mr=
{
2
}
color=
"gray.500"
/>
<
chakra
.
span
overflow=
"hidden"
whiteSpace=
"nowrap"
fontWeight=
{
700
}
>
<
HashStringShortenDynamic
hash=
{
data
.
tx_hash
}
isTooltipDisabled
/>
</
chakra
.
span
>
</>
);
}
}
})();
const
secondRow
=
(()
=>
{
if
(
!
isMobile
)
{
return
null
;
}
switch
(
data
.
type
)
{
case
'
token
'
:
{
return
(
<
Text
variant=
"secondary"
whiteSpace=
"nowrap"
overflow=
"hidden"
>
<
HashStringShortenDynamic
hash=
{
data
.
address
}
isTooltipDisabled
/>
</
Text
>
</
Text
>
);
);
}
}
case
'
block
'
:
{
return
(
<
Text
variant=
"secondary"
whiteSpace=
"nowrap"
overflow=
"hidden"
>
<
HashStringShortenDynamic
hash=
{
data
.
block_hash
}
isTooltipDisabled
/>
</
Text
>
);
}
case
'
contract
'
:
case
'
address
'
:
{
return
(
<
Text
variant=
"secondary"
whiteSpace=
"nowrap"
overflow=
"hidden"
>
{
data
.
name
}
</
Text
>
);
}
default
:
{
return
null
;
}
}
}
})();
})();
...
@@ -82,7 +134,9 @@ const SearchBarSuggestItem = ({ data, isMobile }: Props) => {
...
@@ -82,7 +134,9 @@ const SearchBarSuggestItem = ({ data, isMobile }: Props) => {
<
chakra
.
a
<
chakra
.
a
py=
{
3
}
py=
{
3
}
px=
{
1
}
px=
{
1
}
display=
"block"
display=
"flex"
flexDir=
"column"
rowGap=
{
2
}
borderColor=
{
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
)
}
borderColor=
{
useColorModeValue
(
'
blackAlpha.200
'
,
'
whiteAlpha.200
'
)
}
borderBottomWidth=
"1px"
borderBottomWidth=
"1px"
_last=
{
{
_last=
{
{
...
@@ -93,8 +147,14 @@ const SearchBarSuggestItem = ({ data, isMobile }: Props) => {
...
@@ -93,8 +147,14 @@ const SearchBarSuggestItem = ({ data, isMobile }: Props) => {
}
}
}
}
fontSize=
"sm"
fontSize=
"sm"
href=
{
url
}
href=
{
url
}
_first=
{
{
mt
:
2
,
}
}
>
>
{
content
}
<
Flex
display=
"flex"
alignItems=
"center"
>
{
firstRow
}
</
Flex
>
{
secondRow
}
</
chakra
.
a
>
</
chakra
.
a
>
);
);
};
};
...
...
ui/snippets/searchBar/useSearchQuery.tsx
View file @
ce6b0349
...
@@ -6,49 +6,49 @@ import useDebounce from 'lib/hooks/useDebounce';
...
@@ -6,49 +6,49 @@ import useDebounce from 'lib/hooks/useDebounce';
import
useQueryWithPages
from
'
lib/hooks/useQueryWithPages
'
;
import
useQueryWithPages
from
'
lib/hooks/useQueryWithPages
'
;
import
useUpdateValueEffect
from
'
lib/hooks/useUpdateValueEffect
'
;
import
useUpdateValueEffect
from
'
lib/hooks/useUpdateValueEffect
'
;
// const data =
[
// const data =
{
//
{
//
items: [
//
address: '0x377c5F2B300B25a534d4639177873b7fEAA56d4B',
//
{
//
address_url: '/address/
0x377c5F2B300B25a534d4639177873b7fEAA56d4B',
//
address: '
0x377c5F2B300B25a534d4639177873b7fEAA56d4B',
//
name: 'Toms NFT
',
//
address_url: '/address/0x377c5F2B300B25a534d4639177873b7fEAA56d4B
',
//
symbol: 'TN
T',
//
name: 'Toms NF
T',
//
token_url: '/token/0x377c5F2B300B25a534d4639177873b7fEAA56d4B
',
//
symbol: 'TNT
',
//
type: 'token' as const
,
//
token_url: '/token/0x377c5F2B300B25a534d4639177873b7fEAA56d4B'
,
//
}
,
//
type: 'token' as const
,
//
{
//
},
//
address: '0xC35Cc7223B0175245E9964f2E3119c261E8e21F9',
//
{
//
address_url: '/address/
0xC35Cc7223B0175245E9964f2E3119c261E8e21F9',
//
address: '
0xC35Cc7223B0175245E9964f2E3119c261E8e21F9',
//
name: 'TomToken
',
//
address_url: '/address/0xC35Cc7223B0175245E9964f2E3119c261E8e21F9
',
//
symbol: 'pdE1B
',
//
name: 'TomToken
',
//
token_url: '/token/0xC35Cc7223B0175245E9964f2E3119c261E8e21F9
',
//
symbol: 'pdE1B
',
//
type: 'token' as const
,
//
token_url: '/token/0xC35Cc7223B0175245E9964f2E3119c261E8e21F9'
,
//
}
,
//
type: 'token' as const
,
//
{
//
},
//
address: '0xC35Cc7223B0175245E9964f2E3119c261E8e21F9',
//
{
//
address_url: '/address/0xC35Cc7223B0175245E9964f2E3119c261E8e21F9
',
//
block_hash: '0x1af31d7535dded06bab9a88eb40ee2f8d0529a60ab3b8a7be2ba69b008cacbd1
',
//
name: 'TomToken'
,
//
block_number: 8198536
,
//
symbol: 'pdE1B'
,
//
type: 'block' as const
,
//
token_url: '/token/0xC35Cc7223B0175245E9964f2E3119c261E8e21F9
',
//
url: '/block/0x1af31d7535dded06bab9a88eb40ee2f8d0529a60ab3b8a7be2ba69b008cacbd1
',
//
type: 'token' as const
,
//
}
,
//
},
//
{
//
{
//
address: '0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a',
//
block_hash: '0x1af31d7535dded06bab9a88eb40ee2f8d0529a60ab3b8a7be2ba69b008cacbd1'
,
//
name: null
,
//
block_number: 8198536
,
//
type: 'address' as const
,
//
type: 'block' as const
,
//
url: '/address/0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a'
,
//
url: '/block/0x1af31d7535dded06bab9a88eb40ee2f8d0529a60ab3b8a7be2ba69b008cacbd1'
,
//
}
,
//
},
//
{
//
{
//
address: '0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a',
//
address: '0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a
',
//
name: 'Unkown
',
//
name: null
,
//
type: 'contract' as const
,
//
type: 'address' as const
,
//
url: '/address/0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a'
,
//
url: '/address/0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a'
,
//
}
,
//
},
//
{
//
{
//
tx_hash: '0x349d4025d03c6faec117ee10ac0bce7c7a805dd2cbff7a9f101304d9a8a525dd',
//
tx_hash: '0x349d4025d03c6faec117ee10ac0bce7c7a805dd2cbff7a9f101304d9a8a525dd'
,
//
type: 'transaction' as const
,
//
type: 'transaction' as const
,
//
url: '/tx/0x349d4025d03c6faec117ee10ac0bce7c7a805dd2cbff7a9f101304d9a8a525dd'
,
//
url: '/tx/0x349d4025d03c6faec117ee10ac0bce7c7a805dd2cbff7a9f101304d9a8a525dd'
,
//
}
,
//
}
,
//
]
,
//
]
;
//
}
;
export
default
function
useSearchQuery
(
isSearchPage
=
false
)
{
export
default
function
useSearchQuery
(
isSearchPage
=
false
)
{
const
router
=
useRouter
();
const
router
=
useRouter
();
...
...
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