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
89b91fc2
Commit
89b91fc2
authored
Mar 14, 2024
by
Max Alekseenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
create contract list modal
parent
37f66880
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
191 additions
and
13 deletions
+191
-13
marketplace.ts
types/client/marketplace.ts
+6
-0
ContractListModal.tsx
ui/marketplace/ContractListModal.tsx
+71
-0
ContractSecurityReport.tsx
ui/marketplace/ContractSecurityReport.tsx
+47
-0
MarketplaceListWithScores.tsx
ui/marketplace/MarketplaceListWithScores.tsx
+5
-1
AppSecurityReport.tsx
...rketplace/MarketplaceListWithScores/AppSecurityReport.tsx
+12
-4
ListItem.tsx
ui/marketplace/MarketplaceListWithScores/ListItem.tsx
+4
-3
Table.tsx
ui/marketplace/MarketplaceListWithScores/Table.tsx
+4
-2
TableItem.tsx
ui/marketplace/MarketplaceListWithScores/TableItem.tsx
+14
-3
useMarketplace.tsx
ui/marketplace/useMarketplace.tsx
+12
-0
Marketplace.tsx
ui/pages/Marketplace.tsx
+16
-0
No files found.
types/client/marketplace.ts
View file @
89b91fc2
...
@@ -28,3 +28,9 @@ export enum MarketplaceCategory {
...
@@ -28,3 +28,9 @@ export enum MarketplaceCategory {
ALL
=
'
All
'
,
ALL
=
'
All
'
,
FAVORITES
=
'
Favorites
'
,
FAVORITES
=
'
Favorites
'
,
}
}
export
enum
ContractListTypes
{
ANALYZED
=
'
Analyzed
'
,
ALL
=
'
All
'
,
VERIFIED
=
'
Verified
'
,
}
ui/marketplace/ContractListModal.tsx
0 → 100644
View file @
89b91fc2
import
{
Grid
,
Modal
,
ModalBody
,
ModalCloseButton
,
ModalContent
,
ModalHeader
,
ModalOverlay
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
ContractListTypes
}
from
'
types/client/marketplace
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
ContractSecurityReport
from
'
./ContractSecurityReport
'
;
type
Props
=
{
onClose
:
()
=>
void
;
type
:
ContractListTypes
;
contracts
:
Array
<
any
>
;
// eslint-disable-line @typescript-eslint/no-explicit-any
}
const
ContractListModal
=
({
onClose
,
type
,
contracts
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
displayedContracts
=
React
.
useMemo
(()
=>
{
switch
(
type
)
{
default
:
case
ContractListTypes
.
ALL
:
return
contracts
;
case
ContractListTypes
.
ANALYZED
:
return
contracts
.
filter
((
contract
)
=>
Boolean
(
contract
.
solidityScanReport
))
.
sort
((
a
,
b
)
=>
b
.
solidityScanReport
.
scan_summary
.
score_v2
-
a
.
solidityScanReport
.
scan_summary
.
score_v2
);
case
ContractListTypes
.
VERIFIED
:
return
contracts
.
filter
((
contract
)
=>
contract
.
isVerified
);
}
},
[
contracts
,
type
]);
return
(
<
Modal
isOpen=
{
Boolean
(
type
)
}
onClose=
{
onClose
}
size=
{
isMobile
?
'
full
'
:
'
md
'
}
isCentered
>
<
ModalOverlay
/>
<
ModalContent
>
<
ModalHeader
fontWeight=
"500"
textStyle=
"h3"
mb=
{
4
}
>
Contracts
</
ModalHeader
>
<
ModalCloseButton
/>
<
ModalBody
maxH=
"352px"
overflow=
"scroll"
mb=
{
0
}
display=
"flex"
flexDirection=
"column"
gap=
{
2
}
>
{
displayedContracts
.
map
((
contract
)
=>
(
<
Grid
key=
{
contract
.
address
}
height=
{
8
}
alignItems=
"center"
gap=
{
6
}
templateColumns=
"max-content 1fr"
>
{
type
===
ContractListTypes
.
ANALYZED
&&
(
<
ContractSecurityReport
securityReport=
{
contract
.
solidityScanReport
}
/>
)
}
<
AddressEntity
address=
{
{
hash
:
contract
.
address
,
name
:
contract
.
solidityScanReport
?.
contractname
,
is_contract
:
true
,
is_verified
:
contract
.
isVerified
,
}
}
noCopy
/>
</
Grid
>
))
}
</
ModalBody
>
</
ModalContent
>
</
Modal
>
);
};
export
default
ContractListModal
;
ui/marketplace/ContractSecurityReport.tsx
0 → 100644
View file @
89b91fc2
import
{
Box
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
config
from
'
configs/app
'
;
import
LinkExternal
from
'
ui/shared/LinkExternal
'
;
import
SolidityscanReportButton
from
'
ui/shared/solidityscanReport/SolidityscanReportButton
'
;
import
SolidityscanReportDetails
from
'
ui/shared/solidityscanReport/SolidityscanReportDetails
'
;
import
SolidityscanReportScore
from
'
ui/shared/solidityscanReport/SolidityscanReportScore
'
;
type
Props
=
{
securityReport
?:
any
;
// eslint-disable-line @typescript-eslint/no-explicit-any
}
const
ContractSecurityReport
=
({
securityReport
}:
Props
)
=>
{
const
{
scanner_reference_url
:
url
,
scan_summary
:
{
score_v2
:
securityScore
,
issue_severity_distribution
:
issueSeverityDistribution
,
},
}
=
securityReport
;
const
totalIssues
=
Object
.
values
(
issueSeverityDistribution
as
Record
<
string
,
number
>
).
reduce
((
acc
,
val
)
=>
acc
+
val
,
0
);
return
(
<
SolidityscanReportButton
score=
{
securityScore
}
popoverContent=
{
(
<>
<
Box
mb=
{
5
}
>
The security score was derived from evaluating the smart contracts of a protocol on the
{
config
.
chain
.
name
}
network.
</
Box
>
<
SolidityscanReportScore
score=
{
securityScore
}
/>
{
issueSeverityDistribution
&&
totalIssues
>
0
&&
(
<
Box
mb=
{
5
}
>
<
Text
py=
"7px"
variant=
"secondary"
fontSize=
"xs"
fontWeight=
{
500
}
>
Threat score
&
vulnerabilities
</
Text
>
<
SolidityscanReportDetails
vulnerabilities=
{
issueSeverityDistribution
}
vulnerabilitiesCount=
{
totalIssues
}
/>
</
Box
>
)
}
<
LinkExternal
href=
{
url
}
>
View full report
</
LinkExternal
>
</>
)
}
/>
);
};
export
default
ContractSecurityReport
;
ui/marketplace/MarketplaceListWithScores.tsx
View file @
89b91fc2
...
@@ -2,7 +2,7 @@ import { Hide, Show } from '@chakra-ui/react';
...
@@ -2,7 +2,7 @@ import { Hide, Show } from '@chakra-ui/react';
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MarketplaceAppPreview
}
from
'
types/client/marketplace
'
;
import
type
{
MarketplaceAppPreview
,
ContractListTypes
}
from
'
types/client/marketplace
'
;
import
{
MarketplaceCategory
}
from
'
types/client/marketplace
'
;
import
{
MarketplaceCategory
}
from
'
types/client/marketplace
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
...
@@ -23,6 +23,7 @@ interface Props {
...
@@ -23,6 +23,7 @@ interface Props {
selectedCategoryId
?:
string
;
selectedCategoryId
?:
string
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
securityReports
:
Array
<
any
>
|
undefined
;
// eslint-disable-line @typescript-eslint/no-explicit-any
securityReports
:
Array
<
any
>
|
undefined
;
// eslint-disable-line @typescript-eslint/no-explicit-any
showContractList
:
(
id
:
string
,
type
:
ContractListTypes
)
=>
void
;
}
}
const
MarketplaceListWithScores
=
({
const
MarketplaceListWithScores
=
({
...
@@ -34,6 +35,7 @@ const MarketplaceListWithScores = ({
...
@@ -34,6 +35,7 @@ const MarketplaceListWithScores = ({
selectedCategoryId
,
selectedCategoryId
,
onAppClick
,
onAppClick
,
securityReports
=
[],
securityReports
=
[],
showContractList
,
}:
Props
)
=>
{
}:
Props
)
=>
{
const
displayedApps
=
React
.
useMemo
(()
=>
const
displayedApps
=
React
.
useMemo
(()
=>
...
@@ -63,6 +65,7 @@ const MarketplaceListWithScores = ({
...
@@ -63,6 +65,7 @@ const MarketplaceListWithScores = ({
onFavoriteClick=
{
onFavoriteClick
}
onFavoriteClick=
{
onFavoriteClick
}
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
onAppClick=
{
onAppClick
}
onAppClick=
{
onAppClick
}
showContractList=
{
showContractList
}
/>
/>
))
}
))
}
</
Show
>
</
Show
>
...
@@ -74,6 +77,7 @@ const MarketplaceListWithScores = ({
...
@@ -74,6 +77,7 @@ const MarketplaceListWithScores = ({
favoriteApps=
{
favoriteApps
}
favoriteApps=
{
favoriteApps
}
onFavoriteClick=
{
onFavoriteClick
}
onFavoriteClick=
{
onFavoriteClick
}
onInfoClick=
{
showAppInfo
}
onInfoClick=
{
showAppInfo
}
showContractList=
{
showContractList
}
/>
/>
</
Hide
>
</
Hide
>
</>
</>
...
...
ui/marketplace/MarketplaceListWithScores/AppSecurityReport.tsx
View file @
89b91fc2
import
{
Box
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Text
,
Link
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
ContractListTypes
}
from
'
types/client/marketplace
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
LinkExternal
from
'
ui/shared/LinkExternal
'
;
import
SolidityscanReportButton
from
'
ui/shared/solidityscanReport/SolidityscanReportButton
'
;
import
SolidityscanReportButton
from
'
ui/shared/solidityscanReport/SolidityscanReportButton
'
;
import
SolidityscanReportDetails
from
'
ui/shared/solidityscanReport/SolidityscanReportDetails
'
;
import
SolidityscanReportDetails
from
'
ui/shared/solidityscanReport/SolidityscanReportDetails
'
;
import
SolidityscanReportScore
from
'
ui/shared/solidityscanReport/SolidityscanReportScore
'
;
import
SolidityscanReportScore
from
'
ui/shared/solidityscanReport/SolidityscanReportScore
'
;
type
Props
=
{
type
Props
=
{
id
:
string
;
securityReport
?:
any
;
// eslint-disable-line @typescript-eslint/no-explicit-any
securityReport
?:
any
;
// eslint-disable-line @typescript-eslint/no-explicit-any
isLarge
?:
boolean
;
isLarge
?:
boolean
;
showContractList
:
(
id
:
string
,
type
:
ContractListTypes
)
=>
void
;
}
}
const
AppSecurityReport
=
({
securityReport
,
isLarge
}:
Props
)
=>
{
const
AppSecurityReport
=
({
id
,
securityReport
,
isLarge
,
showContractList
}:
Props
)
=>
{
const
{
const
{
overallInfo
:
{
overallInfo
:
{
securityScore
,
securityScore
,
...
@@ -23,6 +26,11 @@ const AppSecurityReport = ({ securityReport, isLarge }: Props) => {
...
@@ -23,6 +26,11 @@ const AppSecurityReport = ({ securityReport, isLarge }: Props) => {
},
},
}
=
securityReport
;
}
=
securityReport
;
const
showAnalyzedContracts
=
React
.
useCallback
(()
=>
{
showContractList
(
id
,
ContractListTypes
.
ANALYZED
);
},
[
showContractList
,
id
]);
return
(
return
(
<
SolidityscanReportButton
<
SolidityscanReportButton
height=
{
isLarge
?
undefined
:
'
30px
'
}
height=
{
isLarge
?
undefined
:
'
30px
'
}
...
@@ -40,7 +48,7 @@ const AppSecurityReport = ({ securityReport, isLarge }: Props) => {
...
@@ -40,7 +48,7 @@ const AppSecurityReport = ({ securityReport, isLarge }: Props) => {
<
SolidityscanReportDetails
vulnerabilities=
{
issueSeverityDistribution
}
vulnerabilitiesCount=
{
totalIssues
}
/>
<
SolidityscanReportDetails
vulnerabilities=
{
issueSeverityDistribution
}
vulnerabilitiesCount=
{
totalIssues
}
/>
</
Box
>
</
Box
>
)
}
)
}
<
Link
External
href=
"#"
>
Analyzed contracts
</
LinkExternal
>
<
Link
onClick=
{
showAnalyzedContracts
}
>
Analyzed contracts
</
Link
>
</>
</>
)
}
)
}
/>
/>
...
...
ui/marketplace/MarketplaceListWithScores/ListItem.tsx
View file @
89b91fc2
...
@@ -2,7 +2,7 @@ import { Flex, IconButton } from '@chakra-ui/react';
...
@@ -2,7 +2,7 @@ import { Flex, IconButton } from '@chakra-ui/react';
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MarketplaceAppPreview
}
from
'
types/client/marketplace
'
;
import
type
{
MarketplaceAppPreview
,
ContractListTypes
}
from
'
types/client/marketplace
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
@@ -19,9 +19,10 @@ type Props = {
...
@@ -19,9 +19,10 @@ type Props = {
onFavoriteClick
:
(
id
:
string
,
isFavorite
:
boolean
)
=>
void
;
onFavoriteClick
:
(
id
:
string
,
isFavorite
:
boolean
)
=>
void
;
isLoading
:
boolean
;
isLoading
:
boolean
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
showContractList
:
(
id
:
string
,
type
:
ContractListTypes
)
=>
void
;
}
}
const
ListItem
=
({
app
,
onInfoClick
,
isFavorite
,
onFavoriteClick
,
isLoading
,
onAppClick
}:
Props
)
=>
{
const
ListItem
=
({
app
,
onInfoClick
,
isFavorite
,
onFavoriteClick
,
isLoading
,
onAppClick
,
showContractList
}:
Props
)
=>
{
const
{
const
{
id
,
id
,
securityReport
,
securityReport
,
...
@@ -78,7 +79,7 @@ const ListItem = ({ app, onInfoClick, isFavorite, onFavoriteClick, isLoading, on
...
@@ -78,7 +79,7 @@ const ListItem = ({ app, onInfoClick, isFavorite, onFavoriteClick, isLoading, on
</
Flex
>
</
Flex
>
<
Flex
alignItems=
"center"
>
<
Flex
alignItems=
"center"
>
<
Flex
flex=
{
1
}
gap=
{
3
}
alignItems=
"center"
>
<
Flex
flex=
{
1
}
gap=
{
3
}
alignItems=
"center"
>
<
AppSecurityReport
securityReport=
{
securityRepor
t
}
/>
<
AppSecurityReport
id=
{
id
}
securityReport=
{
securityReport
}
showContractList=
{
showContractLis
t
}
/>
<
LinkButton
onClick=
{
handleInfoClick
}
icon=
"contracts"
>
{
totalContractsNumber
}
</
LinkButton
>
<
LinkButton
onClick=
{
handleInfoClick
}
icon=
"contracts"
>
{
totalContractsNumber
}
</
LinkButton
>
<
LinkButton
onClick=
{
handleInfoClick
}
icon=
"contracts_verified"
iconColor=
"green.500"
>
{
verifiedNumber
}
</
LinkButton
>
<
LinkButton
onClick=
{
handleInfoClick
}
icon=
"contracts_verified"
iconColor=
"green.500"
>
{
verifiedNumber
}
</
LinkButton
>
</
Flex
>
</
Flex
>
...
...
ui/marketplace/MarketplaceListWithScores/Table.tsx
View file @
89b91fc2
...
@@ -2,7 +2,7 @@ import { Table as ChakraTable, Tbody, Th, Tr } from '@chakra-ui/react';
...
@@ -2,7 +2,7 @@ import { Table as ChakraTable, Tbody, Th, Tr } from '@chakra-ui/react';
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MarketplaceAppPreview
}
from
'
types/client/marketplace
'
;
import
type
{
MarketplaceAppPreview
,
ContractListTypes
}
from
'
types/client/marketplace
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
import
{
default
as
Thead
}
from
'
ui/shared/TheadSticky
'
;
...
@@ -15,9 +15,10 @@ type Props = {
...
@@ -15,9 +15,10 @@ type Props = {
onFavoriteClick
:
(
id
:
string
,
isFavorite
:
boolean
)
=>
void
;
onFavoriteClick
:
(
id
:
string
,
isFavorite
:
boolean
)
=>
void
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
onInfoClick
:
(
id
:
string
)
=>
void
;
onInfoClick
:
(
id
:
string
)
=>
void
;
showContractList
:
(
id
:
string
,
type
:
ContractListTypes
)
=>
void
;
}
}
const
Table
=
({
apps
,
isLoading
,
favoriteApps
,
onFavoriteClick
,
onAppClick
,
onInfoClick
}:
Props
)
=>
{
const
Table
=
({
apps
,
isLoading
,
favoriteApps
,
onFavoriteClick
,
onAppClick
,
onInfoClick
,
showContractList
}:
Props
)
=>
{
return
(
return
(
<
ChakraTable
>
<
ChakraTable
>
<
Thead
top=
{
0
}
>
<
Thead
top=
{
0
}
>
...
@@ -40,6 +41,7 @@ const Table = ({ apps, isLoading, favoriteApps, onFavoriteClick, onAppClick, onI
...
@@ -40,6 +41,7 @@ const Table = ({ apps, isLoading, favoriteApps, onFavoriteClick, onAppClick, onI
onFavoriteClick=
{
onFavoriteClick
}
onFavoriteClick=
{
onFavoriteClick
}
onAppClick=
{
onAppClick
}
onAppClick=
{
onAppClick
}
onInfoClick=
{
onInfoClick
}
onInfoClick=
{
onInfoClick
}
showContractList=
{
showContractList
}
/>
/>
))
}
))
}
</
Tbody
>
</
Tbody
>
...
...
ui/marketplace/MarketplaceListWithScores/TableItem.tsx
View file @
89b91fc2
...
@@ -3,6 +3,7 @@ import React from 'react';
...
@@ -3,6 +3,7 @@ import React from 'react';
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MarketplaceAppPreview
}
from
'
types/client/marketplace
'
;
import
type
{
MarketplaceAppPreview
}
from
'
types/client/marketplace
'
;
import
{
ContractListTypes
}
from
'
types/client/marketplace
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
@@ -18,6 +19,7 @@ type Props = {
...
@@ -18,6 +19,7 @@ type Props = {
onFavoriteClick
:
(
id
:
string
,
isFavorite
:
boolean
)
=>
void
;
onFavoriteClick
:
(
id
:
string
,
isFavorite
:
boolean
)
=>
void
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
onAppClick
:
(
event
:
MouseEvent
,
id
:
string
)
=>
void
;
onInfoClick
:
(
id
:
string
)
=>
void
;
onInfoClick
:
(
id
:
string
)
=>
void
;
showContractList
:
(
id
:
string
,
type
:
ContractListTypes
)
=>
void
;
}
}
const
TableItem
=
({
const
TableItem
=
({
...
@@ -27,6 +29,7 @@ const TableItem = ({
...
@@ -27,6 +29,7 @@ const TableItem = ({
onFavoriteClick
,
onFavoriteClick
,
onAppClick
,
onAppClick
,
onInfoClick
,
onInfoClick
,
showContractList
,
}:
Props
)
=>
{
}:
Props
)
=>
{
const
{
const
{
...
@@ -50,6 +53,14 @@ const TableItem = ({
...
@@ -50,6 +53,14 @@ const TableItem = ({
onFavoriteClick
(
id
,
isFavorite
);
onFavoriteClick
(
id
,
isFavorite
);
},
[
onFavoriteClick
,
id
,
isFavorite
]);
},
[
onFavoriteClick
,
id
,
isFavorite
]);
const
showAllContracts
=
React
.
useCallback
(()
=>
{
showContractList
(
id
,
ContractListTypes
.
ALL
);
},
[
showContractList
,
id
]);
const
showVerifiedContracts
=
React
.
useCallback
(()
=>
{
showContractList
(
id
,
ContractListTypes
.
VERIFIED
);
},
[
showContractList
,
id
]);
return
(
return
(
<
Tr
>
<
Tr
>
<
Td
verticalAlign=
"middle"
px=
{
2
}
>
<
Td
verticalAlign=
"middle"
px=
{
2
}
>
...
@@ -71,13 +82,13 @@ const TableItem = ({
...
@@ -71,13 +82,13 @@ const TableItem = ({
<
AppLink
app=
{
app
}
isLoading=
{
isLoading
}
onAppClick=
{
onAppClick
}
isLarge
/>
<
AppLink
app=
{
app
}
isLoading=
{
isLoading
}
onAppClick=
{
onAppClick
}
isLarge
/>
</
Td
>
</
Td
>
<
Td
verticalAlign=
"middle"
>
<
Td
verticalAlign=
"middle"
>
<
AppSecurityReport
securityReport=
{
securityRepor
t
}
isLarge
/>
<
AppSecurityReport
id=
{
id
}
securityReport=
{
securityReport
}
showContractList=
{
showContractLis
t
}
isLarge
/>
</
Td
>
</
Td
>
<
Td
verticalAlign=
"middle"
>
<
Td
verticalAlign=
"middle"
>
<
LinkButton
onClick=
{
handleInfoClick
}
icon=
"contracts"
>
{
totalContractsNumber
}
</
LinkButton
>
<
LinkButton
onClick=
{
showAllContracts
}
icon=
"contracts"
>
{
totalContractsNumber
}
</
LinkButton
>
</
Td
>
</
Td
>
<
Td
verticalAlign=
"middle"
>
<
Td
verticalAlign=
"middle"
>
<
LinkButton
onClick=
{
handleInfoClick
}
icon=
"contracts_verified"
iconColor=
"green.500"
>
{
verifiedNumber
}
</
LinkButton
>
<
LinkButton
onClick=
{
showVerifiedContracts
}
icon=
"contracts_verified"
iconColor=
"green.500"
>
{
verifiedNumber
}
</
LinkButton
>
</
Td
>
</
Td
>
<
Td
verticalAlign=
"middle"
isNumeric
>
<
Td
verticalAlign=
"middle"
isNumeric
>
<
LinkButton
onClick=
{
handleInfoClick
}
>
More info
</
LinkButton
>
<
LinkButton
onClick=
{
handleInfoClick
}
>
More info
</
LinkButton
>
...
...
ui/marketplace/useMarketplace.tsx
View file @
89b91fc2
...
@@ -2,6 +2,7 @@ import _pickBy from 'lodash/pickBy';
...
@@ -2,6 +2,7 @@ import _pickBy from 'lodash/pickBy';
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ContractListTypes
}
from
'
types/client/marketplace
'
;
import
{
MarketplaceCategory
}
from
'
types/client/marketplace
'
;
import
{
MarketplaceCategory
}
from
'
types/client/marketplace
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
import
useDebounce
from
'
lib/hooks/useDebounce
'
;
...
@@ -33,6 +34,7 @@ export default function useMarketplace() {
...
@@ -33,6 +34,7 @@ export default function useMarketplace() {
const
[
isFavoriteAppsLoaded
,
setIsFavoriteAppsLoaded
]
=
React
.
useState
<
boolean
>
(
false
);
const
[
isFavoriteAppsLoaded
,
setIsFavoriteAppsLoaded
]
=
React
.
useState
<
boolean
>
(
false
);
const
[
isAppInfoModalOpen
,
setIsAppInfoModalOpen
]
=
React
.
useState
<
boolean
>
(
false
);
const
[
isAppInfoModalOpen
,
setIsAppInfoModalOpen
]
=
React
.
useState
<
boolean
>
(
false
);
const
[
isDisclaimerModalOpen
,
setIsDisclaimerModalOpen
]
=
React
.
useState
<
boolean
>
(
false
);
const
[
isDisclaimerModalOpen
,
setIsDisclaimerModalOpen
]
=
React
.
useState
<
boolean
>
(
false
);
const
[
contractListModalType
,
setContractListModalType
]
=
React
.
useState
<
ContractListTypes
|
null
>
(
null
);
const
handleFavoriteClick
=
React
.
useCallback
((
id
:
string
,
isFavorite
:
boolean
)
=>
{
const
handleFavoriteClick
=
React
.
useCallback
((
id
:
string
,
isFavorite
:
boolean
)
=>
{
mixpanel
.
logEvent
(
mixpanel
.
EventTypes
.
PAGE_WIDGET
,
{
Type
:
'
Favorite app
'
,
Info
:
id
});
mixpanel
.
logEvent
(
mixpanel
.
EventTypes
.
PAGE_WIDGET
,
{
Type
:
'
Favorite app
'
,
Info
:
id
});
...
@@ -60,11 +62,17 @@ export default function useMarketplace() {
...
@@ -60,11 +62,17 @@ export default function useMarketplace() {
setIsDisclaimerModalOpen
(
true
);
setIsDisclaimerModalOpen
(
true
);
},
[]);
},
[]);
const
showContractList
=
React
.
useCallback
((
id
:
string
,
type
:
ContractListTypes
)
=>
{
setSelectedAppId
(
id
);
setContractListModalType
(
type
);
},
[]);
const
debouncedFilterQuery
=
useDebounce
(
filterQuery
,
500
);
const
debouncedFilterQuery
=
useDebounce
(
filterQuery
,
500
);
const
clearSelectedAppId
=
React
.
useCallback
(()
=>
{
const
clearSelectedAppId
=
React
.
useCallback
(()
=>
{
setSelectedAppId
(
null
);
setSelectedAppId
(
null
);
setIsAppInfoModalOpen
(
false
);
setIsAppInfoModalOpen
(
false
);
setIsDisclaimerModalOpen
(
false
);
setIsDisclaimerModalOpen
(
false
);
setContractListModalType
(
null
);
},
[]);
},
[]);
const
handleCategoryChange
=
React
.
useCallback
((
newCategory
:
string
)
=>
{
const
handleCategoryChange
=
React
.
useCallback
((
newCategory
:
string
)
=>
{
...
@@ -133,6 +141,8 @@ export default function useMarketplace() {
...
@@ -133,6 +141,8 @@ export default function useMarketplace() {
showDisclaimer
,
showDisclaimer
,
appsTotal
:
data
?.
length
||
0
,
appsTotal
:
data
?.
length
||
0
,
isCategoriesPlaceholderData
,
isCategoriesPlaceholderData
,
showContractList
,
contractListModalType
,
}),
[
}),
[
selectedCategoryId
,
selectedCategoryId
,
categories
,
categories
,
...
@@ -152,5 +162,7 @@ export default function useMarketplace() {
...
@@ -152,5 +162,7 @@ export default function useMarketplace() {
showDisclaimer
,
showDisclaimer
,
data
?.
length
,
data
?.
length
,
isCategoriesPlaceholderData
,
isCategoriesPlaceholderData
,
showContractList
,
contractListModalType
,
]);
]);
}
}
ui/pages/Marketplace.tsx
View file @
89b91fc2
...
@@ -10,6 +10,7 @@ import { useAppContext } from 'lib/contexts/app';
...
@@ -10,6 +10,7 @@ import { useAppContext } from 'lib/contexts/app';
import
*
as
cookies
from
'
lib/cookies
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
ContractListModal
from
'
ui/marketplace/ContractListModal
'
;
import
MarketplaceAppModal
from
'
ui/marketplace/MarketplaceAppModal
'
;
import
MarketplaceAppModal
from
'
ui/marketplace/MarketplaceAppModal
'
;
import
MarketplaceDisclaimerModal
from
'
ui/marketplace/MarketplaceDisclaimerModal
'
;
import
MarketplaceDisclaimerModal
from
'
ui/marketplace/MarketplaceDisclaimerModal
'
;
import
MarketplaceList
from
'
ui/marketplace/MarketplaceList
'
;
import
MarketplaceList
from
'
ui/marketplace/MarketplaceList
'
;
...
@@ -68,6 +69,8 @@ const Marketplace = () => {
...
@@ -68,6 +69,8 @@ const Marketplace = () => {
showDisclaimer
,
showDisclaimer
,
appsTotal
,
appsTotal
,
isCategoriesPlaceholderData
,
isCategoriesPlaceholderData
,
showContractList
,
contractListModalType
,
}
=
useMarketplace
();
}
=
useMarketplace
();
const
{
const
{
...
@@ -134,6 +137,10 @@ const Marketplace = () => {
...
@@ -134,6 +137,10 @@ const Marketplace = () => {
}
}
const
selectedApp
=
displayedApps
.
find
(
app
=>
app
.
id
===
selectedAppId
);
const
selectedApp
=
displayedApps
.
find
(
app
=>
app
.
id
===
selectedAppId
);
const
selectedAppContractList
=
securityReports
?.
find
(
item
=>
item
.
appName
===
selectedAppId
)
?.
chainsData
[
config
.
chain
.
name
?.
toLowerCase
()
||
''
]
?.
contractsData
;
return
(
return
(
<>
<>
...
@@ -214,6 +221,7 @@ const Marketplace = () => {
...
@@ -214,6 +221,7 @@ const Marketplace = () => {
selectedCategoryId=
{
selectedCategoryId
}
selectedCategoryId=
{
selectedCategoryId
}
onAppClick=
{
handleAppClick
}
onAppClick=
{
handleAppClick
}
securityReports=
{
securityReports
}
securityReports=
{
securityReports
}
showContractList=
{
showContractList
}
/>
/>
)
:
(
)
:
(
<
MarketplaceList
<
MarketplaceList
...
@@ -243,6 +251,14 @@ const Marketplace = () => {
...
@@ -243,6 +251,14 @@ const Marketplace = () => {
appId=
{
selectedApp
.
id
}
appId=
{
selectedApp
.
id
}
/>
/>
)
}
)
}
{
(
selectedApp
&&
contractListModalType
)
&&
(
<
ContractListModal
type=
{
contractListModalType
}
contracts=
{
selectedAppContractList
}
onClose=
{
clearSelectedAppId
}
/>
)
}
</>
</>
);
);
};
};
...
...
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