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
9837acc2
Commit
9837acc2
authored
Sep 20, 2024
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add auth guard to address action items
parent
b98271b6
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
122 additions
and
91 deletions
+122
-91
useIsAccountActionAllowed.tsx
lib/hooks/useIsAccountActionAllowed.tsx
+0
-8
AddressFavoriteButton.tsx
ui/address/details/AddressFavoriteButton.tsx
+24
-24
AccountActionsMenu.tsx
ui/shared/AccountActionsMenu/AccountActionsMenu.tsx
+2
-4
PrivateTagMenuItem.tsx
ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx
+17
-14
PublicTagMenuItem.tsx
ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx
+14
-22
TokenInfoMenuItem.tsx
ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx
+18
-15
types.ts
ui/shared/AccountActionsMenu/types.ts
+0
-2
AuthGuard.tsx
ui/snippets/auth/AuthGuard.tsx
+39
-0
AuthModal.tsx
ui/snippets/auth/AuthModal.tsx
+8
-2
No files found.
lib/hooks/useIsAccountActionAllowed.tsx
deleted
100644 → 0
View file @
b98271b6
import
React
from
'
react
'
;
// TODO @tom2drum remove this hook
export
default
function
useIsAccountActionAllowed
()
{
return
React
.
useCallback
(()
=>
{
return
true
;
},
[]);
}
ui/address/details/AddressFavoriteButton.tsx
View file @
9837acc2
...
@@ -5,10 +5,10 @@ import React from 'react';
...
@@ -5,10 +5,10 @@ import React from 'react';
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
useIsAccountActionAllowed
from
'
lib/hooks/useIsAccountActionAllowed
'
;
import
usePreventFocusAfterModalClosing
from
'
lib/hooks/usePreventFocusAfterModalClosing
'
;
import
usePreventFocusAfterModalClosing
from
'
lib/hooks/usePreventFocusAfterModalClosing
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
AuthGuard
from
'
ui/snippets/auth/AuthGuard
'
;
import
WatchlistAddModal
from
'
ui/watchlist/AddressModal/AddressModal
'
;
import
WatchlistAddModal
from
'
ui/watchlist/AddressModal/AddressModal
'
;
import
DeleteAddressModal
from
'
ui/watchlist/DeleteAddressModal
'
;
import
DeleteAddressModal
from
'
ui/watchlist/DeleteAddressModal
'
;
...
@@ -23,16 +23,12 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
...
@@ -23,16 +23,12 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
const
deleteModalProps
=
useDisclosure
();
const
deleteModalProps
=
useDisclosure
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
isAccountActionAllowed
=
useIsAccountActionAllowed
();
const
onFocusCapture
=
usePreventFocusAfterModalClosing
();
const
onFocusCapture
=
usePreventFocusAfterModalClosing
();
const
handleClick
=
React
.
useCallback
(()
=>
{
const
handleAddToFavorite
=
React
.
useCallback
(()
=>
{
if
(
!
isAccountActionAllowed
())
{
return
;
}
watchListId
?
deleteModalProps
.
onOpen
()
:
addModalProps
.
onOpen
();
watchListId
?
deleteModalProps
.
onOpen
()
:
addModalProps
.
onOpen
();
!
watchListId
&&
mixpanel
.
logEvent
(
mixpanel
.
EventTypes
.
PAGE_WIDGET
,
{
Type
:
'
Add to watchlist
'
});
!
watchListId
&&
mixpanel
.
logEvent
(
mixpanel
.
EventTypes
.
PAGE_WIDGET
,
{
Type
:
'
Add to watchlist
'
});
},
[
isAccountActionAllowed
,
watchListId
,
deleteModalProps
,
addModalProps
]);
},
[
watchListId
,
deleteModalProps
,
addModalProps
]);
const
handleAddOrDeleteSuccess
=
React
.
useCallback
(
async
()
=>
{
const
handleAddOrDeleteSuccess
=
React
.
useCallback
(
async
()
=>
{
const
queryKey
=
getResourceKey
(
'
address
'
,
{
pathParams
:
{
hash
:
router
.
query
.
hash
?.
toString
()
}
});
const
queryKey
=
getResourceKey
(
'
address
'
,
{
pathParams
:
{
hash
:
router
.
query
.
hash
?.
toString
()
}
});
...
@@ -50,7 +46,7 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
...
@@ -50,7 +46,7 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
const
formData
=
React
.
useMemo
(()
=>
{
const
formData
=
React
.
useMemo
(()
=>
{
if
(
typeof
watchListId
!==
'
number
'
)
{
if
(
typeof
watchListId
!==
'
number
'
)
{
return
;
return
{
address_hash
:
hash
}
;
}
}
return
{
return
{
...
@@ -65,21 +61,25 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
...
@@ -65,21 +61,25 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
return
(
return
(
<>
<>
<
Tooltip
label=
{
`${ watchListId ? 'Remove address from Watch list' : 'Add address to Watch list' }`
}
>
<
AuthGuard
onAuthSuccess=
{
handleAddToFavorite
}
>
<
IconButton
{
({
onClick
})
=>
(
isActive=
{
Boolean
(
watchListId
)
}
<
Tooltip
label=
{
`${ watchListId ? 'Remove address from Watch list' : 'Add address to Watch list' }`
}
>
className=
{
className
}
<
IconButton
aria
-
label=
"edit"
isActive=
{
Boolean
(
watchListId
)
}
variant=
"outline"
className=
{
className
}
size=
"sm"
aria
-
label=
"edit"
pl=
"6px"
variant=
"outline"
pr=
"6px"
size=
"sm"
flexShrink=
{
0
}
pl=
"6px"
onClick=
{
handleClick
}
pr=
"6px"
icon=
{
<
IconSvg
name=
{
watchListId
?
'
star_filled
'
:
'
star_outline
'
}
boxSize=
{
5
}
/>
}
flexShrink=
{
0
}
onFocusCapture=
{
onFocusCapture
}
onClick=
{
onClick
}
/>
icon=
{
<
IconSvg
name=
{
watchListId
?
'
star_filled
'
:
'
star_outline
'
}
boxSize=
{
5
}
/>
}
</
Tooltip
>
onFocusCapture=
{
onFocusCapture
}
/>
</
Tooltip
>
)
}
</
AuthGuard
>
<
WatchlistAddModal
<
WatchlistAddModal
{
...
addModalProps
}
{
...
addModalProps
}
isAdd
isAdd
...
@@ -87,7 +87,7 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
...
@@ -87,7 +87,7 @@ const AddressFavoriteButton = ({ className, hash, watchListId }: Props) => {
onSuccess=
{
handleAddOrDeleteSuccess
}
onSuccess=
{
handleAddOrDeleteSuccess
}
data=
{
formData
}
data=
{
formData
}
/>
/>
{
formData
&&
(
{
formData
.
id
&&
(
<
DeleteAddressModal
<
DeleteAddressModal
{
...
deleteModalProps
}
{
...
deleteModalProps
}
onClose=
{
handleDeleteModalClose
}
onClose=
{
handleDeleteModalClose
}
...
...
ui/shared/AccountActionsMenu/AccountActionsMenu.tsx
View file @
9837acc2
...
@@ -5,7 +5,6 @@ import React from 'react';
...
@@ -5,7 +5,6 @@ import React from 'react';
import
type
{
ItemProps
}
from
'
./types
'
;
import
type
{
ItemProps
}
from
'
./types
'
;
import
config
from
'
configs/app
'
;
import
config
from
'
configs/app
'
;
import
useIsAccountActionAllowed
from
'
lib/hooks/useIsAccountActionAllowed
'
;
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
Menu
from
'
ui/shared/chakra/Menu
'
;
import
Menu
from
'
ui/shared/chakra/Menu
'
;
...
@@ -30,7 +29,6 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
...
@@ -30,7 +29,6 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
const
isTokenPage
=
router
.
pathname
===
'
/token/[hash]
'
;
const
isTokenPage
=
router
.
pathname
===
'
/token/[hash]
'
;
const
isTokenInstancePage
=
router
.
pathname
===
'
/token/[hash]/instance/[id]
'
;
const
isTokenInstancePage
=
router
.
pathname
===
'
/token/[hash]/instance/[id]
'
;
const
isTxPage
=
router
.
pathname
===
'
/tx/[hash]
'
;
const
isTxPage
=
router
.
pathname
===
'
/tx/[hash]
'
;
const
isAccountActionAllowed
=
useIsAccountActionAllowed
();
const
profileQuery
=
useProfileQuery
();
const
profileQuery
=
useProfileQuery
();
...
@@ -74,7 +72,7 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
...
@@ -74,7 +72,7 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
if
(
items
.
length
===
1
)
{
if
(
items
.
length
===
1
)
{
return
(
return
(
<
Box
className=
{
className
}
>
<
Box
className=
{
className
}
>
{
items
[
0
].
render
({
type
:
'
button
'
,
hash
,
onBeforeClick
:
isAccountActionAllowed
})
}
{
items
[
0
].
render
({
type
:
'
button
'
,
hash
})
}
</
Box
>
</
Box
>
);
);
}
}
...
@@ -95,7 +93,7 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
...
@@ -95,7 +93,7 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
<
MenuList
minWidth=
"180px"
zIndex=
"popover"
>
<
MenuList
minWidth=
"180px"
zIndex=
"popover"
>
{
items
.
map
(({
render
},
index
)
=>
(
{
items
.
map
(({
render
},
index
)
=>
(
<
React
.
Fragment
key=
{
index
}
>
<
React
.
Fragment
key=
{
index
}
>
{
render
({
type
:
'
menu_item
'
,
hash
,
onBeforeClick
:
isAccountActionAllowed
})
}
{
render
({
type
:
'
menu_item
'
,
hash
})
}
</
React
.
Fragment
>
</
React
.
Fragment
>
))
}
))
}
</
MenuList
>
</
MenuList
>
...
...
ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx
View file @
9837acc2
...
@@ -12,6 +12,7 @@ import getPageType from 'lib/mixpanel/getPageType';
...
@@ -12,6 +12,7 @@ import getPageType from 'lib/mixpanel/getPageType';
import
AddressModal
from
'
ui/privateTags/AddressModal/AddressModal
'
;
import
AddressModal
from
'
ui/privateTags/AddressModal/AddressModal
'
;
import
TransactionModal
from
'
ui/privateTags/TransactionModal/TransactionModal
'
;
import
TransactionModal
from
'
ui/privateTags/TransactionModal/TransactionModal
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
AuthGuard
from
'
ui/snippets/auth/AuthGuard
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
...
@@ -20,7 +21,7 @@ interface Props extends ItemProps {
...
@@ -20,7 +21,7 @@ interface Props extends ItemProps {
entityType
?:
'
address
'
|
'
tx
'
;
entityType
?:
'
address
'
|
'
tx
'
;
}
}
const
PrivateTagMenuItem
=
({
className
,
hash
,
onBeforeClick
,
entityType
=
'
address
'
,
type
}:
Props
)
=>
{
const
PrivateTagMenuItem
=
({
className
,
hash
,
entityType
=
'
address
'
,
type
}:
Props
)
=>
{
const
modal
=
useDisclosure
();
const
modal
=
useDisclosure
();
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
const
router
=
useRouter
();
...
@@ -28,14 +29,6 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, entityType = 'addr
...
@@ -28,14 +29,6 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, entityType = 'addr
const
queryKey
=
getResourceKey
(
entityType
===
'
tx
'
?
'
tx
'
:
'
address
'
,
{
pathParams
:
{
hash
}
});
const
queryKey
=
getResourceKey
(
entityType
===
'
tx
'
?
'
tx
'
:
'
address
'
,
{
pathParams
:
{
hash
}
});
const
queryData
=
queryClient
.
getQueryData
<
Address
|
Transaction
>
(
queryKey
);
const
queryData
=
queryClient
.
getQueryData
<
Address
|
Transaction
>
(
queryKey
);
const
handleClick
=
React
.
useCallback
(()
=>
{
if
(
!
onBeforeClick
())
{
return
;
}
modal
.
onOpen
();
},
[
modal
,
onBeforeClick
]);
const
handleAddPrivateTag
=
React
.
useCallback
(
async
()
=>
{
const
handleAddPrivateTag
=
React
.
useCallback
(
async
()
=>
{
await
queryClient
.
refetchQueries
({
queryKey
});
await
queryClient
.
refetchQueries
({
queryKey
});
modal
.
onClose
();
modal
.
onClose
();
...
@@ -62,14 +55,24 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, entityType = 'addr
...
@@ -62,14 +55,24 @@ const PrivateTagMenuItem = ({ className, hash, onBeforeClick, entityType = 'addr
const
element
=
(()
=>
{
const
element
=
(()
=>
{
switch
(
type
)
{
switch
(
type
)
{
case
'
button
'
:
{
case
'
button
'
:
{
return
<
ButtonItem
label=
"Add private tag"
icon=
"privattags"
onClick=
{
handleClick
}
className=
{
className
}
/>;
return
(
<
AuthGuard
onAuthSuccess=
{
modal
.
onOpen
}
>
{
({
onClick
})
=>
(
<
ButtonItem
label=
"Add private tag"
icon=
"privattags"
onClick=
{
onClick
}
className=
{
className
}
/>
)
}
</
AuthGuard
>
);
}
}
case
'
menu_item
'
:
{
case
'
menu_item
'
:
{
return
(
return
(
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
<
AuthGuard
onAuthSuccess=
{
modal
.
onOpen
}
>
<
IconSvg
name=
"privattags"
boxSize=
{
6
}
mr=
{
2
}
/>
{
({
onClick
})
=>
(
<
span
>
Add private tag
</
span
>
<
MenuItem
className=
{
className
}
onClick=
{
onClick
}
>
</
MenuItem
>
<
IconSvg
name=
"privattags"
boxSize=
{
6
}
mr=
{
2
}
/>
<
span
>
Add private tag
</
span
>
</
MenuItem
>
)
}
</
AuthGuard
>
);
);
}
}
}
}
...
...
ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx
View file @
9837acc2
...
@@ -8,34 +8,26 @@ import IconSvg from 'ui/shared/IconSvg';
...
@@ -8,34 +8,26 @@ import IconSvg from 'ui/shared/IconSvg';
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
const
PublicTagMenuItem
=
({
className
,
hash
,
onBeforeClick
,
type
}:
ItemProps
)
=>
{
const
PublicTagMenuItem
=
({
className
,
hash
,
type
}:
ItemProps
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
handleClick
=
React
.
useCallback
(()
=>
{
const
handleClick
=
React
.
useCallback
(()
=>
{
if
(
!
onBeforeClick
())
{
return
;
}
router
.
push
({
pathname
:
'
/public-tags/submit
'
,
query
:
{
addresses
:
[
hash
]
}
});
router
.
push
({
pathname
:
'
/public-tags/submit
'
,
query
:
{
addresses
:
[
hash
]
}
});
},
[
hash
,
onBeforeClick
,
router
]);
},
[
hash
,
router
]);
const
element
=
(()
=>
{
switch
(
type
)
{
switch
(
type
)
{
case
'
button
'
:
{
case
'
button
'
:
{
return
<
ButtonItem
label=
"Add public tag"
icon=
"publictags"
onClick=
{
handleClick
}
className=
{
className
}
/>;
return
<
ButtonItem
label=
"Add public tag"
icon=
"publictags"
onClick=
{
handleClick
}
className=
{
className
}
/>;
}
case
'
menu_item
'
:
{
return
(
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
<
IconSvg
name=
"publictags"
boxSize=
{
6
}
mr=
{
2
}
/>
<
span
>
Add public tag
</
span
>
</
MenuItem
>
);
}
}
}
})();
case
'
menu_item
'
:
{
return
(
return
element
;
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
<
IconSvg
name=
"publictags"
boxSize=
{
6
}
mr=
{
2
}
/>
<
span
>
Add public tag
</
span
>
</
MenuItem
>
);
}
}
};
};
export
default
React
.
memo
(
PublicTagMenuItem
);
export
default
React
.
memo
(
PublicTagMenuItem
);
ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx
View file @
9837acc2
...
@@ -9,12 +9,13 @@ import useApiQuery from 'lib/api/useApiQuery';
...
@@ -9,12 +9,13 @@ import useApiQuery from 'lib/api/useApiQuery';
import
{
PAGE_TYPE_DICT
}
from
'
lib/mixpanel/getPageType
'
;
import
{
PAGE_TYPE_DICT
}
from
'
lib/mixpanel/getPageType
'
;
import
AddressVerificationModal
from
'
ui/addressVerification/AddressVerificationModal
'
;
import
AddressVerificationModal
from
'
ui/addressVerification/AddressVerificationModal
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
AuthGuard
from
'
ui/snippets/auth/AuthGuard
'
;
import
useIsAuth
from
'
ui/snippets/auth/useIsAuth
'
;
import
useIsAuth
from
'
ui/snippets/auth/useIsAuth
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
const
TokenInfoMenuItem
=
({
className
,
hash
,
onBeforeClick
,
type
}:
ItemProps
)
=>
{
const
TokenInfoMenuItem
=
({
className
,
hash
,
type
}:
ItemProps
)
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
modal
=
useDisclosure
();
const
modal
=
useDisclosure
();
const
isAuth
=
useIsAuth
();
const
isAuth
=
useIsAuth
();
...
@@ -38,14 +39,6 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick, type }: ItemProps)
...
@@ -38,14 +39,6 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick, type }: ItemProps)
},
},
});
});
const
handleAddAddressClick
=
React
.
useCallback
(()
=>
{
if
(
!
onBeforeClick
({
pathname
:
'
/account/verified-addresses
'
}))
{
return
;
}
modal
.
onOpen
();
},
[
modal
,
onBeforeClick
]);
const
handleAddApplicationClick
=
React
.
useCallback
(
async
()
=>
{
const
handleAddApplicationClick
=
React
.
useCallback
(
async
()
=>
{
router
.
push
({
pathname
:
'
/account/verified-addresses
'
,
query
:
{
address
:
hash
}
});
router
.
push
({
pathname
:
'
/account/verified-addresses
'
,
query
:
{
address
:
hash
}
});
},
[
hash
,
router
]);
},
[
hash
,
router
]);
...
@@ -72,18 +65,28 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick, type }: ItemProps)
...
@@ -72,18 +65,28 @@ const TokenInfoMenuItem = ({ className, hash, onBeforeClick, type }: ItemProps)
return
hasApplication
||
tokenInfoQuery
.
data
?.
tokenAddress
?
'
Update token info
'
:
'
Add token info
'
;
return
hasApplication
||
tokenInfoQuery
.
data
?.
tokenAddress
?
'
Update token info
'
:
'
Add token info
'
;
})();
})();
const
on
Click
=
isVerifiedAddress
?
handleAddApplicationClick
:
handleAddAddressClick
;
const
on
AuthSuccess
=
isVerifiedAddress
?
handleAddApplicationClick
:
modal
.
onOpen
;
switch
(
type
)
{
switch
(
type
)
{
case
'
button
'
:
{
case
'
button
'
:
{
return
<
ButtonItem
label=
{
label
}
icon=
{
icon
}
onClick=
{
onClick
}
className=
{
className
}
/>;
return
(
<
AuthGuard
onAuthSuccess=
{
onAuthSuccess
}
>
{
({
onClick
})
=>
(
<
ButtonItem
label=
{
label
}
icon=
{
icon
}
onClick=
{
onClick
}
className=
{
className
}
/>
)
}
</
AuthGuard
>
);
}
}
case
'
menu_item
'
:
{
case
'
menu_item
'
:
{
return
(
return
(
<
MenuItem
className=
{
className
}
onClick=
{
onClick
}
>
<
AuthGuard
onAuthSuccess=
{
onAuthSuccess
}
>
{
icon
}
{
({
onClick
})
=>
(
<
chakra
.
span
ml=
{
2
}
>
{
label
}
</
chakra
.
span
>
<
MenuItem
className=
{
className
}
onClick=
{
onClick
}
>
</
MenuItem
>
{
icon
}
<
chakra
.
span
ml=
{
2
}
>
{
label
}
</
chakra
.
span
>
</
MenuItem
>
)
}
</
AuthGuard
>
);
);
}
}
}
}
...
...
ui/shared/AccountActionsMenu/types.ts
View file @
9837acc2
export
type
ItemType
=
'
button
'
|
'
menu_item
'
;
export
type
ItemType
=
'
button
'
|
'
menu_item
'
;
import
type
{
Route
}
from
'
nextjs-routes
'
;
export
interface
ItemProps
{
export
interface
ItemProps
{
className
?:
string
;
className
?:
string
;
type
:
ItemType
;
type
:
ItemType
;
hash
:
string
;
hash
:
string
;
onBeforeClick
:
(
route
?:
Route
)
=>
boolean
;
}
}
ui/snippets/auth/AuthGuard.tsx
0 → 100644
View file @
9837acc2
import
{
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
AuthModal
from
'
./AuthModal
'
;
import
useIsAuth
from
'
./useIsAuth
'
;
interface
InjectedProps
{
onClick
:
()
=>
void
;
}
interface
Props
{
children
:
(
props
:
InjectedProps
)
=>
React
.
ReactNode
;
onAuthSuccess
:
()
=>
void
;
}
const
AuthGuard
=
({
children
,
onAuthSuccess
}:
Props
)
=>
{
const
authModal
=
useDisclosure
();
const
isAuth
=
useIsAuth
();
const
handleClick
=
React
.
useCallback
(()
=>
{
isAuth
?
onAuthSuccess
()
:
authModal
.
onOpen
();
},
[
authModal
,
isAuth
,
onAuthSuccess
]);
const
handleModalClose
=
React
.
useCallback
((
isSuccess
?:
boolean
)
=>
{
if
(
isSuccess
)
{
onAuthSuccess
();
}
authModal
.
onClose
();
},
[
authModal
,
onAuthSuccess
]);
return
(
<>
{
children
({
onClick
:
handleClick
})
}
{
authModal
.
isOpen
&&
<
AuthModal
onClose=
{
handleModalClose
}
initialScreen=
{
{
type
:
'
select_method
'
}
}
/>
}
</>
);
};
export
default
React
.
memo
(
AuthGuard
);
ui/snippets/auth/AuthModal.tsx
View file @
9837acc2
...
@@ -15,11 +15,12 @@ import useProfileQuery from './useProfileQuery';
...
@@ -15,11 +15,12 @@ import useProfileQuery from './useProfileQuery';
interface
Props
{
interface
Props
{
initialScreen
:
Screen
;
initialScreen
:
Screen
;
onClose
:
()
=>
void
;
onClose
:
(
isSuccess
?:
boolean
)
=>
void
;
}
}
const
AuthModal
=
({
initialScreen
,
onClose
}:
Props
)
=>
{
const
AuthModal
=
({
initialScreen
,
onClose
}:
Props
)
=>
{
const
[
steps
,
setSteps
]
=
React
.
useState
<
Array
<
Screen
>>
([
initialScreen
]);
const
[
steps
,
setSteps
]
=
React
.
useState
<
Array
<
Screen
>>
([
initialScreen
]);
const
[
isSuccess
,
setIsSuccess
]
=
React
.
useState
(
false
);
const
profileQuery
=
useProfileQuery
();
const
profileQuery
=
useProfileQuery
();
const
onNextStep
=
React
.
useCallback
((
screen
:
Screen
)
=>
{
const
onNextStep
=
React
.
useCallback
((
screen
:
Screen
)
=>
{
...
@@ -35,6 +36,7 @@ const AuthModal = ({ initialScreen, onClose }: Props) => {
...
@@ -35,6 +36,7 @@ const AuthModal = ({ initialScreen, onClose }: Props) => {
},
[
initialScreen
,
onClose
]);
},
[
initialScreen
,
onClose
]);
const
onAuthSuccess
=
React
.
useCallback
(
async
(
screen
:
ScreenSuccess
)
=>
{
const
onAuthSuccess
=
React
.
useCallback
(
async
(
screen
:
ScreenSuccess
)
=>
{
setIsSuccess
(
true
);
const
{
data
}
=
await
profileQuery
.
refetch
();
const
{
data
}
=
await
profileQuery
.
refetch
();
if
(
data
)
{
if
(
data
)
{
onNextStep
({
...
screen
,
profile
:
data
});
onNextStep
({
...
screen
,
profile
:
data
});
...
@@ -42,6 +44,10 @@ const AuthModal = ({ initialScreen, onClose }: Props) => {
...
@@ -42,6 +44,10 @@ const AuthModal = ({ initialScreen, onClose }: Props) => {
// TODO @tom2drum handle error case
// TODO @tom2drum handle error case
},
[
onNextStep
,
profileQuery
]);
},
[
onNextStep
,
profileQuery
]);
const
onModalClose
=
React
.
useCallback
(()
=>
{
onClose
(
isSuccess
);
},
[
isSuccess
,
onClose
]);
const
header
=
(()
=>
{
const
header
=
(()
=>
{
const
currentStep
=
steps
[
steps
.
length
-
1
];
const
currentStep
=
steps
[
steps
.
length
-
1
];
switch
(
currentStep
.
type
)
{
switch
(
currentStep
.
type
)
{
...
@@ -92,7 +98,7 @@ const AuthModal = ({ initialScreen, onClose }: Props) => {
...
@@ -92,7 +98,7 @@ const AuthModal = ({ initialScreen, onClose }: Props) => {
})();
})();
return
(
return
(
<
Modal
isOpen
onClose=
{
onClose
}
size=
{
{
base
:
'
full
'
,
lg
:
'
sm
'
}
}
>
<
Modal
isOpen
onClose=
{
on
Modal
Close
}
size=
{
{
base
:
'
full
'
,
lg
:
'
sm
'
}
}
>
<
ModalOverlay
/>
<
ModalOverlay
/>
<
ModalContent
p=
{
6
}
maxW=
{
{
lg
:
'
400px
'
}
}
>
<
ModalContent
p=
{
6
}
maxW=
{
{
lg
:
'
400px
'
}
}
>
<
ModalHeader
fontWeight=
"500"
textStyle=
"h3"
mb=
{
2
}
display=
"flex"
alignItems=
"center"
columnGap=
{
2
}
>
<
ModalHeader
fontWeight=
"500"
textStyle=
"h3"
mb=
{
2
}
display=
"flex"
alignItems=
"center"
columnGap=
{
2
}
>
...
...
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