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
04ca8bcc
Commit
04ca8bcc
authored
Sep 14, 2022
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pass csrf token for state changing requests
parent
13ae1199
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
144 additions
and
76 deletions
+144
-76
fetch.ts
lib/client/fetch.ts
+0
-33
useFetch.tsx
lib/hooks/useFetch.tsx
+54
-0
useFetchProfileInfo.tsx
lib/hooks/useFetchProfileInfo.tsx
+3
-1
index.ts
pages/api/account/csrf/index.ts
+18
-0
account.ts
types/client/account.ts
+4
-0
ApiKeyForm.tsx
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
+4
-3
DeleteApiKeyModal.tsx
ui/apiKey/DeleteApiKeyModal.tsx
+3
-2
CustomAbiForm.tsx
ui/customAbi/CustomAbiModal/CustomAbiForm.tsx
+4
-3
ApiKeys.tsx
ui/pages/ApiKeys.tsx
+2
-1
CustomAbi.tsx
ui/pages/CustomAbi.tsx
+2
-1
Watchlist.tsx
ui/pages/Watchlist.tsx
+2
-1
AddressForm.tsx
ui/privateTags/AddressModal/AddressForm.tsx
+5
-4
DeletePrivateTagModal.tsx
ui/privateTags/DeletePrivateTagModal.tsx
+5
-3
PrivateAddressTags.tsx
ui/privateTags/PrivateAddressTags.tsx
+2
-1
PrivateTransactionTags.tsx
ui/privateTags/PrivateTransactionTags.tsx
+2
-1
TransactionForm.tsx
ui/privateTags/TransactionModal/TransactionForm.tsx
+5
-4
DeletePublicTagModal.tsx
ui/publicTags/DeletePublicTagModal.tsx
+4
-3
PublicTagsData.tsx
ui/publicTags/PublicTagsData.tsx
+2
-1
PublicTagsForm.tsx
ui/publicTags/PublicTagsForm/PublicTagsForm.tsx
+4
-4
Page.tsx
ui/shared/Page.tsx
+6
-0
AddressForm.tsx
ui/watchlist/AddressModal/AddressForm.tsx
+6
-5
DeleteAddressModal.tsx
ui/watchlist/DeleteAddressModal.tsx
+3
-2
WatchListTableItem.tsx
ui/watchlist/WatchlistTable/WatchListTableItem.tsx
+4
-3
No files found.
lib/client/fetch.ts
deleted
100644 → 0
View file @
13ae1199
import
*
as
Sentry
from
'
@sentry/nextjs
'
;
export
interface
ErrorType
<
T
>
{
error
?:
T
;
status
:
Response
[
'
status
'
];
statusText
:
Response
[
'
statusText
'
];
}
export
default
function
clientFetch
<
Success
,
Error
>
(
path
:
string
,
init
?:
RequestInit
):
Promise
<
Success
|
ErrorType
<
Error
>>
{
return
fetch
(
path
,
init
).
then
(
response
=>
{
if
(
!
response
.
ok
)
{
return
response
.
json
().
then
(
(
jsonError
)
=>
Promise
.
reject
({
error
:
jsonError
as
Error
,
status
:
response
.
status
,
statusText
:
response
.
statusText
,
}),
()
=>
{
const
error
=
{
status
:
response
.
status
,
statusText
:
response
.
statusText
,
};
Sentry
.
captureException
(
new
Error
(
'
Client fetch failed
'
),
{
extra
:
error
,
tags
:
{
source
:
'
fetch
'
}
});
return
Promise
.
reject
(
error
);
},
);
}
else
{
return
response
.
json
()
as
Promise
<
Success
>
;
}
});
}
lib/hooks/useFetch.tsx
0 → 100644
View file @
04ca8bcc
import
*
as
Sentry
from
'
@sentry/nextjs
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
React
from
'
react
'
;
import
type
{
CsrfData
}
from
'
types/client/account
'
;
export
interface
ErrorType
<
T
>
{
error
?:
T
;
status
:
Response
[
'
status
'
];
statusText
:
Response
[
'
statusText
'
];
}
interface
Params
{
method
?:
RequestInit
[
'
method
'
];
body
?:
Record
<
string
,
unknown
>
;
}
export
default
function
useFetch
()
{
const
queryClient
=
useQueryClient
();
const
{
token
}
=
queryClient
.
getQueryData
<
CsrfData
>
([
'
csrf
'
])
||
{};
return
React
.
useCallback
(<
Success
,
Error
>
(path: string, params?: Params): Promise
<
Success
|
ErrorType
<
Error
>
>
=
>
{
const
reqParams
=
{
...
params
,
body
:
params
?.
method
&&
!
[
'
GET
'
,
'
HEAD
'
].
includes
(
params
.
method
)
?
JSON
.
stringify
({
...
params
?.
body
,
_csrf_token
:
token
})
:
undefined
,
};
return
fetch
(
path
,
reqParams
).
then
(
response
=>
{
if
(
!
response
.
ok
)
{
return
response
.
json
().
then
(
(
jsonError
)
=>
Promise
.
reject
({
error
:
jsonError
as
Error
,
status
:
response
.
status
,
statusText
:
response
.
statusText
,
}),
()
=>
{
const
error
=
{
status
:
response
.
status
,
statusText
:
response
.
statusText
,
};
Sentry
.
captureException
(
new
Error
(
'
Client fetch failed
'
),
{
extra
:
error
,
tags
:
{
source
:
'
fetch
'
}
});
return
Promise
.
reject
(
error
);
},
);
}
else
{
return
response
.
json
()
as
Promise
<
Success
>
;
}
});
}
, [ token ]);
}
lib/hooks/useFetchProfileInfo.tsx
View file @
04ca8bcc
...
@@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query';
...
@@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query';
import
type
{
UserInfo
}
from
'
types/api/account
'
;
import
type
{
UserInfo
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
interface
Error
{
interface
Error
{
error
?:
{
error
?:
{
...
@@ -12,6 +12,8 @@ interface Error {
...
@@ -12,6 +12,8 @@ interface Error {
}
}
export
default
function
useFetchProfileInfo
()
{
export
default
function
useFetchProfileInfo
()
{
const
fetch
=
useFetch
();
return
useQuery
<
unknown
,
Error
,
UserInfo
>
([
'
profile
'
],
async
()
=>
{
return
useQuery
<
unknown
,
Error
,
UserInfo
>
([
'
profile
'
],
async
()
=>
{
return
fetch
(
'
/api/account/profile
'
);
return
fetch
(
'
/api/account/profile
'
);
},
{
},
{
...
...
pages/api/account/csrf/index.ts
0 → 100644
View file @
04ca8bcc
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'
next
'
;
import
fetchFactory
from
'
lib/api/fetch
'
;
import
getUrlWithNetwork
from
'
lib/api/getUrlWithNetwork
'
;
export
default
async
function
csrfHandler
(
_req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
const
url
=
getUrlWithNetwork
(
_req
,
`api/account/v1/get_csrf`
);
const
fetch
=
fetchFactory
(
_req
);
const
response
=
await
fetch
(
url
);
if
(
response
.
status
===
200
)
{
const
token
=
response
.
headers
.
get
(
'
x-bs-account-csrf
'
);
res
.
status
(
200
).
json
({
token
});
return
;
}
res
.
status
(
500
).
json
({
statusText
:
response
.
statusText
,
status
:
response
.
status
});
}
types/client/account.ts
View file @
04ca8bcc
...
@@ -3,3 +3,7 @@ import type { WatchlistAddress } from '../api/account';
...
@@ -3,3 +3,7 @@ import type { WatchlistAddress } from '../api/account';
export
type
TWatchlistItem
=
WatchlistAddress
&
{
tokens_count
:
number
};
export
type
TWatchlistItem
=
WatchlistAddress
&
{
tokens_count
:
number
};
export
type
TWatchlist
=
Array
<
TWatchlistItem
>
;
export
type
TWatchlist
=
Array
<
TWatchlistItem
>
;
export
interface
CsrfData
{
token
:
string
;
}
ui/apiKey/ApiKeyModal/ApiKeyForm.tsx
View file @
04ca8bcc
...
@@ -13,10 +13,10 @@ import { useForm, Controller } from 'react-hook-form';
...
@@ -13,10 +13,10 @@ import { useForm, Controller } from 'react-hook-form';
import
type
{
ApiKey
,
ApiKeys
,
ApiKeyErrors
}
from
'
types/api/account
'
;
import
type
{
ApiKey
,
ApiKeys
,
ApiKeyErrors
}
from
'
types/api/account
'
;
import
type
{
ErrorType
}
from
'
lib/client/fetch
'
;
import
fetch
from
'
lib/client/fetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getPlaceholderWithError
from
'
lib/getPlaceholderWithError
'
;
import
getPlaceholderWithError
from
'
lib/getPlaceholderWithError
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
type
Props
=
{
type
Props
=
{
data
?:
ApiKey
;
data
?:
ApiKey
;
...
@@ -39,11 +39,12 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -39,11 +39,12 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
name
:
data
?.
name
||
''
,
name
:
data
?.
name
||
''
,
},
},
});
});
const
fetch
=
useFetch
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
formBackgroundColor
=
useColorModeValue
(
'
white
'
,
'
gray.900
'
);
const
formBackgroundColor
=
useColorModeValue
(
'
white
'
,
'
gray.900
'
);
const
updateApiKey
=
(
data
:
Inputs
)
=>
{
const
updateApiKey
=
(
data
:
Inputs
)
=>
{
const
body
=
JSON
.
stringify
({
name
:
data
.
name
})
;
const
body
=
{
name
:
data
.
name
}
;
if
(
!
data
.
token
)
{
if
(
!
data
.
token
)
{
return
fetch
(
'
/api/account/api-keys
'
,
{
method
:
'
POST
'
,
body
});
return
fetch
(
'
/api/account/api-keys
'
,
{
method
:
'
POST
'
,
body
});
...
...
ui/apiKey/DeleteApiKeyModal.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback } from 'react';
import
type
{
ApiKey
,
ApiKeys
}
from
'
types/api/account
'
;
import
type
{
ApiKey
,
ApiKeys
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
type
Props
=
{
type
Props
=
{
...
@@ -15,10 +15,11 @@ type Props = {
...
@@ -15,10 +15,11 @@ type Props = {
const
DeleteAddressModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClose
,
data
})
=>
{
const
DeleteAddressModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClose
,
data
})
=>
{
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
fetch
=
useFetch
();
const
mutationFn
=
useCallback
(()
=>
{
const
mutationFn
=
useCallback
(()
=>
{
return
fetch
(
`/api/account/api-keys/
${
data
.
api_key
}
`
,
{
method
:
'
DELETE
'
});
return
fetch
(
`/api/account/api-keys/
${
data
.
api_key
}
`
,
{
method
:
'
DELETE
'
});
},
[
data
]);
},
[
data
.
api_key
,
fetch
]);
const
onSuccess
=
useCallback
(
async
()
=>
{
const
onSuccess
=
useCallback
(
async
()
=>
{
queryClient
.
setQueryData
([
'
api-keys
'
],
(
prevData
:
ApiKeys
|
undefined
)
=>
{
queryClient
.
setQueryData
([
'
api-keys
'
],
(
prevData
:
ApiKeys
|
undefined
)
=>
{
...
...
ui/customAbi/CustomAbiModal/CustomAbiForm.tsx
View file @
04ca8bcc
...
@@ -14,10 +14,10 @@ import { useForm, Controller } from 'react-hook-form';
...
@@ -14,10 +14,10 @@ import { useForm, Controller } from 'react-hook-form';
import
type
{
CustomAbi
,
CustomAbis
,
CustomAbiErrors
}
from
'
types/api/account
'
;
import
type
{
CustomAbi
,
CustomAbis
,
CustomAbiErrors
}
from
'
types/api/account
'
;
import
type
{
ErrorType
}
from
'
lib/client/fetch
'
;
import
fetch
from
'
lib/client/fetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getPlaceholderWithError
from
'
lib/getPlaceholderWithError
'
;
import
getPlaceholderWithError
from
'
lib/getPlaceholderWithError
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
{
ADDRESS_REGEXP
}
from
'
lib/validations/address
'
;
import
{
ADDRESS_REGEXP
}
from
'
lib/validations/address
'
;
import
AddressInput
from
'
ui/shared/AddressInput
'
;
import
AddressInput
from
'
ui/shared/AddressInput
'
;
...
@@ -46,9 +46,10 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -46,9 +46,10 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
});
});
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
fetch
=
useFetch
();
const
customAbiKey
=
(
data
:
Inputs
&
{
id
?:
number
})
=>
{
const
customAbiKey
=
(
data
:
Inputs
&
{
id
?:
number
})
=>
{
const
body
=
JSON
.
stringify
({
name
:
data
.
name
,
contract_address_hash
:
data
.
contract_address_hash
,
abi
:
data
.
abi
})
;
const
body
=
{
name
:
data
.
name
,
contract_address_hash
:
data
.
contract_address_hash
,
abi
:
data
.
abi
}
;
if
(
!
data
.
id
)
{
if
(
!
data
.
id
)
{
return
fetch
<
CustomAbi
,
CustomAbiErrors
>
(
'
/api/account/custom-abis
'
,
{
method
:
'
POST
'
,
body
});
return
fetch
<
CustomAbi
,
CustomAbiErrors
>
(
'
/api/account/custom-abis
'
,
{
method
:
'
POST
'
,
body
});
...
...
ui/pages/ApiKeys.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
import
type
{
ApiKey
,
ApiKeys
}
from
'
types/api/account
'
;
import
type
{
ApiKey
,
ApiKeys
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
ApiKeyModal
from
'
ui/apiKey/ApiKeyModal/ApiKeyModal
'
;
import
ApiKeyModal
from
'
ui/apiKey/ApiKeyModal/ApiKeyModal
'
;
...
@@ -25,6 +25,7 @@ const ApiKeysPage: React.FC = () => {
...
@@ -25,6 +25,7 @@ const ApiKeysPage: React.FC = () => {
const
apiKeyModalProps
=
useDisclosure
();
const
apiKeyModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
[
apiKeyModalData
,
setApiKeyModalData
]
=
useState
<
ApiKey
>
();
const
[
apiKeyModalData
,
setApiKeyModalData
]
=
useState
<
ApiKey
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
ApiKey
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
ApiKey
>
();
...
...
ui/pages/CustomAbi.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
import
type
{
CustomAbi
,
CustomAbis
}
from
'
types/api/account
'
;
import
type
{
CustomAbi
,
CustomAbis
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
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
'
;
...
@@ -22,6 +22,7 @@ const CustomAbiPage: React.FC = () => {
...
@@ -22,6 +22,7 @@ const CustomAbiPage: React.FC = () => {
const
customAbiModalProps
=
useDisclosure
();
const
customAbiModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
[
customAbiModalData
,
setCustomAbiModalData
]
=
useState
<
CustomAbi
>
();
const
[
customAbiModalData
,
setCustomAbiModalData
]
=
useState
<
CustomAbi
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
CustomAbi
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
CustomAbi
>
();
...
...
ui/pages/Watchlist.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
import
type
{
TWatchlist
,
TWatchlistItem
}
from
'
types/client/account
'
;
import
type
{
TWatchlist
,
TWatchlistItem
}
from
'
types/client/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
...
@@ -24,6 +24,7 @@ const WatchList: React.FC = () => {
...
@@ -24,6 +24,7 @@ const WatchList: React.FC = () => {
const
addressModalProps
=
useDisclosure
();
const
addressModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
[
addressModalData
,
setAddressModalData
]
=
useState
<
TWatchlistItem
>
();
const
[
addressModalData
,
setAddressModalData
]
=
useState
<
TWatchlistItem
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
TWatchlistItem
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
TWatchlistItem
>
();
...
...
ui/privateTags/AddressModal/AddressForm.tsx
View file @
04ca8bcc
...
@@ -10,9 +10,9 @@ import { useForm, Controller } from 'react-hook-form';
...
@@ -10,9 +10,9 @@ import { useForm, Controller } from 'react-hook-form';
import
type
{
AddressTag
,
AddressTagErrors
}
from
'
types/api/account
'
;
import
type
{
AddressTag
,
AddressTagErrors
}
from
'
types/api/account
'
;
import
type
{
ErrorType
}
from
'
lib/client/fetch
'
;
import
fetch
from
'
lib/client/fetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
{
ADDRESS_REGEXP
}
from
'
lib/validations/address
'
;
import
{
ADDRESS_REGEXP
}
from
'
lib/validations/address
'
;
import
AddressInput
from
'
ui/shared/AddressInput
'
;
import
AddressInput
from
'
ui/shared/AddressInput
'
;
import
TagInput
from
'
ui/shared/TagInput
'
;
import
TagInput
from
'
ui/shared/TagInput
'
;
...
@@ -31,6 +31,7 @@ type Inputs = {
...
@@ -31,6 +31,7 @@ type Inputs = {
}
}
const
AddressForm
:
React
.
FC
<
Props
>
=
({
data
,
onClose
,
setAlertVisible
})
=>
{
const
AddressForm
:
React
.
FC
<
Props
>
=
({
data
,
onClose
,
setAlertVisible
})
=>
{
const
fetch
=
useFetch
();
const
[
pending
,
setPending
]
=
useState
(
false
);
const
[
pending
,
setPending
]
=
useState
(
false
);
const
{
control
,
handleSubmit
,
formState
:
{
errors
,
isValid
},
setError
}
=
useForm
<
Inputs
>
({
const
{
control
,
handleSubmit
,
formState
:
{
errors
,
isValid
},
setError
}
=
useForm
<
Inputs
>
({
mode
:
'
all
'
,
mode
:
'
all
'
,
...
@@ -45,10 +46,10 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -45,10 +46,10 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
{
mutate
}
=
useMutation
((
formData
:
Inputs
)
=>
{
const
{
mutate
}
=
useMutation
((
formData
:
Inputs
)
=>
{
const
body
=
JSON
.
stringify
(
{
const
body
=
{
name
:
formData
?.
tag
,
name
:
formData
?.
tag
,
address_hash
:
formData
?.
address
,
address_hash
:
formData
?.
address
,
}
)
;
};
const
isEdit
=
data
?.
id
;
const
isEdit
=
data
?.
id
;
if
(
isEdit
)
{
if
(
isEdit
)
{
...
...
ui/privateTags/DeletePrivateTagModal.tsx
View file @
04ca8bcc
...
@@ -4,6 +4,7 @@ import React, { useCallback } from 'react';
...
@@ -4,6 +4,7 @@ import React, { useCallback } from 'react';
import
type
{
AddressTag
,
TransactionTag
,
AddressTags
,
TransactionTags
}
from
'
types/api/account
'
;
import
type
{
AddressTag
,
TransactionTag
,
AddressTags
,
TransactionTags
}
from
'
types/api/account
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
type
Props
=
{
type
Props
=
{
...
@@ -18,18 +19,19 @@ const DeletePrivateTagModal: React.FC<Props> = ({ isOpen, onClose, data, type })
...
@@ -18,18 +19,19 @@ const DeletePrivateTagModal: React.FC<Props> = ({ isOpen, onClose, data, type })
const
id
=
data
.
id
;
const
id
=
data
.
id
;
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
fetch
=
useFetch
();
const
mutationFn
=
useCallback
(()
=>
{
const
mutationFn
=
useCallback
(()
=>
{
return
fetch
(
`/api/account/private-tags/
${
type
}
/
${
id
}
`
,
{
method
:
'
DELETE
'
});
return
fetch
(
`/api/account/private-tags/
${
type
}
/
${
id
}
`
,
{
method
:
'
DELETE
'
});
},
[
type
,
id
]);
},
[
fetch
,
type
,
id
]);
const
onSuccess
=
useCallback
(
async
()
=>
{
const
onSuccess
=
useCallback
(
async
()
=>
{
if
(
type
===
'
address
'
)
{
if
(
type
===
'
address
'
)
{
queryClient
.
setQueryData
([
type
],
(
prevData
:
AddressTags
|
undefined
)
=>
{
queryClient
.
setQueryData
([
'
address-tags
'
],
(
prevData
:
AddressTags
|
undefined
)
=>
{
return
prevData
?.
filter
((
item
:
AddressTag
)
=>
item
.
id
!==
id
);
return
prevData
?.
filter
((
item
:
AddressTag
)
=>
item
.
id
!==
id
);
});
});
}
else
{
}
else
{
queryClient
.
setQueryData
([
type
],
(
prevData
:
TransactionTags
|
undefined
)
=>
{
queryClient
.
setQueryData
([
'
transaction-tags
'
],
(
prevData
:
TransactionTags
|
undefined
)
=>
{
return
prevData
?.
filter
((
item
:
TransactionTag
)
=>
item
.
id
!==
id
);
return
prevData
?.
filter
((
item
:
TransactionTag
)
=>
item
.
id
!==
id
);
});
});
}
}
...
...
ui/privateTags/PrivateAddressTags.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
import
type
{
AddressTags
,
AddressTag
}
from
'
types/api/account
'
;
import
type
{
AddressTags
,
AddressTag
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
...
@@ -23,6 +23,7 @@ const PrivateAddressTags = () => {
...
@@ -23,6 +23,7 @@ const PrivateAddressTags = () => {
const
addressModalProps
=
useDisclosure
();
const
addressModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
[
addressModalData
,
setAddressModalData
]
=
useState
<
AddressTag
>
();
const
[
addressModalData
,
setAddressModalData
]
=
useState
<
AddressTag
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
AddressTag
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
AddressTag
>
();
...
...
ui/privateTags/PrivateTransactionTags.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
import
type
{
TransactionTags
,
TransactionTag
}
from
'
types/api/account
'
;
import
type
{
TransactionTags
,
TransactionTag
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
...
@@ -23,6 +23,7 @@ const PrivateTransactionTags = () => {
...
@@ -23,6 +23,7 @@ const PrivateTransactionTags = () => {
const
transactionModalProps
=
useDisclosure
();
const
transactionModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
[
transactionModalData
,
setTransactionModalData
]
=
useState
<
TransactionTag
>
();
const
[
transactionModalData
,
setTransactionModalData
]
=
useState
<
TransactionTag
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
TransactionTag
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
TransactionTag
>
();
...
...
ui/privateTags/TransactionModal/TransactionForm.tsx
View file @
04ca8bcc
...
@@ -10,9 +10,9 @@ import { useForm, Controller } from 'react-hook-form';
...
@@ -10,9 +10,9 @@ import { useForm, Controller } from 'react-hook-form';
import
type
{
TransactionTag
,
TransactionTagErrors
}
from
'
types/api/account
'
;
import
type
{
TransactionTag
,
TransactionTagErrors
}
from
'
types/api/account
'
;
import
type
{
ErrorType
}
from
'
lib/client/fetch
'
;
import
fetch
from
'
lib/client/fetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
{
TRANSACTION_HASH_REGEXP
}
from
'
lib/validations/transaction
'
;
import
{
TRANSACTION_HASH_REGEXP
}
from
'
lib/validations/transaction
'
;
import
TagInput
from
'
ui/shared/TagInput
'
;
import
TagInput
from
'
ui/shared/TagInput
'
;
import
TransactionInput
from
'
ui/shared/TransactionInput
'
;
import
TransactionInput
from
'
ui/shared/TransactionInput
'
;
...
@@ -43,12 +43,13 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
...
@@ -43,12 +43,13 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
});
});
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
fetch
=
useFetch
();
const
{
mutate
}
=
useMutation
((
formData
:
Inputs
)
=>
{
const
{
mutate
}
=
useMutation
((
formData
:
Inputs
)
=>
{
const
body
=
JSON
.
stringify
(
{
const
body
=
{
name
:
formData
?.
tag
,
name
:
formData
?.
tag
,
transaction_hash
:
formData
?.
transaction
,
transaction_hash
:
formData
?.
transaction
,
}
)
;
};
const
isEdit
=
data
?.
id
;
const
isEdit
=
data
?.
id
;
if
(
isEdit
)
{
if
(
isEdit
)
{
...
...
ui/publicTags/DeletePublicTagModal.tsx
View file @
04ca8bcc
...
@@ -5,7 +5,7 @@ import type { ChangeEvent } from 'react';
...
@@ -5,7 +5,7 @@ import type { ChangeEvent } from 'react';
import
type
{
PublicTags
,
PublicTag
}
from
'
types/api/account
'
;
import
type
{
PublicTags
,
PublicTag
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
type
Props
=
{
type
Props
=
{
...
@@ -22,12 +22,13 @@ const DeletePublicTagModal: React.FC<Props> = ({ isOpen, onClose, data, onDelete
...
@@ -22,12 +22,13 @@ const DeletePublicTagModal: React.FC<Props> = ({ isOpen, onClose, data, onDelete
const
tags
=
data
.
tags
.
split
(
'
;
'
);
const
tags
=
data
.
tags
.
split
(
'
;
'
);
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
fetch
=
useFetch
();
const
formBackgroundColor
=
useColorModeValue
(
'
white
'
,
'
gray.900
'
);
const
formBackgroundColor
=
useColorModeValue
(
'
white
'
,
'
gray.900
'
);
const
deleteApiKey
=
useCallback
(()
=>
{
const
deleteApiKey
=
useCallback
(()
=>
{
const
body
=
JSON
.
stringify
({
remove_reason
:
reason
})
;
const
body
=
{
remove_reason
:
reason
}
;
return
fetch
(
`/api/account/public-tags/
${
data
.
id
}
`
,
{
method
:
'
DELETE
'
,
body
});
return
fetch
(
`/api/account/public-tags/
${
data
.
id
}
`
,
{
method
:
'
DELETE
'
,
body
});
},
[
data
,
reason
]);
},
[
data
.
id
,
fetch
,
reason
]);
const
onSuccess
=
useCallback
(
async
()
=>
{
const
onSuccess
=
useCallback
(
async
()
=>
{
onDeleteSuccess
();
onDeleteSuccess
();
...
...
ui/publicTags/PublicTagsData.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react';
import
type
{
PublicTags
,
PublicTag
}
from
'
types/api/account
'
;
import
type
{
PublicTags
,
PublicTag
}
from
'
types/api/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
PublicTagListItem
from
'
ui/publicTags/PublicTagTable/PublicTagListItem
'
;
import
PublicTagListItem
from
'
ui/publicTags/PublicTagTable/PublicTagListItem
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
...
@@ -24,6 +24,7 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
...
@@ -24,6 +24,7 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
const
deleteModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
PublicTag
>
();
const
[
deleteModalData
,
setDeleteModalData
]
=
useState
<
PublicTag
>
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
PublicTags
>
([
'
public-tags
'
],
async
()
=>
await
fetch
(
'
/api/account/public-tags
'
));
const
{
data
,
isLoading
,
isError
}
=
useQuery
<
unknown
,
unknown
,
PublicTags
>
([
'
public-tags
'
],
async
()
=>
await
fetch
(
'
/api/account/public-tags
'
));
...
...
ui/publicTags/PublicTagsForm/PublicTagsForm.tsx
View file @
04ca8bcc
...
@@ -13,9 +13,9 @@ import { useForm, useFieldArray } from 'react-hook-form';
...
@@ -13,9 +13,9 @@ import { useForm, useFieldArray } from 'react-hook-form';
import
type
{
PublicTags
,
PublicTag
,
PublicTagNew
,
PublicTagErrors
}
from
'
types/api/account
'
;
import
type
{
PublicTags
,
PublicTag
,
PublicTagNew
,
PublicTagErrors
}
from
'
types/api/account
'
;
import
type
{
ErrorType
}
from
'
lib/client/fetch
'
;
import
fetch
from
'
lib/client/fetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
{
EMAIL_REGEXP
}
from
'
lib/validations/email
'
;
import
{
EMAIL_REGEXP
}
from
'
lib/validations/email
'
;
import
FormSubmitAlert
from
'
ui/shared/FormSubmitAlert
'
;
import
FormSubmitAlert
from
'
ui/shared/FormSubmitAlert
'
;
...
@@ -58,6 +58,7 @@ const ADDRESS_INPUT_BUTTONS_WIDTH = 100;
...
@@ -58,6 +58,7 @@ const ADDRESS_INPUT_BUTTONS_WIDTH = 100;
const
PublicTagsForm
=
({
changeToDataScreen
,
data
}:
Props
)
=>
{
const
PublicTagsForm
=
({
changeToDataScreen
,
data
}:
Props
)
=>
{
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
inputSize
=
isMobile
?
'
md
'
:
'
lg
'
;
const
inputSize
=
isMobile
?
'
md
'
:
'
lg
'
;
const
{
control
,
handleSubmit
,
formState
:
{
errors
,
isValid
},
setError
}
=
useForm
<
Inputs
>
({
const
{
control
,
handleSubmit
,
formState
:
{
errors
,
isValid
},
setError
}
=
useForm
<
Inputs
>
({
...
@@ -87,7 +88,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
...
@@ -87,7 +88,7 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
const
onRemoveFieldClick
=
useCallback
((
index
:
number
)
=>
()
=>
remove
(
index
),
[
remove
]);
const
onRemoveFieldClick
=
useCallback
((
index
:
number
)
=>
()
=>
remove
(
index
),
[
remove
]);
const
updatePublicTag
=
(
formData
:
Inputs
)
=>
{
const
updatePublicTag
=
(
formData
:
Inputs
)
=>
{
const
payload
:
PublicTagNew
=
{
const
body
:
PublicTagNew
=
{
full_name
:
formData
.
fullName
||
''
,
full_name
:
formData
.
fullName
||
''
,
email
:
formData
.
email
||
''
,
email
:
formData
.
email
||
''
,
company
:
formData
.
companyName
||
''
,
company
:
formData
.
companyName
||
''
,
...
@@ -97,7 +98,6 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
...
@@ -97,7 +98,6 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
tags
:
formData
.
tags
?.
split
(
'
;
'
).
map
((
s
)
=>
s
.
trim
()).
join
(
'
;
'
)
||
''
,
tags
:
formData
.
tags
?.
split
(
'
;
'
).
map
((
s
)
=>
s
.
trim
()).
join
(
'
;
'
)
||
''
,
additional_comment
:
formData
.
comment
||
''
,
additional_comment
:
formData
.
comment
||
''
,
};
};
const
body
=
JSON
.
stringify
(
payload
);
if
(
!
data
?.
id
)
{
if
(
!
data
?.
id
)
{
return
fetch
<
PublicTag
,
PublicTagErrors
>
(
'
/api/account/public-tags
'
,
{
method
:
'
POST
'
,
body
});
return
fetch
<
PublicTag
,
PublicTagErrors
>
(
'
/api/account/public-tags
'
,
{
method
:
'
POST
'
,
body
});
...
...
ui/shared/Page.tsx
View file @
04ca8bcc
import
{
Box
,
HStack
,
VStack
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
HStack
,
VStack
}
from
'
@chakra-ui/react
'
;
import
{
useQuery
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
*
as
cookies
from
'
lib/cookies
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
Header
from
'
ui/blocks/header/Header
'
;
import
Header
from
'
ui/blocks/header/Header
'
;
import
NavigationDesktop
from
'
ui/blocks/navigation/NavigationDesktop
'
;
import
NavigationDesktop
from
'
ui/blocks/navigation/NavigationDesktop
'
;
...
@@ -14,9 +16,13 @@ interface Props {
...
@@ -14,9 +16,13 @@ interface Props {
const
Page
=
({
children
}:
Props
)
=>
{
const
Page
=
({
children
}:
Props
)
=>
{
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
fetch
=
useFetch
();
const
networkType
=
router
.
query
.
network_type
;
const
networkType
=
router
.
query
.
network_type
;
const
networkSubType
=
router
.
query
.
network_sub_type
;
const
networkSubType
=
router
.
query
.
network_sub_type
;
useQuery
<
unknown
,
unknown
,
unknown
>
([
'
csrf
'
],
async
()
=>
await
fetch
(
'
/api/account/csrf
'
));
React
.
useEffect
(()
=>
{
React
.
useEffect
(()
=>
{
if
(
typeof
networkType
===
'
string
'
)
{
if
(
typeof
networkType
===
'
string
'
)
{
cookies
.
set
(
cookies
.
NAMES
.
NETWORK_TYPE
,
networkType
);
cookies
.
set
(
cookies
.
NAMES
.
NETWORK_TYPE
,
networkType
);
...
...
ui/watchlist/AddressModal/AddressForm.tsx
View file @
04ca8bcc
...
@@ -12,9 +12,9 @@ import { useForm, Controller } from 'react-hook-form';
...
@@ -12,9 +12,9 @@ import { useForm, Controller } from 'react-hook-form';
import
type
{
WatchlistErrors
}
from
'
types/api/account
'
;
import
type
{
WatchlistErrors
}
from
'
types/api/account
'
;
import
type
{
TWatchlistItem
}
from
'
types/client/account
'
;
import
type
{
TWatchlistItem
}
from
'
types/client/account
'
;
import
type
{
ErrorType
}
from
'
lib/client/fetch
'
;
import
fetch
from
'
lib/client/fetch
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
getErrorMessage
from
'
lib/getErrorMessage
'
;
import
type
{
ErrorType
}
from
'
lib/hooks/useFetch
'
;
import
useFetch
from
'
lib/hooks/useFetch
'
;
import
{
ADDRESS_REGEXP
}
from
'
lib/validations/address
'
;
import
{
ADDRESS_REGEXP
}
from
'
lib/validations/address
'
;
import
AddressInput
from
'
ui/shared/AddressInput
'
;
import
AddressInput
from
'
ui/shared/AddressInput
'
;
import
CheckboxInput
from
'
ui/shared/CheckboxInput
'
;
import
CheckboxInput
from
'
ui/shared/CheckboxInput
'
;
...
@@ -83,9 +83,10 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -83,9 +83,10 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
});
});
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
fetch
=
useFetch
();
function
updateWatchlist
(
formData
:
Inputs
)
{
function
updateWatchlist
(
formData
:
Inputs
)
{
const
requestParams
=
{
const
body
=
{
name
:
formData
?.
tag
,
name
:
formData
?.
tag
,
address_hash
:
formData
?.
address
,
address_hash
:
formData
?.
address
,
notification_settings
:
formData
.
notification_settings
,
notification_settings
:
formData
.
notification_settings
,
...
@@ -95,11 +96,11 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
...
@@ -95,11 +96,11 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
};
};
if
(
data
)
{
if
(
data
)
{
// edit address
// edit address
return
fetch
<
TWatchlistItem
,
WatchlistErrors
>
(
`/api/account/watchlist/
${
data
.
id
}
`
,
{
method
:
'
PUT
'
,
body
:
JSON
.
stringify
(
requestParams
)
});
return
fetch
<
TWatchlistItem
,
WatchlistErrors
>
(
`/api/account/watchlist/
${
data
.
id
}
`
,
{
method
:
'
PUT
'
,
body
});
}
else
{
}
else
{
// add address
// add address
return
fetch
<
TWatchlistItem
,
WatchlistErrors
>
(
'
/api/account/watchlist
'
,
{
method
:
'
POST
'
,
body
:
JSON
.
stringify
(
requestParams
)
});
return
fetch
<
TWatchlistItem
,
WatchlistErrors
>
(
'
/api/account/watchlist
'
,
{
method
:
'
POST
'
,
body
});
}
}
}
}
...
...
ui/watchlist/DeleteAddressModal.tsx
View file @
04ca8bcc
...
@@ -4,7 +4,7 @@ import React, { useCallback } from 'react';
...
@@ -4,7 +4,7 @@ import React, { useCallback } from 'react';
import
type
{
TWatchlistItem
,
TWatchlist
}
from
'
types/client/account
'
;
import
type
{
TWatchlistItem
,
TWatchlist
}
from
'
types/client/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
import
DeleteModal
from
'
ui/shared/DeleteModal
'
;
...
@@ -17,10 +17,11 @@ type Props = {
...
@@ -17,10 +17,11 @@ type Props = {
const
DeleteAddressModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClose
,
data
})
=>
{
const
DeleteAddressModal
:
React
.
FC
<
Props
>
=
({
isOpen
,
onClose
,
data
})
=>
{
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
isMobile
=
useIsMobile
();
const
isMobile
=
useIsMobile
();
const
fetch
=
useFetch
();
const
mutationFn
=
useCallback
(()
=>
{
const
mutationFn
=
useCallback
(()
=>
{
return
fetch
(
`/api/account1/watchlist/
${
data
?.
id
}
`, { method: 'DELETE' });
return
fetch
(
`/api/account1/watchlist/
${
data
?.
id
}
`, { method: 'DELETE' });
}, [ data ]);
}, [ data
?.id, fetch
]);
const onSuccess = useCallback(async() => {
const onSuccess = useCallback(async() => {
queryClient.setQueryData([ 'watchlist' ], (prevData: TWatchlist | undefined) => {
queryClient.setQueryData([ 'watchlist' ], (prevData: TWatchlist | undefined) => {
...
...
ui/watchlist/WatchlistTable/WatchListTableItem.tsx
View file @
04ca8bcc
...
@@ -9,7 +9,7 @@ import React, { useCallback, useState } from 'react';
...
@@ -9,7 +9,7 @@ import React, { useCallback, useState } from 'react';
import
type
{
TWatchlistItem
}
from
'
types/client/account
'
;
import
type
{
TWatchlistItem
}
from
'
types/client/account
'
;
import
fetch
from
'
lib/client/f
etch
'
;
import
useFetch
from
'
lib/hooks/useF
etch
'
;
import
useToast
from
'
lib/hooks/useToast
'
;
import
useToast
from
'
lib/hooks/useToast
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
import
TableItemActionButtons
from
'
ui/shared/TableItemActionButtons
'
;
import
TruncatedTextTooltip
from
'
ui/shared/TruncatedTextTooltip
'
;
import
TruncatedTextTooltip
from
'
ui/shared/TruncatedTextTooltip
'
;
...
@@ -34,6 +34,7 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
...
@@ -34,6 +34,7 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
},
[
item
,
onDeleteClick
]);
},
[
item
,
onDeleteClick
]);
const
toast
=
useToast
();
const
toast
=
useToast
();
const
fetch
=
useFetch
();
const
showToast
=
useCallback
(()
=>
{
const
showToast
=
useCallback
(()
=>
{
toast
({
toast
({
...
@@ -49,9 +50,9 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
...
@@ -49,9 +50,9 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
const
{
mutate
}
=
useMutation
(()
=>
{
const
{
mutate
}
=
useMutation
(()
=>
{
setSwitchDisabled
(
true
);
setSwitchDisabled
(
true
);
const
data
=
{
...
item
,
notification_methods
:
{
email
:
!
notificationEnabled
}
};
const
body
=
{
...
item
,
notification_methods
:
{
email
:
!
notificationEnabled
}
};
setNotificationEnabled
(
prevState
=>
!
prevState
);
setNotificationEnabled
(
prevState
=>
!
prevState
);
return
fetch
(
`/api/account1/watchlist/
${
item
.
id
}
`
,
{
method
:
'
PUT
'
,
body
:
JSON
.
stringify
(
data
)
});
return
fetch
(
`/api/account1/watchlist/
${
item
.
id
}
`
,
{
method
:
'
PUT
'
,
body
});
},
{
},
{
onError
:
()
=>
{
onError
:
()
=>
{
showToast
();
showToast
();
...
...
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