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
f3fc1267
Commit
f3fc1267
authored
Jul 12, 2022
by
isstuev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
api keys page
parent
dcc3e4f0
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
394 additions
and
6 deletions
+394
-6
apiKey.ts
data/apiKey.ts
+21
-0
api-keys.tsx
pages/api-keys.tsx
+16
-0
Input.ts
theme/components/Input.ts
+3
-1
ApiKeyForm.tsx
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
+100
-0
ApiKeyModal.tsx
ui/apiKey/ApiKeyModal/ApiKeyModal.tsx
+33
-0
ApiKeyTable.tsx
ui/apiKey/ApiKeyTable/ApiKeyTable.tsx
+48
-0
ApiKeyTableItem.tsx
ui/apiKey/ApiKeyTable/ApiKeyTableItem.tsx
+54
-0
DeleteApiKeyModal.tsx
ui/apiKey/DeleteApiKeyModal.tsx
+27
-0
ApiKeys.tsx
ui/pages/ApiKeys.tsx
+87
-0
AddressForm.tsx
ui/privateTags/AddressModal/AddressForm.tsx
+2
-2
TransactionTagTable.tsx
ui/privateTags/TransactionTagTable/TransactionTagTable.tsx
+1
-1
AddressForm.tsx
ui/watchlist/AddressModal/AddressForm.tsx
+2
-2
No files found.
data/apiKey.ts
0 → 100644
View file @
f3fc1267
export
const
apiKey
=
[
{
token
:
'
6fd12fe0-841c-4abf-ac2a-8c1b08dadf8e
'
,
name
:
'
zapper.fi
'
,
},
{
token
:
'
057085a1-d2eb-4d8d-8b89-1dd9fba32071
'
,
name
:
'
TenderlyBlaBlaName
'
,
},
{
token
:
'
057085a1-d2eb-4d8d-8b89-1dd9fba32071
'
,
name
:
'
Application name
'
,
},
];
export
type
TApiKey
=
Array
<
TApiKeyItem
>
export
type
TApiKeyItem
=
{
token
:
string
;
name
:
string
;
}
pages/api-keys.tsx
0 → 100644
View file @
f3fc1267
import
React
from
'
react
'
;
import
type
{
NextPage
}
from
'
next
'
;
import
Head
from
'
next/head
'
import
ApiKeys
from
'
../ui/pages/ApiKeys
'
;
const
ApiKeysPage
:
NextPage
=
()
=>
{
return
(
<>
<
Head
><
title
>
API keys
</
title
></
Head
>
<
ApiKeys
/>
</>
);
}
export
default
ApiKeysPage
theme/components/Input.ts
View file @
f3fc1267
...
@@ -32,7 +32,9 @@ const variantOutline: PartsStyleFunction<typeof parts> = (props) => {
...
@@ -32,7 +32,9 @@ const variantOutline: PartsStyleFunction<typeof parts> = (props) => {
userSelect
:
'
all
'
,
userSelect
:
'
all
'
,
},
},
_disabled
:
{
_disabled
:
{
opacity
:
0.4
,
opacity
:
1
,
background
:
mode
(
'
gray.200
'
,
'
whiteAlpha.400
'
)(
props
),
border
:
'
none
'
,
cursor
:
'
not-allowed
'
,
cursor
:
'
not-allowed
'
,
},
},
_invalid
:
{
_invalid
:
{
...
...
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
0 → 100644
View file @
f3fc1267
import
React
,
{
useCallback
,
useEffect
}
from
'
react
'
;
import
type
{
SubmitHandler
,
ControllerRenderProps
}
from
'
react-hook-form
'
;
import
{
useForm
,
Controller
}
from
'
react-hook-form
'
;
import
{
Box
,
Button
,
FormControl
,
FormLabel
,
Input
,
}
from
'
@chakra-ui/react
'
;
import
type
{
TApiKeyItem
}
from
'
../../../data/apiKey
'
;
type
Props
=
{
data
?:
TApiKeyItem
;
}
type
Inputs
=
{
token
:
string
;
name
:
string
;
}
// idk, maybe there is no limit
const
NAME_MAX_LENGTH
=
100
;
const
ApiKeyForm
:
React
.
FC
<
Props
>
=
({
data
})
=>
{
const
{
control
,
handleSubmit
,
formState
:
{
errors
},
setValue
}
=
useForm
<
Inputs
>
();
useEffect
(()
=>
{
setValue
(
'
token
'
,
data
?.
token
||
''
);
setValue
(
'
name
'
,
data
?.
name
||
''
);
},
[
setValue
,
data
]);
// eslint-disable-next-line no-console
const
onSubmit
:
SubmitHandler
<
Inputs
>
=
data
=>
console
.
log
(
data
);
const
renderTokenInput
=
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
Inputs
,
'
token
'
>
})
=>
{
return
(
<
FormControl
variant=
"floating"
id=
"address"
isRequired
>
<
Input
{
...
field
}
placeholder=
" "
disabled=
{
true
}
/>
<
FormLabel
>
Auto-generated API key token
</
FormLabel
>
</
FormControl
>
)
},
[]);
const
renderNameInput
=
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
Inputs
,
'
name
'
>
})
=>
{
return
(
<
FormControl
variant=
"floating"
id=
"name"
isRequired
>
<
Input
{
...
field
}
placeholder=
" "
isInvalid=
{
Boolean
(
errors
.
name
)
}
maxLength=
{
NAME_MAX_LENGTH
}
/>
<
FormLabel
>
Application name for API key (e.g Web3 project)
</
FormLabel
>
</
FormControl
>
)
},
[
errors
]);
return
(
<>
{
data
&&
(
<
Box
marginBottom=
{
5
}
>
<
Controller
name=
"token"
control=
{
control
}
render=
{
renderTokenInput
}
/>
</
Box
>
)
}
<
Box
marginBottom=
{
8
}
>
<
Controller
name=
"name"
control=
{
control
}
rules=
{
{
maxLength
:
NAME_MAX_LENGTH
,
}
}
render=
{
renderNameInput
}
/>
</
Box
>
<
Box
marginTop=
{
8
}
>
<
Button
size=
"lg"
variant=
"primary"
onClick=
{
handleSubmit
(
onSubmit
)
}
disabled=
{
Object
.
keys
(
errors
).
length
>
0
}
>
{
data
?
'
Save
'
:
'
Generate API key
'
}
</
Button
>
</
Box
>
</>
)
}
export
default
ApiKeyForm
;
ui/apiKey/ApiKeyModal/ApiKeyModal.tsx
0 → 100644
View file @
f3fc1267
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
TApiKeyItem
}
from
'
../../../data/apiKey
'
;
import
ApiKeyForm
from
'
./ApiKeyForm
'
;
import
FormModal
from
'
../../shared/FormModal
'
;
type
Props
=
{
isOpen
:
boolean
;
onClose
:
()
=>
void
;
data
?:
TApiKeyItem
;
}
const
AddressModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClose
,
data
})
=>
{
const
title
=
data
?
'
Edit API key
'
:
'
New API key
'
;
const
text
=
'
Add an application name to identify your API key. Click the button below to auto-generate the associated key.
'
const
renderForm
=
useCallback
(()
=>
{
return
<
ApiKeyForm
data=
{
data
}
/>
},
[
data
]);
return
(
<
FormModal
<
TApiKeyItem
>
isOpen=
{
isOpen
}
onClose=
{
onClose
}
title=
{
title
}
text=
{
text
}
data=
{
data
}
renderForm=
{
renderForm
}
/
>
)
}
export default AddressModal;
ui/apiKey/ApiKeyTable/ApiKeyTable.tsx
0 → 100644
View file @
f3fc1267
import
React
from
'
react
'
;
import
{
Table
,
Thead
,
Tbody
,
Tr
,
Th
,
TableContainer
,
}
from
'
@chakra-ui/react
'
import
type
{
TApiKey
,
TApiKeyItem
}
from
'
../../../data/apiKey
'
;
import
ApiKeyTableItem
from
'
./ApiKeyTableItem
'
;
interface
Props
{
data
:
TApiKey
;
onEditClick
:
(
data
:
TApiKeyItem
)
=>
void
;
onDeleteClick
:
(
data
:
TApiKeyItem
)
=>
void
;
limit
:
number
;
}
const
ApiKeyTable
=
({
data
,
onDeleteClick
,
onEditClick
,
limit
}:
Props
)
=>
{
return
(
<
TableContainer
width=
"100%"
>
<
Table
variant=
"simple"
minWidth=
"600px"
>
<
Thead
>
<
Tr
>
<
Th
>
{
`API key token (limit ${ limit } keys)`
}
</
Th
>
<
Th
width=
"108px"
></
Th
>
</
Tr
>
</
Thead
>
<
Tbody
>
{
data
.
map
((
item
)
=>
(
<
ApiKeyTableItem
item=
{
item
}
key=
{
item
.
token
}
onDeleteClick=
{
onDeleteClick
}
onEditClick=
{
onEditClick
}
/>
))
}
</
Tbody
>
</
Table
>
</
TableContainer
>
);
};
export
default
ApiKeyTable
;
ui/apiKey/ApiKeyTable/ApiKeyTableItem.tsx
0 → 100644
View file @
f3fc1267
import
React
,
{
useCallback
}
from
'
react
'
;
import
{
Tr
,
Td
,
HStack
,
Text
,
useColorModeValue
,
}
from
'
@chakra-ui/react
'
import
EditButton
from
'
../../shared/EditButton
'
;
import
DeleteButton
from
'
../../shared/DeleteButton
'
;
import
type
{
TApiKeyItem
}
from
'
../../../data/apiKey
'
;
import
CopyToClipboard
from
'
../../shared/CopyToClipboard
'
;
interface
Props
{
item
:
TApiKeyItem
;
onEditClick
:
(
data
:
TApiKeyItem
)
=>
void
;
onDeleteClick
:
(
data
:
TApiKeyItem
)
=>
void
;
}
const
WatchlistTableItem
=
({
item
,
onEditClick
,
onDeleteClick
}:
Props
)
=>
{
const
onItemEditClick
=
useCallback
(()
=>
{
return
onEditClick
(
item
);
},
[
item
,
onEditClick
]);
const
onItemDeleteClick
=
useCallback
(()
=>
{
return
onDeleteClick
(
item
);
},
[
item
,
onDeleteClick
]);
const
secondaryColor
=
useColorModeValue
(
'
gray.500
'
,
'
gray.400
'
);
return
(
<
Tr
alignItems=
"top"
key=
{
item
.
token
}
>
<
Td
>
<
HStack
>
<
Text
fontSize=
"md"
fontWeight=
{
600
}
>
{
item
.
token
}
</
Text
>
<
CopyToClipboard
text=
{
item
.
token
}
/>
</
HStack
>
<
Text
fontSize=
"sm"
marginTop=
{
0.5
}
color=
{
secondaryColor
}
>
{
item
.
name
}
</
Text
>
</
Td
>
<
Td
>
<
HStack
spacing=
{
6
}
>
icons
<
EditButton
onClick=
{
onItemEditClick
}
/>
<
DeleteButton
onClick=
{
onItemDeleteClick
}
/>
</
HStack
>
</
Td
>
</
Tr
>
)
};
export
default
WatchlistTableItem
;
ui/apiKey/DeleteApiKeyModal.tsx
0 → 100644
View file @
f3fc1267
import
React
,
{
useCallback
}
from
'
react
'
;
import
DeleteModal
from
'
../shared/DeleteModal
'
type
Props
=
{
isOpen
:
boolean
;
onClose
:
()
=>
void
;
name
?:
string
;
}
const
DeleteAddressModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClose
,
name
})
=>
{
const
onDelete
=
useCallback
(()
=>
{
// eslint-disable-next-line no-console
console
.
log
(
'
delete
'
,
name
);
},
[
name
]);
return
(
<
DeleteModal
isOpen=
{
isOpen
}
onClose=
{
onClose
}
onDelete=
{
onDelete
}
title=
"Remove API key"
text=
{
`API key for "${ name || 'name' }" will be deleted`
}
/>
)
}
export
default
DeleteAddressModal
;
ui/pages/ApiKeys.tsx
0 → 100644
View file @
f3fc1267
import
React
,
{
useCallback
,
useState
}
from
'
react
'
;
import
{
Box
,
Button
,
HStack
,
Link
,
Text
,
useColorModeValue
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
Page
from
'
../Page/Page
'
;
import
ApiKeyTable
from
'
../apiKey/ApiKeyTable/ApiKeyTable
'
;
import
ApiKeyModal
from
'
../apiKey/ApiKeyModal/ApiKeyModal
'
;
import
DeleteApiKeyModal
from
'
../apiKey/DeleteApiKeyModal
'
;
import
type
{
TApiKeyItem
}
from
'
../../data/apiKey
'
;
import
{
apiKey
}
from
'
../../data/apiKey
'
;
import
{
space
}
from
'
../../lib/html-entities
'
;
const
DATA_LIMIT
=
3
;
const
ApiKeys
:
React
.
FC
=
()
=>
{
const
apiKeyModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
[
apiKeyModalData
,
setApiKeyModalData
]
=
useState
<
TApiKeyItem
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
string
>
();
const
onEditClick
=
useCallback
((
data
:
TApiKeyItem
)
=>
{
setApiKeyModalData
(
data
);
apiKeyModalProps
.
onOpen
();
},
[
apiKeyModalProps
])
const
onApiKeyModalClose
=
useCallback
(()
=>
{
setApiKeyModalData
(
undefined
);
apiKeyModalProps
.
onClose
();
},
[
apiKeyModalProps
]);
const
onDeleteClick
=
useCallback
((
data
:
TApiKeyItem
)
=>
{
setDeleteModalData
(
data
.
name
);
deleteModalProps
.
onOpen
();
},
[
deleteModalProps
])
const
onDeleteModalClose
=
useCallback
(()
=>
{
setDeleteModalData
(
undefined
);
deleteModalProps
.
onClose
();
},
[
deleteModalProps
]);
const
captionColor
=
useColorModeValue
(
'
gray.500
'
,
'
gray.400
'
);
const
canAdd
=
apiKey
.
length
<
DATA_LIMIT
return
(
<
Page
>
<
Box
h=
"100%"
>
<
Box
as=
"h1"
textStyle=
"h2"
marginBottom=
{
8
}
>
API keys
</
Box
>
<
Text
marginBottom=
{
12
}
>
Create API keys to use for your RPC and EthRPC API requests. For more information, see
{
space
}
<
Link
href=
"#"
>
“How to use a Blockscout API key”
</
Link
>
.
</
Text
>
{
Boolean
(
apiKey
.
length
)
&&
(
<
ApiKeyTable
data=
{
apiKey
}
onDeleteClick=
{
onDeleteClick
}
onEditClick=
{
onEditClick
}
limit=
{
DATA_LIMIT
}
/>
)
}
<
HStack
marginTop=
{
8
}
spacing=
{
5
}
>
<
Button
variant=
"primary"
size=
"lg"
onClick=
{
apiKeyModalProps
.
onOpen
}
disabled=
{
!
canAdd
}
>
Add API key
</
Button
>
{
!
canAdd
&&
(
<
Text
fontSize=
"sm"
color=
{
captionColor
}
>
{
`You have added the maximum number of API keys (${ DATA_LIMIT }). Contact us to request additional keys.`
}
</
Text
>
)
}
</
HStack
>
</
Box
>
<
ApiKeyModal
{
...
apiKeyModalProps
}
onClose=
{
onApiKeyModalClose
}
data=
{
apiKeyModalData
}
/>
<
DeleteApiKeyModal
{
...
deleteModalProps
}
onClose=
{
onDeleteModalClose
}
name=
{
deleteModalData
}
/>
</
Page
>
);
};
export
default
ApiKeys
ui/privateTags/AddressModal/AddressForm.tsx
View file @
f3fc1267
...
@@ -24,7 +24,7 @@ type Inputs = {
...
@@ -24,7 +24,7 @@ type Inputs = {
tag
:
string
;
tag
:
string
;
}
}
const
Address
Modal
:
React
.
FC
<
Props
>
=
({
data
})
=>
{
const
Address
Form
:
React
.
FC
<
Props
>
=
({
data
})
=>
{
const
{
control
,
handleSubmit
,
formState
:
{
errors
},
setValue
}
=
useForm
<
Inputs
>
();
const
{
control
,
handleSubmit
,
formState
:
{
errors
},
setValue
}
=
useForm
<
Inputs
>
();
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -80,4 +80,4 @@ const AddressModal: React.FC<Props> = ({ data }) => {
...
@@ -80,4 +80,4 @@ const AddressModal: React.FC<Props> = ({ data }) => {
)
)
}
}
export
default
Address
Modal
;
export
default
Address
Form
;
ui/privateTags/TransactionTagTable/TransactionTagTable.tsx
View file @
f3fc1267
...
@@ -25,7 +25,7 @@ const AddressTagTable = ({ data, onDeleteClick, onEditClick }: Props) => {
...
@@ -25,7 +25,7 @@ const AddressTagTable = ({ data, onDeleteClick, onEditClick }: Props) => {
<
Table
variant=
"simple"
minWidth=
"600px"
>
<
Table
variant=
"simple"
minWidth=
"600px"
>
<
Thead
>
<
Thead
>
<
Tr
>
<
Tr
>
<
Th
width=
"75%"
>
Address
</
Th
>
<
Th
width=
"75%"
>
Transaction
</
Th
>
<
Th
width=
"25%"
>
Private tag
</
Th
>
<
Th
width=
"25%"
>
Private tag
</
Th
>
<
Th
width=
"108px"
></
Th
>
<
Th
width=
"108px"
></
Th
>
</
Tr
>
</
Tr
>
...
...
ui/watchlist/AddressModal/AddressForm.tsx
View file @
f3fc1267
...
@@ -30,7 +30,7 @@ type Inputs = {
...
@@ -30,7 +30,7 @@ type Inputs = {
notification
:
boolean
;
notification
:
boolean
;
}
}
const
Address
Modal
:
React
.
FC
<
Props
>
=
({
data
})
=>
{
const
Address
Form
:
React
.
FC
<
Props
>
=
({
data
})
=>
{
const
{
control
,
handleSubmit
,
formState
:
{
errors
},
setValue
}
=
useForm
<
Inputs
>
();
const
{
control
,
handleSubmit
,
formState
:
{
errors
},
setValue
}
=
useForm
<
Inputs
>
();
useEffect
(()
=>
{
useEffect
(()
=>
{
...
@@ -122,4 +122,4 @@ const AddressModal: React.FC<Props> = ({ data }) => {
...
@@ -122,4 +122,4 @@ const AddressModal: React.FC<Props> = ({ data }) => {
)
)
}
}
export
default
Address
Modal
;
export
default
Address
Form
;
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