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
4c8f5ae9
Commit
4c8f5ae9
authored
Feb 21, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
api keys, custom abi, vizualize and csv export pages
parent
add0e9bb
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
180 additions
and
216 deletions
+180
-216
api-key.tsx
pages/account/api-key.tsx
+2
-2
custom-abi.tsx
pages/account/custom-abi.tsx
+2
-2
csv-export.tsx
pages/csv-export.tsx
+2
-2
sol2uml.tsx
pages/visualize/sol2uml.tsx
+2
-2
theme.ts
toolkit/theme/theme.ts
+0
-5
ContractExternalLibraries.tsx
ui/address/contract/ContractExternalLibraries.tsx
+26
-34
TokenSelect.tsx
ui/address/tokenSelect/TokenSelect.tsx
+16
-21
ApiKeyForm.tsx
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
+9
-12
ApiKeyModal.tsx
ui/apiKey/ApiKeyModal/ApiKeyModal.tsx
+7
-7
ApiKeyTable.tsx
ui/apiKey/ApiKeyTable/ApiKeyTable.tsx
+12
-17
ApiKeyTableItem.tsx
ui/apiKey/ApiKeyTable/ApiKeyTableItem.tsx
+7
-10
DeleteApiKeyModal.tsx
ui/apiKey/DeleteApiKeyModal.tsx
+5
-5
CsvExportForm.tsx
ui/csvExport/CsvExportForm.tsx
+8
-11
CsvExportFormField.tsx
ui/csvExport/CsvExportFormField.tsx
+3
-4
CustomAbiListItem.tsx
ui/customAbi/CustomAbiTable/CustomAbiListItem.tsx
+2
-2
CustomAbiTable.tsx
ui/customAbi/CustomAbiTable/CustomAbiTable.tsx
+12
-17
CustomAbiTableItem.tsx
ui/customAbi/CustomAbiTable/CustomAbiTableItem.tsx
+10
-13
DeleteCustomAbiModal.tsx
ui/customAbi/DeleteCustomAbiModal.tsx
+5
-5
ApiKeys.tsx
ui/pages/ApiKeys.tsx
+16
-13
CustomAbi.tsx
ui/pages/CustomAbi.tsx
+13
-11
ApiKeySnippet.tsx
ui/shared/ApiKeySnippet.tsx
+6
-6
CoinzillaTextAd.tsx
ui/shared/ad/CoinzillaTextAd.tsx
+11
-11
Sol2UmlDiagram.tsx
ui/sol2uml/Sol2UmlDiagram.tsx
+4
-4
No files found.
pages/account/api-key.tsx
View file @
4c8f5ae9
...
@@ -4,12 +4,12 @@ import React from 'react';
...
@@ -4,12 +4,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const ApiKeys = dynamic(() => import('ui/pages/ApiKeys'), { ssr: false });
const
ApiKeys
=
dynamic
(()
=>
import
(
'
ui/pages/ApiKeys
'
),
{
ssr
:
false
});
const
Page
:
NextPage
=
()
=>
{
const
Page
:
NextPage
=
()
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/account/api-key"
>
<
PageNextJs
pathname=
"/account/api-key"
>
{
/* <ApiKeys/> */
}
<
ApiKeys
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
pages/account/custom-abi.tsx
View file @
4c8f5ae9
...
@@ -4,12 +4,12 @@ import React from 'react';
...
@@ -4,12 +4,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const CustomAbi = dynamic(() => import('ui/pages/CustomAbi'), { ssr: false });
const
CustomAbi
=
dynamic
(()
=>
import
(
'
ui/pages/CustomAbi
'
),
{
ssr
:
false
});
const
Page
:
NextPage
=
()
=>
{
const
Page
:
NextPage
=
()
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/account/custom-abi"
>
<
PageNextJs
pathname=
"/account/custom-abi"
>
{
/* <CustomAbi/> */
}
<
CustomAbi
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
pages/csv-export.tsx
View file @
4c8f5ae9
...
@@ -3,12 +3,12 @@ import React from 'react';
...
@@ -3,12 +3,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
import CsvExport from 'ui/pages/CsvExport';
import
CsvExport
from
'
ui/pages/CsvExport
'
;
const
Page
:
NextPage
=
()
=>
{
const
Page
:
NextPage
=
()
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/csv-export"
>
<
PageNextJs
pathname=
"/csv-export"
>
{
/* <CsvExport/> */
}
<
CsvExport
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
pages/visualize/sol2uml.tsx
View file @
4c8f5ae9
...
@@ -3,12 +3,12 @@ import React from 'react';
...
@@ -3,12 +3,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
import Sol2Uml from 'ui/pages/Sol2Uml';
import
Sol2Uml
from
'
ui/pages/Sol2Uml
'
;
const
Page
:
NextPage
=
()
=>
{
const
Page
:
NextPage
=
()
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/visualize/sol2uml"
>
<
PageNextJs
pathname=
"/visualize/sol2uml"
>
{
/* <Sol2Uml/> */
}
<
Sol2Uml
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
toolkit/theme/theme.ts
View file @
4c8f5ae9
import
{
createSystem
,
defaultConfig
,
defineConfig
}
from
'
@chakra-ui/react
'
;
import
{
createSystem
,
defaultConfig
,
defineConfig
}
from
'
@chakra-ui/react
'
;
// TODO @tom2drum migrate this to the new recipe system
// import components from './components/index';
// import config from './config';
import
{
keyframes
}
from
'
./foundations/animations
'
;
import
{
keyframes
}
from
'
./foundations/animations
'
;
import
*
as
borders
from
'
./foundations/borders
'
;
import
*
as
borders
from
'
./foundations/borders
'
;
import
breakpoints
from
'
./foundations/breakpoints
'
;
import
breakpoints
from
'
./foundations/breakpoints
'
;
...
@@ -39,8 +36,6 @@ const customConfig = defineConfig({
...
@@ -39,8 +36,6 @@ const customConfig = defineConfig({
},
},
},
},
},
},
// components,
// config,
});
});
export
default
createSystem
(
defaultConfig
,
customConfig
);
export
default
createSystem
(
defaultConfig
,
customConfig
);
ui/address/contract/ContractExternalLibraries.tsx
View file @
4c8f5ae9
import
{
import
{
Box
,
Flex
,
Separator
,
VStack
}
from
'
@chakra-ui/react
'
;
Alert
,
Box
,
Button
,
Flex
,
Heading
,
Modal
,
ModalCloseButton
,
ModalContent
,
PopoverBody
,
PopoverContent
,
PopoverTrigger
,
StackDivider
,
useDisclosure
,
VStack
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SmartContractExternalLibrary
}
from
'
types/api/contract
'
;
import
type
{
SmartContractExternalLibrary
}
from
'
types/api/contract
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
{
apos
}
from
'
lib/html-entities
'
;
import
Popover
from
'
ui/shared/chakra/Popover
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
DialogBody
,
DialogContent
,
DialogHeader
,
DialogRoot
}
from
'
toolkit/chakra/dialog
'
;
import
{
Heading
}
from
'
toolkit/chakra/heading
'
;
import
{
PopoverRoot
,
PopoverBody
,
PopoverContent
,
PopoverTrigger
}
from
'
toolkit/chakra/popover
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
@@ -47,11 +37,11 @@ const Item = (data: SmartContractExternalLibrary) => {
...
@@ -47,11 +37,11 @@ const Item = (data: SmartContractExternalLibrary) => {
};
};
const
ContractExternalLibraries
=
({
className
,
data
,
isLoading
}:
Props
)
=>
{
const
ContractExternalLibraries
=
({
className
,
data
,
isLoading
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClos
e
}
=
useDisclosure
();
const
{
open
,
onToggle
,
onOpenChang
e
}
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
if
(
isLoading
)
{
if
(
isLoading
)
{
return
<
Skeleton
h=
{
8
}
w=
"150px"
borderRadius=
"base"
/>;
return
<
Skeleton
loading
h=
{
8
}
w=
"150px"
borderRadius=
"base"
/>;
}
}
if
(
data
.
length
===
0
)
{
if
(
data
.
length
===
0
)
{
...
@@ -62,17 +52,17 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
...
@@ -62,17 +52,17 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
<
Button
<
Button
className=
{
className
}
className=
{
className
}
size=
"sm"
size=
"sm"
variant=
"outline"
variant=
"dropdown"
colorScheme=
"gray"
onClick=
{
onToggle
}
onClick=
{
onToggle
}
isActive=
{
isO
pen
}
expanded=
{
o
pen
}
fontWeight=
{
600
}
fontWeight=
{
600
}
px=
{
2
}
px=
{
2
}
gap=
{
0
}
aria
-
label=
"View external libraries"
aria
-
label=
"View external libraries"
>
>
<
span
>
{
data
.
length
}
{
data
.
length
>
1
?
'
Libraries
'
:
'
Library
'
}
</
span
>
<
span
>
{
data
.
length
}
{
data
.
length
>
1
?
'
Libraries
'
:
'
Library
'
}
</
span
>
<
IconSvg
name=
"status/warning"
boxSize=
{
5
}
color=
"orange.400"
ml=
"2px"
/>
<
IconSvg
name=
"status/warning"
boxSize=
{
5
}
color=
"orange.400"
ml=
"2px"
/>
<
IconSvg
name=
"arrows/east-mini"
transform=
{
isO
pen
?
'
rotate(90deg)
'
:
'
rotate(-90deg)
'
}
transitionDuration=
"faster"
boxSize=
{
5
}
ml=
{
2
}
/>
<
IconSvg
name=
"arrows/east-mini"
transform=
{
o
pen
?
'
rotate(90deg)
'
:
'
rotate(-90deg)
'
}
transitionDuration=
"faster"
boxSize=
{
5
}
ml=
{
2
}
/>
</
Button
>
</
Button
>
);
);
...
@@ -84,8 +74,8 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
...
@@ -84,8 +74,8 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
Check the source code at the library address (if any) if you want to be sure in case if there is any library linked
Check the source code at the library address (if any) if you want to be sure in case if there is any library linked
</
Alert
>
</
Alert
>
<
VStack
<
VStack
divider=
{
<
StackDivider
borderColor=
"border.divider"
/>
}
separator=
{
<
Separator
/>
}
spacing
=
{
2
}
gap
=
{
2
}
mt=
{
4
}
mt=
{
4
}
maxH=
{
{
lg
:
'
50vh
'
}
}
maxH=
{
{
lg
:
'
50vh
'
}
}
overflowY=
"scroll"
overflowY=
"scroll"
...
@@ -99,18 +89,20 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
...
@@ -99,18 +89,20 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
return
(
return
(
<>
<>
{
button
}
{
button
}
<
Modal
isOpen=
{
isOpen
}
onClose=
{
onClose
}
size=
"full"
>
<
DialogRoot
open=
{
open
}
onOpenChange=
{
onOpenChange
}
size=
"full"
>
<
ModalContent
paddingTop=
{
4
}
>
<
DialogContent
paddingTop=
{
4
}
>
<
ModalCloseButton
/>
<
DialogHeader
/>
<
DialogBody
>
{
content
}
{
content
}
</
ModalContent
>
</
DialogBody
>
</
Modal
>
</
DialogContent
>
</
DialogRoot
>
</>
</>
);
);
}
}
return
(
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
Popover
Root
open=
{
open
}
onOpenChange=
{
onOpenChange
}
>
<
PopoverTrigger
>
<
PopoverTrigger
>
{
button
}
{
button
}
</
PopoverTrigger
>
</
PopoverTrigger
>
...
@@ -119,7 +111,7 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
...
@@ -119,7 +111,7 @@ const ContractExternalLibraries = ({ className, data, isLoading }: Props) => {
{
content
}
{
content
}
</
PopoverBody
>
</
PopoverBody
>
</
PopoverContent
>
</
PopoverContent
>
</
Popover
>
</
Popover
Root
>
);
);
};
};
...
...
ui/address/tokenSelect/TokenSelect.tsx
View file @
4c8f5ae9
...
@@ -6,15 +6,17 @@ import React from 'react';
...
@@ -6,15 +6,17 @@ import React from 'react';
import
type
{
Address
}
from
'
types/api/address
'
;
import
type
{
Address
}
from
'
types/api/address
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
NextLink
from
'
ui/shared/NextLink
'
;
import
useFetchTokens
from
'
../utils/useFetchTokens
'
;
import
useFetchTokens
from
'
../utils/useFetchTokens
'
;
import
TokenSelectDesktop
from
'
./TokenSelectDesktop
'
;
import
TokenSelectDesktop
from
'
./TokenSelectDesktop
'
;
...
@@ -64,27 +66,20 @@ const TokenSelect = ({ onClick }: Props) => {
...
@@ -64,27 +66,20 @@ const TokenSelect = ({ onClick }: Props) => {
<
TokenSelectDesktop
data=
{
data
}
isLoading=
{
tokensIsFetching
===
1
}
/>
<
TokenSelectDesktop
data=
{
data
}
isLoading=
{
tokensIsFetching
===
1
}
/>
}
}
<
Tooltip
content=
"Show all tokens"
>
<
Tooltip
content=
"Show all tokens"
>
<
Box
>
<
Link
{
/* TODO @tom2drum: replace with Link */
}
href=
{
route
({
pathname
:
'
/address/[hash]
'
,
query
:
{
hash
:
addressHash
,
tab
:
'
tokens
'
}
})
}
<
NextLink
asChild
href=
{
{
pathname
:
'
/address/[hash]
'
,
query
:
{
hash
:
addressHash
,
tab
:
'
tokens
'
}
}
}
passHref
legacyBehavior
scroll=
{
false
}
scroll=
{
false
}
>
>
<
IconButton
<
IconButton
aria
-
label=
"Show all tokens"
aria
-
label=
"Show all tokens"
variant=
"outline"
variant=
"outline"
size=
"sm"
size=
"sm"
pl=
"6px"
pr=
"6px"
as=
"a"
onClick=
{
handleIconButtonClick
}
onClick=
{
handleIconButtonClick
}
>
>
<
IconSvg
name=
"wallet"
boxSize=
{
5
}
/>
<
IconSvg
name=
"wallet"
boxSize=
{
5
}
/>
</
IconButton
>
</
IconButton
>
</
NextLink
>
</
Link
>
</
Box
>
</
Tooltip
>
</
Tooltip
>
</
Flex
>
</
Flex
>
);
);
...
...
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
View file @
4c8f5ae9
import
{
import
{
Box
}
from
'
@chakra-ui/react
'
;
Box
,
Button
,
}
from
'
@chakra-ui/react
'
;
import
{
useMutation
,
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useMutation
,
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
...
@@ -13,11 +10,12 @@ import type { ResourceErrorAccount } from 'lib/api/resources';
...
@@ -13,11 +10,12 @@ import type { ResourceErrorAccount } from 'lib/api/resources';
import
{
resourceKey
}
from
'
lib/api/resources
'
;
import
{
resourceKey
}
from
'
lib/api/resources
'
;
import
useApiFetch
from
'
lib/api/useApiFetch
'
;
import
useApiFetch
from
'
lib/api/useApiFetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
type
Props
=
{
type
Props
=
{
data
?:
ApiKey
;
data
?:
ApiKey
;
on
Close
:
(
)
=>
void
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
setAlertVisible
:
(
isAlertVisible
:
boolean
)
=>
void
;
setAlertVisible
:
(
isAlertVisible
:
boolean
)
=>
void
;
};
};
...
@@ -28,7 +26,7 @@ type Inputs = {
...
@@ -28,7 +26,7 @@ type Inputs = {
const
NAME_MAX_LENGTH
=
255
;
const
NAME_MAX_LENGTH
=
255
;
const
ApiKeyForm
:
React
.
FC
<
Props
>
=
({
data
,
on
Clos
e
,
setAlertVisible
})
=>
{
const
ApiKeyForm
:
React
.
FC
<
Props
>
=
({
data
,
on
OpenChang
e
,
setAlertVisible
})
=>
{
const
formApi
=
useForm
<
Inputs
>
({
const
formApi
=
useForm
<
Inputs
>
({
mode
:
'
onTouched
'
,
mode
:
'
onTouched
'
,
defaultValues
:
{
defaultValues
:
{
...
@@ -73,7 +71,7 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -73,7 +71,7 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
return
[
response
,
...(
prevData
||
[])
];
return
[
response
,
...(
prevData
||
[])
];
});
});
on
Close
(
);
on
OpenChange
({
open
:
false
}
);
},
},
onError
:
(
error
:
ResourceErrorAccount
<
ApiKeyErrors
>
)
=>
{
onError
:
(
error
:
ResourceErrorAccount
<
ApiKeyErrors
>
)
=>
{
const
errorMap
=
error
.
payload
?.
errors
;
const
errorMap
=
error
.
payload
?.
errors
;
...
@@ -99,15 +97,14 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -99,15 +97,14 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
FormFieldText
<
Inputs
>
<
FormFieldText
<
Inputs
>
name="token"
name="token"
placeholder="Auto-generated API key token"
placeholder="Auto-generated API key token"
isReadOnly
readOnly
bgColor="dialog.bg"
mb=
{
5
}
mb=
{
5
}
/
>
/
>
)
}
)
}
<
FormFieldText
<
Inputs
>
<
FormFieldText
<
Inputs
>
name="name"
name="name"
placeholder="Application name for API key (e.g Web3 project)"
placeholder="Application name for API key (e.g Web3 project)"
isR
equired
r
equired
rules=
{
{
rules=
{
{
maxLength
:
NAME_MAX_LENGTH
,
maxLength
:
NAME_MAX_LENGTH
,
}
}
}
}
...
@@ -118,8 +115,8 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -118,8 +115,8 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
<
Button
<
Button
size=
"lg"
size=
"lg"
type=
"submit"
type=
"submit"
isD
isabled=
{
!
formApi
.
formState
.
isDirty
}
d
isabled=
{
!
formApi
.
formState
.
isDirty
}
isL
oading=
{
isPending
}
l
oading=
{
isPending
}
>
>
{
data
?
'
Save
'
:
'
Generate API key
'
}
{
data
?
'
Save
'
:
'
Generate API key
'
}
</
Button
>
</
Button
>
...
...
ui/apiKey/ApiKeyModal/ApiKeyModal.tsx
View file @
4c8f5ae9
...
@@ -7,24 +7,24 @@ import FormModal from 'ui/shared/FormModal';
...
@@ -7,24 +7,24 @@ import FormModal from 'ui/shared/FormModal';
import
ApiKeyForm
from
'
./ApiKeyForm
'
;
import
ApiKeyForm
from
'
./ApiKeyForm
'
;
type
Props
=
{
type
Props
=
{
isO
pen
:
boolean
;
o
pen
:
boolean
;
on
Close
:
(
)
=>
void
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
data
?:
ApiKey
;
data
?:
ApiKey
;
};
};
const
ApiKeyModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClos
e
,
data
})
=>
{
const
ApiKeyModal
:
React
.
FC
<
Props
>
=
({
open
,
onOpenChang
e
,
data
})
=>
{
const
title
=
data
?
'
Edit API key
'
:
'
New API key
'
;
const
title
=
data
?
'
Edit API key
'
:
'
New API key
'
;
const
text
=
!
data
?
'
Add an application name to identify your API key. Click the button below to auto-generate the associated key.
'
:
''
;
const
text
=
!
data
?
'
Add an application name to identify your API key. Click the button below to auto-generate the associated key.
'
:
''
;
const
[
isAlertVisible
,
setAlertVisible
]
=
useState
(
false
);
const
[
isAlertVisible
,
setAlertVisible
]
=
useState
(
false
);
const
renderForm
=
useCallback
(()
=>
{
const
renderForm
=
useCallback
(()
=>
{
return
<
ApiKeyForm
data=
{
data
}
on
Close=
{
onClos
e
}
setAlertVisible=
{
setAlertVisible
}
/>;
return
<
ApiKeyForm
data=
{
data
}
on
OpenChange=
{
onOpenChang
e
}
setAlertVisible=
{
setAlertVisible
}
/>;
},
[
data
,
on
Clos
e
]);
},
[
data
,
on
OpenChang
e
]);
return
(
return
(
<
FormModal
<
ApiKey
>
<
FormModal
<
ApiKey
>
isOpen=
{
isO
pen
}
open=
{
o
pen
}
on
Close=
{
onClos
e
}
on
OpenChange=
{
onOpenChang
e
}
title=
{
title
}
title=
{
title
}
text=
{
text
}
text=
{
text
}
renderForm=
{
renderForm
}
renderForm=
{
renderForm
}
...
...
ui/apiKey/ApiKeyTable/ApiKeyTable.tsx
View file @
4c8f5ae9
import
{
Table
,
Thead
,
Tbody
,
Tr
,
Th
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
ApiKeys
,
ApiKey
}
from
'
types/api/account
'
;
import
type
{
ApiKeys
,
ApiKey
}
from
'
types/api/account
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeader
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
ApiKeyTableItem
from
'
./ApiKeyTableItem
'
;
import
ApiKeyTableItem
from
'
./ApiKeyTableItem
'
;
interface
Props
{
interface
Props
{
...
@@ -21,14 +16,14 @@ interface Props {
...
@@ -21,14 +16,14 @@ interface Props {
const
ApiKeyTable
=
({
data
,
isLoading
,
onDeleteClick
,
onEditClick
,
limit
}:
Props
)
=>
{
const
ApiKeyTable
=
({
data
,
isLoading
,
onDeleteClick
,
onEditClick
,
limit
}:
Props
)
=>
{
return
(
return
(
<
Table
minWidth=
"600px"
>
<
Table
Root
minWidth=
"600px"
>
<
T
head
>
<
T
ableHeader
>
<
T
r
>
<
T
ableRow
>
<
T
h
>
{
`API key token (limit ${ limit } keys)`
}
</
Th
>
<
T
ableColumnHeader
>
{
`API key token (limit ${ limit } keys)`
}
</
TableColumnHeader
>
<
T
h
width=
"108px"
></
Th
>
<
T
ableColumnHeader
width=
"108px"
></
TableColumnHeader
>
</
T
r
>
</
T
ableRow
>
</
T
head
>
</
T
ableHeader
>
<
T
b
ody
>
<
T
ableB
ody
>
{
data
?.
map
((
item
,
index
)
=>
(
{
data
?.
map
((
item
,
index
)
=>
(
<
ApiKeyTableItem
<
ApiKeyTableItem
key=
{
item
.
api_key
+
(
isLoading
?
index
:
''
)
}
key=
{
item
.
api_key
+
(
isLoading
?
index
:
''
)
}
...
@@ -38,8 +33,8 @@ const ApiKeyTable = ({ data, isLoading, onDeleteClick, onEditClick, limit }: Pro
...
@@ -38,8 +33,8 @@ const ApiKeyTable = ({ data, isLoading, onDeleteClick, onEditClick, limit }: Pro
onEditClick=
{
onEditClick
}
onEditClick=
{
onEditClick
}
/>
/>
))
}
))
}
</
T
b
ody
>
</
T
ableB
ody
>
</
Table
>
</
Table
Root
>
);
);
};
};
...
...
ui/apiKey/ApiKeyTable/ApiKeyTableItem.tsx
View file @
4c8f5ae9
import
{
Tr
,
Td
,
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
ApiKey
}
from
'
types/api/account
'
;
import
type
{
ApiKey
}
from
'
types/api/account
'
;
import
{
TableCell
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
ApiKeySnippet
from
'
ui/shared/ApiKeySnippet
'
;
import
ApiKeySnippet
from
'
ui/shared/ApiKeySnippet
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
...
@@ -27,14 +24,14 @@ const ApiKeyTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Props)
...
@@ -27,14 +24,14 @@ const ApiKeyTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Props)
},
[
item
,
onDeleteClick
]);
},
[
item
,
onDeleteClick
]);
return
(
return
(
<
T
r
alignItems=
"top"
key=
{
item
.
api_key
}
>
<
T
ableRow
alignItems=
"top"
key=
{
item
.
api_key
}
>
<
T
d
>
<
T
ableCell
>
<
ApiKeySnippet
apiKey=
{
item
.
api_key
}
name=
{
item
.
name
}
isLoading=
{
isLoading
}
/>
<
ApiKeySnippet
apiKey=
{
item
.
api_key
}
name=
{
item
.
name
}
isLoading=
{
isLoading
}
/>
</
T
d
>
</
T
ableCell
>
<
T
d
>
<
T
ableCell
>
<
TableItemActionButtons
onDeleteClick=
{
onItemDeleteClick
}
onEditClick=
{
onItemEditClick
}
isLoading=
{
isLoading
}
/>
<
TableItemActionButtons
onDeleteClick=
{
onItemDeleteClick
}
onEditClick=
{
onItemEditClick
}
isLoading=
{
isLoading
}
/>
</
T
d
>
</
T
ableCell
>
</
T
r
>
</
T
ableRow
>
);
);
};
};
...
...
ui/apiKey/DeleteApiKeyModal.tsx
View file @
4c8f5ae9
...
@@ -9,12 +9,12 @@ import useApiFetch from 'lib/api/useApiFetch';
...
@@ -9,12 +9,12 @@ import useApiFetch from 'lib/api/useApiFetch';
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
type
Props
=
{
type
Props
=
{
isO
pen
:
boolean
;
o
pen
:
boolean
;
on
Close
:
(
)
=>
void
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
data
:
ApiKey
;
data
:
ApiKey
;
};
};
const
DeleteApiKeyModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClos
e
,
data
})
=>
{
const
DeleteApiKeyModal
:
React
.
FC
<
Props
>
=
({
open
,
onOpenChang
e
,
data
})
=>
{
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
apiFetch
=
useApiFetch
();
const
apiFetch
=
useApiFetch
();
...
@@ -39,8 +39,8 @@ const DeleteApiKeyModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
...
@@ -39,8 +39,8 @@ const DeleteApiKeyModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
return
(
return
(
<
DeleteModal
<
DeleteModal
isOpen=
{
isO
pen
}
open=
{
o
pen
}
on
Close=
{
onClos
e
}
on
OpenChange=
{
onOpenChang
e
}
title=
"Remove API key"
title=
"Remove API key"
renderContent=
{
renderText
}
renderContent=
{
renderText
}
mutationFn=
{
mutationFn
}
mutationFn=
{
mutationFn
}
...
...
ui/csvExport/CsvExportForm.tsx
View file @
4c8f5ae9
import
{
Alert
,
Button
,
chakra
,
Flex
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
{
useForm
,
FormProvider
}
from
'
react-hook-form
'
;
import
{
useForm
,
FormProvider
}
from
'
react-hook-form
'
;
...
@@ -11,7 +11,9 @@ import buildUrl from 'lib/api/buildUrl';
...
@@ -11,7 +11,9 @@ import buildUrl from 'lib/api/buildUrl';
import
type
{
ResourceName
}
from
'
lib/api/resources
'
;
import
type
{
ResourceName
}
from
'
lib/api/resources
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
downloadBlob
from
'
lib/downloadBlob
'
;
import
downloadBlob
from
'
lib/downloadBlob
'
;
import
useToast
from
'
lib/hooks/useToast
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
toaster
}
from
'
toolkit/chakra/toaster
'
;
import
ReCaptcha
from
'
ui/shared/reCaptcha/ReCaptcha
'
;
import
ReCaptcha
from
'
ui/shared/reCaptcha/ReCaptcha
'
;
import
useReCaptcha
from
'
ui/shared/reCaptcha/useReCaptcha
'
;
import
useReCaptcha
from
'
ui/shared/reCaptcha/useReCaptcha
'
;
...
@@ -35,7 +37,6 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
...
@@ -35,7 +37,6 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
},
},
});
});
const
{
handleSubmit
,
formState
}
=
formApi
;
const
{
handleSubmit
,
formState
}
=
formApi
;
const
toast
=
useToast
();
const
recaptcha
=
useReCaptcha
();
const
recaptcha
=
useReCaptcha
();
const
onFormSubmit
:
SubmitHandler
<
FormFields
>
=
React
.
useCallback
(
async
(
data
)
=>
{
const
onFormSubmit
:
SubmitHandler
<
FormFields
>
=
React
.
useCallback
(
async
(
data
)
=>
{
...
@@ -73,17 +74,13 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
...
@@ -73,17 +74,13 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
downloadBlob
(
blob
,
fileName
);
downloadBlob
(
blob
,
fileName
);
}
catch
(
error
)
{
}
catch
(
error
)
{
toast
({
toaster
.
error
({
position
:
'
top-right
'
,
title
:
'
Error
'
,
title
:
'
Error
'
,
description
:
(
error
as
Error
)?.
message
||
'
Something went wrong. Try again later.
'
,
description
:
(
error
as
Error
)?.
message
||
'
Something went wrong. Try again later.
'
,
status
:
'
error
'
,
variant
:
'
subtle
'
,
isClosable
:
true
,
});
});
}
}
},
[
recaptcha
,
resource
,
hash
,
exportType
,
filterType
,
filterValue
,
fileNameTemplate
,
toast
]);
},
[
recaptcha
,
resource
,
hash
,
exportType
,
filterType
,
filterValue
,
fileNameTemplate
]);
if
(
!
config
.
services
.
reCaptchaV2
.
siteKey
)
{
if
(
!
config
.
services
.
reCaptchaV2
.
siteKey
)
{
return
(
return
(
...
@@ -110,9 +107,9 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
...
@@ -110,9 +107,9 @@ const CsvExportForm = ({ hash, resource, filterType, filterValue, fileNameTempla
size=
"lg"
size=
"lg"
type=
"submit"
type=
"submit"
mt=
{
8
}
mt=
{
8
}
isL
oading=
{
formState
.
isSubmitting
}
l
oading=
{
formState
.
isSubmitting
}
loadingText=
"Download"
loadingText=
"Download"
isD
isabled=
{
Boolean
(
formState
.
errors
.
from
||
formState
.
errors
.
to
)
}
d
isabled=
{
Boolean
(
formState
.
errors
.
from
||
formState
.
errors
.
to
)
}
>
>
Download
Download
</
Button
>
</
Button
>
...
...
ui/csvExport/CsvExportFormField.tsx
View file @
4c8f5ae9
...
@@ -38,12 +38,11 @@ const CsvExportFormField = ({ formApi, name }: Props) => {
...
@@ -38,12 +38,11 @@ const CsvExportFormField = ({ formApi, name }: Props) => {
return
(
return
(
<
FormFieldText
<
FormFields
,
typeof
name
>
<
FormFieldText
<
FormFields
,
typeof
name
>
name=
{
name
}
name=
{
name
}
type="date"
inputProps=
{
{
type
:
'
date
'
,
max
:
dayjs
().
format
(
'
YYYY-MM-DD
'
)
}
}
max=
{
dayjs
().
format
(
'
YYYY-MM-DD
'
)
}
placeholder=
{
capitalize
(
name
)
}
placeholder=
{
capitalize
(
name
)
}
isR
equired
r
equired
rules=
{
{
validate
}
}
rules=
{
{
validate
}
}
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
size=
"xl"
maxW=
{
{
base
:
'
auto
'
,
lg
:
'
220px
'
}
}
maxW=
{
{
base
:
'
auto
'
,
lg
:
'
220px
'
}
}
/
>
/
>
);
);
...
...
ui/customAbi/CustomAbiTable/CustomAbiListItem.tsx
View file @
4c8f5ae9
...
@@ -3,7 +3,7 @@ import React, { useCallback } from 'react';
...
@@ -3,7 +3,7 @@ import React, { useCallback } from 'react';
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile/ListItemMobile
'
;
import
ListItemMobile
from
'
ui/shared/ListItemMobile/ListItemMobile
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
...
@@ -33,7 +33,7 @@ const CustomAbiListItem = ({ item, isLoading, onEditClick, onDeleteClick }: Prop
...
@@ -33,7 +33,7 @@ const CustomAbiListItem = ({ item, isLoading, onEditClick, onDeleteClick }: Prop
fontWeight=
"600"
fontWeight=
"600"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
/>
/>
<
Skeleton
fontSize=
"sm"
color=
"text_secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
isLoaded=
{
!
isLoading
}
>
<
Skeleton
textStyle=
"sm"
color=
"text.secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
loading=
{
isLoading
}
>
<
span
>
{
item
.
name
}
</
span
>
<
span
>
{
item
.
name
}
</
span
>
</
Skeleton
>
</
Skeleton
>
</
Box
>
</
Box
>
...
...
ui/customAbi/CustomAbiTable/CustomAbiTable.tsx
View file @
4c8f5ae9
import
{
Table
,
Thead
,
Tbody
,
Tr
,
Th
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
CustomAbis
,
CustomAbi
}
from
'
types/api/account
'
;
import
type
{
CustomAbis
,
CustomAbi
}
from
'
types/api/account
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeader
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
CustomAbiTableItem
from
'
./CustomAbiTableItem
'
;
import
CustomAbiTableItem
from
'
./CustomAbiTableItem
'
;
interface
Props
{
interface
Props
{
...
@@ -20,14 +15,14 @@ interface Props {
...
@@ -20,14 +15,14 @@ interface Props {
const
CustomAbiTable
=
({
data
,
isLoading
,
onDeleteClick
,
onEditClick
}:
Props
)
=>
{
const
CustomAbiTable
=
({
data
,
isLoading
,
onDeleteClick
,
onEditClick
}:
Props
)
=>
{
return
(
return
(
<
Table
minWidth=
"600px"
>
<
Table
Root
minWidth=
"600px"
>
<
T
head
>
<
T
ableHeader
>
<
T
r
>
<
T
ableRow
>
<
T
h
>
ABI for Smart contract address (0x...)
</
Th
>
<
T
ableColumnHeader
>
ABI for Smart contract address (0x...)
</
TableColumnHeader
>
<
T
h
width=
"108px"
></
Th
>
<
T
ableColumnHeader
width=
"108px"
></
TableColumnHeader
>
</
T
r
>
</
T
ableRow
>
</
T
head
>
</
T
ableHeader
>
<
T
b
ody
>
<
T
ableB
ody
>
{
data
?.
map
((
item
,
index
)
=>
(
{
data
?.
map
((
item
,
index
)
=>
(
<
CustomAbiTableItem
<
CustomAbiTableItem
key=
{
item
.
id
+
(
isLoading
?
String
(
index
)
:
''
)
}
key=
{
item
.
id
+
(
isLoading
?
String
(
index
)
:
''
)
}
...
@@ -37,8 +32,8 @@ const CustomAbiTable = ({ data, isLoading, onDeleteClick, onEditClick }: Props)
...
@@ -37,8 +32,8 @@ const CustomAbiTable = ({ data, isLoading, onDeleteClick, onEditClick }: Props)
onEditClick=
{
onEditClick
}
onEditClick=
{
onEditClick
}
/>
/>
))
}
))
}
</
T
b
ody
>
</
T
ableB
ody
>
</
Table
>
</
Table
Root
>
);
);
};
};
...
...
ui/customAbi/CustomAbiTable/CustomAbiTableItem.tsx
View file @
4c8f5ae9
import
{
import
{
Box
}
from
'
@chakra-ui/react
'
;
Tr
,
Td
,
Box
,
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
TableCell
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
...
@@ -29,23 +26,23 @@ const CustomAbiTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Pro
...
@@ -29,23 +26,23 @@ const CustomAbiTableItem = ({ item, isLoading, onEditClick, onDeleteClick }: Pro
},
[
item
,
onDeleteClick
]);
},
[
item
,
onDeleteClick
]);
return
(
return
(
<
T
r
alignItems=
"top"
key=
{
item
.
id
}
>
<
T
ableRow
alignItems=
"top"
key=
{
item
.
id
}
>
<
T
d
>
<
T
ableCell
>
<
Box
maxW=
"100%"
>
<
Box
maxW=
"100%"
>
<
AddressEntity
<
AddressEntity
address=
{
item
.
contract_address
}
address=
{
item
.
contract_address
}
fontWeight=
"600"
fontWeight=
"600"
isLoading=
{
isLoading
}
isLoading=
{
isLoading
}
/>
/>
<
Skeleton
fontSize=
"sm"
color=
"text_secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
isLoaded=
{
!
isLoading
}
>
<
Skeleton
textStyle=
"sm"
color=
"text.secondary"
mt=
{
0.5
}
ml=
{
8
}
display=
"inline-block"
loading=
{
isLoading
}
>
<
span
>
{
item
.
name
}
</
span
>
<
span
>
{
item
.
name
}
</
span
>
</
Skeleton
>
</
Skeleton
>
</
Box
>
</
Box
>
</
T
d
>
</
T
ableCell
>
<
T
d
>
<
T
ableCell
>
<
TableItemActionButtons
onDeleteClick=
{
onItemDeleteClick
}
onEditClick=
{
onItemEditClick
}
isLoading=
{
isLoading
}
/>
<
TableItemActionButtons
onDeleteClick=
{
onItemDeleteClick
}
onEditClick=
{
onItemEditClick
}
isLoading=
{
isLoading
}
/>
</
T
d
>
</
T
ableCell
>
</
T
r
>
</
T
ableRow
>
);
);
};
};
...
...
ui/customAbi/DeleteCustomAbiModal.tsx
View file @
4c8f5ae9
...
@@ -9,12 +9,12 @@ import useApiFetch from 'lib/api/useApiFetch';
...
@@ -9,12 +9,12 @@ import useApiFetch from 'lib/api/useApiFetch';
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
type
Props
=
{
type
Props
=
{
isO
pen
:
boolean
;
o
pen
:
boolean
;
on
Close
:
(
)
=>
void
;
on
OpenChange
:
({
open
}:
{
open
:
boolean
}
)
=>
void
;
data
:
CustomAbi
;
data
:
CustomAbi
;
};
};
const
DeleteCustomAbiModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClos
e
,
data
})
=>
{
const
DeleteCustomAbiModal
:
React
.
FC
<
Props
>
=
({
open
,
onOpenChang
e
,
data
})
=>
{
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
apiFetch
=
useApiFetch
();
const
apiFetch
=
useApiFetch
();
...
@@ -40,8 +40,8 @@ const DeleteCustomAbiModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
...
@@ -40,8 +40,8 @@ const DeleteCustomAbiModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
return
(
return
(
<
DeleteModal
<
DeleteModal
isOpen=
{
isO
pen
}
open=
{
o
pen
}
on
Close=
{
onClos
e
}
on
OpenChange=
{
onOpenChang
e
}
title=
"Remove custom ABI"
title=
"Remove custom ABI"
renderContent=
{
renderText
}
renderContent=
{
renderText
}
mutationFn=
{
mutationFn
}
mutationFn=
{
mutationFn
}
...
...
ui/pages/ApiKeys.tsx
View file @
4c8f5ae9
import
{
Box
,
Button
,
Link
,
Text
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
type
{
ApiKey
}
from
'
types/api/account
'
;
import
type
{
ApiKey
}
from
'
types/api/account
'
;
...
@@ -6,12 +6,15 @@ import type { ApiKey } from 'types/api/account';
...
@@ -6,12 +6,15 @@ import type { ApiKey } from 'types/api/account';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
{
API_KEY
}
from
'
stubs/account
'
;
import
{
API_KEY
}
from
'
stubs/account
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
ApiKeyModal
from
'
ui/apiKey/ApiKeyModal/ApiKeyModal
'
;
import
ApiKeyModal
from
'
ui/apiKey/ApiKeyModal/ApiKeyModal
'
;
import
ApiKeyListItem
from
'
ui/apiKey/ApiKeyTable/ApiKeyListItem
'
;
import
ApiKeyListItem
from
'
ui/apiKey/ApiKeyTable/ApiKeyListItem
'
;
import
ApiKeyTable
from
'
ui/apiKey/ApiKeyTable/ApiKeyTable
'
;
import
ApiKeyTable
from
'
ui/apiKey/ApiKeyTable/ApiKeyTable
'
;
import
DeleteApiKeyModal
from
'
ui/apiKey/DeleteApiKeyModal
'
;
import
DeleteApiKeyModal
from
'
ui/apiKey/DeleteApiKeyModal
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
useRedirectForInvalidAuthToken
from
'
ui/snippets/auth/useRedirectForInvalidAuthToken
'
;
import
useRedirectForInvalidAuthToken
from
'
ui/snippets/auth/useRedirectForInvalidAuthToken
'
;
...
@@ -37,9 +40,9 @@ const ApiKeysPage: React.FC = () => {
...
@@ -37,9 +40,9 @@ const ApiKeysPage: React.FC = () => {
apiKeyModalProps
.
onOpen
();
apiKeyModalProps
.
onOpen
();
},
[
apiKeyModalProps
]);
},
[
apiKeyModalProps
]);
const
onApiKeyModal
Close
=
useCallback
((
)
=>
{
const
onApiKeyModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
setApiKeyModalData
(
undefined
);
!
open
&&
setApiKeyModalData
(
undefined
);
apiKeyModalProps
.
on
Close
(
);
apiKeyModalProps
.
on
OpenChange
({
open
}
);
},
[
apiKeyModalProps
]);
},
[
apiKeyModalProps
]);
const
onDeleteClick
=
useCallback
((
data
:
ApiKey
)
=>
{
const
onDeleteClick
=
useCallback
((
data
:
ApiKey
)
=>
{
...
@@ -47,9 +50,9 @@ const ApiKeysPage: React.FC = () => {
...
@@ -47,9 +50,9 @@ const ApiKeysPage: React.FC = () => {
deleteModalProps
.
onOpen
();
deleteModalProps
.
onOpen
();
},
[
deleteModalProps
]);
},
[
deleteModalProps
]);
const
onDeleteModal
Close
=
useCallback
((
)
=>
{
const
onDeleteModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
setDeleteModalData
(
undefined
);
!
open
&&
setDeleteModalData
(
undefined
);
deleteModalProps
.
on
Close
(
);
deleteModalProps
.
on
OpenChange
({
open
}
);
},
[
deleteModalProps
]);
},
[
deleteModalProps
]);
const
description
=
(
const
description
=
(
...
@@ -99,7 +102,7 @@ const ApiKeysPage: React.FC = () => {
...
@@ -99,7 +102,7 @@ const ApiKeysPage: React.FC = () => {
marginTop=
{
8
}
marginTop=
{
8
}
flexDir=
{
{
base
:
'
column
'
,
lg
:
'
row
'
}
}
flexDir=
{
{
base
:
'
column
'
,
lg
:
'
row
'
}
}
alignItems=
{
{
base
:
'
start
'
,
lg
:
'
center
'
}
}
alignItems=
{
{
base
:
'
start
'
,
lg
:
'
center
'
}
}
isLoaded=
{
!
isPlaceholderData
}
loading=
{
isPlaceholderData
}
display=
"inline-flex"
display=
"inline-flex"
columnGap=
{
5
}
columnGap=
{
5
}
rowGap=
{
5
}
rowGap=
{
5
}
...
@@ -107,18 +110,18 @@ const ApiKeysPage: React.FC = () => {
...
@@ -107,18 +110,18 @@ const ApiKeysPage: React.FC = () => {
<
Button
<
Button
size=
"lg"
size=
"lg"
onClick=
{
apiKeyModalProps
.
onOpen
}
onClick=
{
apiKeyModalProps
.
onOpen
}
isD
isabled=
{
!
canAdd
}
d
isabled=
{
!
canAdd
}
>
>
Add API key
Add API key
</
Button
>
</
Button
>
{
!
canAdd
&&
(
{
!
canAdd
&&
(
<
Text
fontSize=
"sm"
variant=
"
secondary"
>
<
Text
fontSize=
"sm"
color=
"text.
secondary"
>
{
`You have added the maximum number of API keys (${ DATA_LIMIT }). Contact us to request additional keys.`
}
{
`You have added the maximum number of API keys (${ DATA_LIMIT }). Contact us to request additional keys.`
}
</
Text
>
</
Text
>
)
}
)
}
</
Skeleton
>
</
Skeleton
>
<
ApiKeyModal
{
...
apiKeyModalProps
}
onClose=
{
onApiKeyModalClos
e
}
data=
{
apiKeyModalData
}
/>
<
ApiKeyModal
open=
{
apiKeyModalProps
.
open
}
onOpenChange=
{
onApiKeyModalOpenChang
e
}
data=
{
apiKeyModalData
}
/>
{
deleteModalData
&&
<
DeleteApiKeyModal
{
...
deleteModalProps
}
onClose=
{
onDeleteModalClos
e
}
data=
{
deleteModalData
}
/>
}
{
deleteModalData
&&
<
DeleteApiKeyModal
open=
{
deleteModalProps
.
open
}
onOpenChange=
{
onDeleteModalOpenChang
e
}
data=
{
deleteModalData
}
/>
}
</>
</>
);
);
})();
})();
...
...
ui/pages/CustomAbi.tsx
View file @
4c8f5ae9
import
{
Box
,
Button
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
type
{
CustomAbi
}
from
'
types/api/account
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
CUSTOM_ABI
}
from
'
stubs/account
'
;
import
{
CUSTOM_ABI
}
from
'
stubs/account
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
CustomAbiModal
from
'
ui/customAbi/CustomAbiModal/CustomAbiModal
'
;
import
CustomAbiModal
from
'
ui/customAbi/CustomAbiModal/CustomAbiModal
'
;
import
CustomAbiListItem
from
'
ui/customAbi/CustomAbiTable/CustomAbiListItem
'
;
import
CustomAbiListItem
from
'
ui/customAbi/CustomAbiTable/CustomAbiListItem
'
;
import
CustomAbiTable
from
'
ui/customAbi/CustomAbiTable/CustomAbiTable
'
;
import
CustomAbiTable
from
'
ui/customAbi/CustomAbiTable/CustomAbiTable
'
;
import
DeleteCustomAbiModal
from
'
ui/customAbi/DeleteCustomAbiModal
'
;
import
DeleteCustomAbiModal
from
'
ui/customAbi/DeleteCustomAbiModal
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
useRedirectForInvalidAuthToken
from
'
ui/snippets/auth/useRedirectForInvalidAuthToken
'
;
import
useRedirectForInvalidAuthToken
from
'
ui/snippets/auth/useRedirectForInvalidAuthToken
'
;
...
@@ -34,9 +36,9 @@ const CustomAbiPage: React.FC = () => {
...
@@ -34,9 +36,9 @@ const CustomAbiPage: React.FC = () => {
customAbiModalProps
.
onOpen
();
customAbiModalProps
.
onOpen
();
},
[
customAbiModalProps
]);
},
[
customAbiModalProps
]);
const
onCustomAbiModal
Close
=
useCallback
((
)
=>
{
const
onCustomAbiModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
setCustomAbiModalData
(
undefined
);
!
open
&&
setCustomAbiModalData
(
undefined
);
customAbiModalProps
.
on
Close
(
);
customAbiModalProps
.
on
OpenChange
({
open
}
);
},
[
customAbiModalProps
]);
},
[
customAbiModalProps
]);
const
onDeleteClick
=
useCallback
((
data
:
CustomAbi
)
=>
{
const
onDeleteClick
=
useCallback
((
data
:
CustomAbi
)
=>
{
...
@@ -44,9 +46,9 @@ const CustomAbiPage: React.FC = () => {
...
@@ -44,9 +46,9 @@ const CustomAbiPage: React.FC = () => {
deleteModalProps
.
onOpen
();
deleteModalProps
.
onOpen
();
},
[
deleteModalProps
]);
},
[
deleteModalProps
]);
const
onDeleteModal
Close
=
useCallback
((
)
=>
{
const
onDeleteModal
OpenChange
=
useCallback
(({
open
}:
{
open
:
boolean
}
)
=>
{
setDeleteModalData
(
undefined
);
!
open
&&
setDeleteModalData
(
undefined
);
deleteModalProps
.
on
Close
(
);
deleteModalProps
.
on
OpenChange
({
open
}
);
},
[
deleteModalProps
]);
},
[
deleteModalProps
]);
const
description
=
(
const
description
=
(
...
@@ -88,7 +90,7 @@ const CustomAbiPage: React.FC = () => {
...
@@ -88,7 +90,7 @@ const CustomAbiPage: React.FC = () => {
<>
<>
{
description
}
{
description
}
{
Boolean
(
data
?.
length
)
&&
list
}
{
Boolean
(
data
?.
length
)
&&
list
}
<
Skeleton
mt=
{
8
}
isLoaded=
{
!
isPlaceholderData
}
display=
"inline-block"
>
<
Skeleton
mt=
{
8
}
loading=
{
isPlaceholderData
}
display=
"inline-block"
>
<
Button
<
Button
size=
"lg"
size=
"lg"
onClick=
{
customAbiModalProps
.
onOpen
}
onClick=
{
customAbiModalProps
.
onOpen
}
...
@@ -96,8 +98,8 @@ const CustomAbiPage: React.FC = () => {
...
@@ -96,8 +98,8 @@ const CustomAbiPage: React.FC = () => {
Add custom ABI
Add custom ABI
</
Button
>
</
Button
>
</
Skeleton
>
</
Skeleton
>
<
CustomAbiModal
{
...
customAbiModalProps
}
onClose=
{
onCustomAbiModalClos
e
}
data=
{
customAbiModalData
}
/>
<
CustomAbiModal
open=
{
customAbiModalProps
.
open
}
onOpenChange=
{
onCustomAbiModalOpenChang
e
}
data=
{
customAbiModalData
}
/>
{
deleteModalData
&&
<
DeleteCustomAbiModal
{
...
deleteModalProps
}
onClose=
{
onDeleteModalClos
e
}
data=
{
deleteModalData
}
/>
}
{
deleteModalData
&&
<
DeleteCustomAbiModal
open=
{
deleteModalProps
.
open
}
onOpenChange=
{
onDeleteModalOpenChang
e
}
data=
{
deleteModalData
}
/>
}
</>
</>
);
);
})();
})();
...
...
ui/shared/ApiKeySnippet.tsx
View file @
4c8f5ae9
import
{
Box
,
HStack
,
Flex
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
HStack
,
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
@@ -13,17 +13,17 @@ interface Props {
...
@@ -13,17 +13,17 @@ interface Props {
const
ApiKeySnippet
=
({
apiKey
,
name
,
isLoading
}:
Props
)
=>
{
const
ApiKeySnippet
=
({
apiKey
,
name
,
isLoading
}:
Props
)
=>
{
return
(
return
(
<
HStack
spacing
=
{
2
}
alignItems=
"start"
>
<
HStack
gap
=
{
2
}
alignItems=
"start"
>
<
IconSvg
name=
"key"
boxSize=
{
6
}
color=
{
useColorModeValue
(
'
gray.500
'
,
'
gray.400
'
)
}
isLoading=
{
isLoading
}
/>
<
IconSvg
name=
"key"
boxSize=
{
6
}
color=
{
{
_light
:
'
gray.500
'
,
_dark
:
'
gray.400
'
}
}
isLoading=
{
isLoading
}
/>
<
Box
>
<
Box
>
<
Flex
alignItems=
{
{
base
:
'
flex-start
'
,
lg
:
'
center
'
}
}
>
<
Flex
alignItems=
{
{
base
:
'
flex-start
'
,
lg
:
'
center
'
}
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
fontWeight=
{
600
}
mr=
{
1
}
>
<
Skeleton
loading=
{
isLoading
}
display=
"inline-block"
fontWeight=
{
600
}
mr=
{
1
}
>
<
span
>
{
apiKey
}
</
span
>
<
span
>
{
apiKey
}
</
span
>
</
Skeleton
>
</
Skeleton
>
<
CopyToClipboard
text=
{
apiKey
}
isLoading=
{
isLoading
}
/>
<
CopyToClipboard
text=
{
apiKey
}
isLoading=
{
isLoading
}
/>
</
Flex
>
</
Flex
>
{
name
&&
(
{
name
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
fontSize=
"sm"
color=
"text_secondary"
mt=
{
1
}
>
<
Skeleton
loading=
{
isLoading
}
display=
"inline-block"
fontSize=
"sm"
color=
"text_secondary"
mt=
{
1
}
>
<
span
>
{
name
}
</
span
>
<
span
>
{
name
}
</
span
>
</
Skeleton
>
</
Skeleton
>
)
}
)
}
...
...
ui/shared/ad/CoinzillaTextAd.tsx
View file @
4c8f5ae9
...
@@ -18,15 +18,15 @@ type AdData = {
...
@@ -18,15 +18,15 @@ type AdData = {
};
};
};
};
//
const MOCK: AdData = {
const
MOCK
:
AdData
=
{
//
ad: {
ad
:
{
//
url: 'https://unsplash.com/s/photos/cute-kitten',
url
:
'
https://unsplash.com/s/photos/cute-kitten
'
,
// thumbnail: 'https://placekitten.com/40/40
',
thumbnail
:
'
https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/gnosis.svg
'
,
//
name: 'All about kitties',
name
:
'
All about kitties
'
,
//
description_short: 'To see millions picture of cute kitties',
description_short
:
'
To see millions picture of cute kitties
'
,
//
cta_button: 'click here',
cta_button
:
'
click here
'
,
//
},
},
//
};
};
const
CoinzillaTextAd
=
({
className
}:
{
className
?:
string
})
=>
{
const
CoinzillaTextAd
=
({
className
}:
{
className
?:
string
})
=>
{
const
[
adData
,
setAdData
]
=
React
.
useState
<
AdData
|
null
>
(
null
);
const
[
adData
,
setAdData
]
=
React
.
useState
<
AdData
|
null
>
(
null
);
...
@@ -44,7 +44,7 @@ const CoinzillaTextAd = ({ className }: { className?: string }) => {
...
@@ -44,7 +44,7 @@ const CoinzillaTextAd = ({ className }: { className?: string }) => {
}
}
})
})
.
finally
(()
=>
{
.
finally
(()
=>
{
//
setAdData(MOCK);
setAdData
(
MOCK
);
setIsLoading
(
false
);
setIsLoading
(
false
);
});
});
}
}
...
@@ -87,7 +87,7 @@ const CoinzillaTextAd = ({ className }: { className?: string }) => {
...
@@ -87,7 +87,7 @@ const CoinzillaTextAd = ({ className }: { className?: string }) => {
src=
{
adData
.
ad
.
thumbnail
}
src=
{
adData
.
ad
.
thumbnail
}
width=
"20px"
width=
"20px"
height=
"20px"
height=
"20px"
mb=
"2px
"
verticalAlign=
"text-bottom
"
mr=
{
1
}
mr=
{
1
}
display=
"inline-block"
display=
"inline-block"
alt=
""
alt=
""
...
...
ui/sol2uml/Sol2UmlDiagram.tsx
View file @
4c8f5ae9
import
{
chakra
,
Tooltip
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
*
as
visualizer
from
'
@blockscout/visualizer-types
'
;
import
type
*
as
visualizer
from
'
@blockscout/visualizer-types
'
;
...
@@ -8,6 +8,7 @@ import type { ResourceError } from 'lib/api/resources';
...
@@ -8,6 +8,7 @@ import type { ResourceError } from 'lib/api/resources';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
throwOnAbsentParamError
from
'
lib/errors/throwOnAbsentParamError
'
;
import
throwOnAbsentParamError
from
'
lib/errors/throwOnAbsentParamError
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
interface
Props
{
interface
Props
{
...
@@ -53,7 +54,6 @@ const Sol2UmlDiagram = ({ addressHash }: Props) => {
...
@@ -53,7 +54,6 @@ const Sol2UmlDiagram = ({ addressHash }: Props) => {
});
});
const
imgUrl
=
`data:image/svg+xml;base64,
${
umlQuery
.
data
?.
svg
}
`;
const
imgUrl
=
`data:image/svg+xml;base64,
${
umlQuery
.
data
?.
svg
}
`;
const imgFilter = useColorModeValue('invert(0)', 'invert(1)');
const handleClick = React.useCallback(() => {
const handleClick = React.useCallback(() => {
const image = new Image();
const image = new Image();
...
@@ -76,13 +76,13 @@ const Sol2UmlDiagram = ({ addressHash }: Props) => {
...
@@ -76,13 +76,13 @@ const Sol2UmlDiagram = ({ addressHash }: Props) => {
}
}
return (
return (
<Tooltip
label="Click on image to zoom" placement="top"
>
<Tooltip
content="Click on image to zoom" positioning={{ placement: 'top' }}
>
<chakra.img
<chakra.img
src={ imgUrl }
src={ imgUrl }
alt={ `
Contract
$
{
contractQuery
.
data
.
name
}
UML
diagram
` }
alt={ `
Contract
$
{
contractQuery
.
data
.
name
}
UML
diagram
` }
onClick={ handleClick }
onClick={ handleClick }
cursor="pointer"
cursor="pointer"
filter={
imgFilter
}
filter={
{ _light: 'invert(0)', _dark: 'invert(1)' }
}
/>
/>
</Tooltip>
</Tooltip>
);
);
...
...
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